
// Make newform 232.4.a.d in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_232_a();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_232_4_a_d();".
// This may take a long time!  To see verbose output, uncomment the SetVerbose lines below.
// The precision argument determines an initial guess on how many Fourier coefficients to use.
// This guess is increased enough to uniquely determine the newform.
// To make the Hecke irreducible modular symbols subspace (type ModSym)
// containing the newform, type "MakeNewformModSym_232_4_a_d();".
// This may take a long time!  To see verbose output, uncomment the SetVerbose line below.
// The default sign is -1.  You can change this with the optional parameter "sign".
function ConvertToHeckeField(input: pass_field := false, Kf := [])
    if not pass_field then
        poly := [-198, 94, 74, -34, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0, 0], [-90, 64, 23, -5, -1], [-109, 140, 23, -5, -1], [-203, -60, 134, -6, -5], [-829, -184, 283, -7, -9]];
    Rf_basisdens := [1, 19, 19, 19, 19];
    Rf_basisnums := ChangeUniverse([[z : z in elt] : elt in Rf_num], Kf);
    Rfbasis := [Rf_basisnums[i]/Rf_basisdens[i] : i in [1..Degree(Kf)]];
    inp_vec := Vector(Rfbasis)*ChangeRing(Transpose(Matrix([[elt : elt in row] : row in input])),Kf);
    return Eltseq(inp_vec);
end function;


// To make the character of type GrpDrchElt, type "MakeCharacter_232_a();"
function MakeCharacter_232_a()
    N := 232;
    order := 1;
    char_gens := [175, 117, 89];
    v := [1, 1, 1];
    // chi(gens[i]) = zeta^v[i]
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    F := CyclotomicField(order);
    chi := DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),[F|F.1^e:e in v]);
    return MinimalBaseRingCharacter(chi);
end function;

function MakeCharacter_232_a_Hecke(Kf)
    return MakeCharacter_232_a();
end function;


function ExtendMultiplicatively(weight, aps, character)
    prec := NextPrime(NthPrime(#aps)) - 1; // we will able to figure out a_0 ... a_prec
    primes := PrimesUpTo(prec);
    prime_powers := primes;
    assert #primes eq #aps;
    log_prec := Floor(Log(prec)/Log(2)); // prec < 2^(log_prec+1)
    F := Universe(aps);
    FXY<X, Y> := PolynomialRing(F, 2);
    // 1/(1 - a_p T + p^(weight - 1) * char(p) T^2) = 1 + a_p T + a_{p^2} T^2 + ...
    R<T> := PowerSeriesRing(FXY : Precision := log_prec + 1);
    recursion := Coefficients(1/(1 - X*T + Y*T^2));
    coeffs := [F!0: i in [1..(prec+1)]];
    coeffs[1] := 1; //a_1
    for i := 1 to #primes do
        p := primes[i];
        coeffs[p] := aps[i];
        b := p^(weight - 1) * F!character(p);
        r := 2;
        p_power := p * p;
        //deals with powers of p
        while p_power le prec do
            Append(~prime_powers, p_power);
            coeffs[p_power] := Evaluate(recursion[r + 1], [aps[i], b]);
            p_power *:= p;
            r +:= 1;
        end while;    
    end for;
    Sort(~prime_powers);
    for pp in prime_powers do
        for k := 1 to Floor(prec/pp) do
            if GCD(k, pp) eq 1 then
                coeffs[pp*k] := coeffs[pp]*coeffs[k];
            end if;
        end for;
    end for;
    return coeffs;
end function;


function qexpCoeffs()
    // To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
    weight := 4;
    raw_aps := [[0, 0, 0, 0, 0], [1, -1, 0, 0, 0], [2, 0, 0, 1, 0], [6, 0, 1, 0, 1], [8, 0, -1, 2, -2], [7, -5, 1, -1, -2], [17, -5, 2, -4, 1], [31, 5, 1, 2, -2], [64, 6, 9, -8, 5], [29, 0, 0, 0, 0], [85, 13, -3, 0, -3], [0, 6, -2, 14, -12], [15, 17, 18, -2, -5], [74, 14, -27, 30, -22], [144, -18, -24, -6, -11], [-21, -9, -3, -15, 6], [174, -12, 7, -8, 33], [-125, -27, -20, 4, 17], [30, -50, 18, 0, -28], [210, -2, 36, 4, -8], [-242, 72, 26, -2, 30], [42, 0, -2, 10, -5], [68, 46, -19, 40, 33], [-367, 71, -36, -26, -13], [-515, 27, -24, -6, 15], [-334, 36, -40, 78, -88], [2, 94, 12, -16, 16], [-418, 24, -5, 28, -49], [-324, -26, 78, -35, 80], [-96, 202, 54, -28, 16], [-257, 73, -103, 26, -50], [-323, 15, -73, 14, -74], [242, -176, 16, -150, 64], [-810, -92, -25, -136, 29], [531, -201, -43, -93, -26], [350, -68, -41, 20, 119], [169, -253, -104, 58, -153], [-719, -117, 24, -116, -70], [1170, -238, -2, -76, 102], [1192, 234, -212, 148, -98], [42, 2, -56, 204, 60], [474, 108, -198, -21, -142], [1427, -111, 3, 130, -96], [375, 281, -34, 154, -33], [1606, 472, -112, 140, -8], [1370, -140, 197, -36, 29], [21, -285, 22, -324, 180], [-72, 176, -86, -72, 84], [28, 516, 64, 24, -2], [-1317, 533, -80, -94, -139], [2206, 414, -15, 3, 97], [1566, 468, 49, -136, 63], [1454, -530, -39, -187, 161], [-349, -471, 0, -52, 10], [2775, -179, 134, 297, -117], [1181, -287, -21, -336, -205], [839, 49, -188, 520, -175], [397, -719, 185, -196, -33], [-1670, -188, -164, 92, 40], [688, -644, 51, 23, 181], [-1398, -432, 71, -76, -19], [1726, -92, 290, -76, 62], [-876, -100, 203, -142, 94], [1035, -367, -277, 42, 40], [-1937, 505, 328, -111, 165], [1287, -119, 12, -360, 45], [1017, -1205, 172, 60, -30], [-2437, -1183, -4, 92, 53], [-922, 326, -100, 272, 152], [-4629, 383, -219, 65, -498], [1528, -186, -8, -320, -130], [-1664, -2, 502, -66, -135], [1131, 701, -287, 338, 62], [-262, 304, -792, 227, 24], [263, 1013, -259, 570, 334], [84, 850, 167, -228, 89], [3556, -562, -208, -58, 286], [-4512, -806, 122, 47, 32], [2468, -108, -467, -41, 307], [-4974, 152, 332, 320, 384], [-878, 958, 186, -152, -62], [1695, 29, 802, -240, 315], [7602, -1164, -461, -176, -251], [4406, 1440, -306, 354, -78], [3624, -1870, -329, -120, -213], [4349, -285, -179, -154, -104], [-2846, -52, -994, 780, -694], [-2600, -778, -212, 16, -110], [-1606, 1652, -304, 40, 300], [3974, 668, 309, -200, 223], [3074, -946, 261, -426, 618], [689, 701, 513, -1004, 759], [504, -958, -59, -16, -293], [9242, 118, -205, 1026, -482], [-6816, 914, -447, 32, 1], [-2995, 681, 21, 956, 79], [-2873, -873, -217, -47, -12], [-1675, 963, 506, 415, -187], [8718, -918, 44, -808, 634], [-8538, 416, 376, -842, 604], [8662, 1276, 217, -444, -83], [-3722, -2224, -560, -196, 368], [1853, 1239, -552, 916, -418], [-6832, -1718, 1326, -816, 860], [-7980, 116, -386, -816, 366], [-6127, 1055, 920, -512, 471], [2894, 1712, -647, 580, -565], [11903, -879, -484, -585, -207], [-14392, 378, 540, 6, 135], [-10853, 657, -864, 258, 21], [10041, 213, 9, -420, 231], [-270, -228, -734, 1333, -918], [4726, -636, -648, 1098, -340], [-11469, 273, 394, -656, 518], [-1592, -72, -186, -744, 724], [-2307, -697, 102, -1288, -259], [3254, 1064, -957, 536, -705], [-312, 966, -283, 188, 905], [1639, -1307, 1314, -846, 99], [-9887, 1115, 994, -360, 930], [-1046, 2012, -600, 472, 172], [3666, -2474, -281, -447, 235], [-6238, 328, -50, 1448, -582], [-1722, -82, 770, 540, 924], [15818, -550, 262, -684, 328], [-2411, -651, 803, -1661, 958], [1373, -891, -293, -461, 286], [-15196, -1564, -566, 444, -484], [8171, 153, 759, 1002, -92], [17708, -154, 792, -374, 922], [-4115, 635, -532, 736, -524], [-9315, 819, -749, -650, -646], [3237, -2709, 379, 142, 582], [-4091, 3011, -62, -316, 465], [13468, -1158, -724, 100, -1050], [3759, -2087, 342, -912, -1169], [-1783, 383, 230, 34, 957], [8604, -1192, 822, -872, -772], [-19749, 3429, -80, -972, 1061], [-20746, -2776, 738, -602, 650], [6844, -590, 1781, -500, 1055], [14585, 3501, 125, -497, -468], [-2973, -843, 1153, -1246, 1474], [9963, 2869, 76, 632, -1112], [-13057, 1485, -406, 900, -593], [2026, -1168, -908, -458, 151], [28326, 1388, 330, -20, -146], [-11125, -1403, 1056, -799, 1401], [13736, 3280, -987, 742, -2], [-8732, 1488, -172, 1464, -490], [14855, -1517, -815, 1801, -762], [-1008, -2146, 764, -296, -610], [10750, -2448, 651, 1132, -585], [6183, 659, 1727, 1060, -1159], [16173, 851, -571, 62, -64], [3985, 1093, 1033, -2172, 1179], [-23878, 2906, 1046, 1804, 1198], [13902, 172, 40, 2348, 36], [17094, 196, 1788, -1084, 1576], [-5288, -2054, 186, 661, 784], [1038, -4914, 239, -1922, 196], [8794, -1074, -1769, 2395, -2125], [-7724, 2082, -996, -1262, -1355], [20039, -359, -1069, 258, -372], [-7031, -1509, 1408, -1095, 1279], [-11942, -2572, -502, 398, 61], [6488, -716, -2396, -460, -1078], [-3798, -360, -134, 378, -1934]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_232_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_232_4_a_d();".
// This may take a long time!  To see verbose output, uncomment the SetVerbose lines below.
// The precision argument determines an initial guess on how many Fourier coefficients to use.
// This guess is increased enough to uniquely determine the newform.
function MakeNewformModFrm_232_4_a_d(:prec:=5)
    chi := MakeCharacter_232_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 4));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(997) - 1;
    while true do
        trunc_vec := Vector(Kf, [0] cat [f_vec[i]: i in [1..prec]]);
        B := Basis(S, prec + 1);
        S_basismat := Matrix([AbsEltseq(g): g in B]);
        if Rank(S_basismat) eq Min(NumberOfRows(S_basismat), NumberOfColumns(S_basismat)) then
            S_basismat := ChangeRing(S_basismat,Kf);
            f_lincom := Solution(S_basismat,trunc_vec);
            f := &+[f_lincom[i]*Basis(S)[i] : i in [1..#Basis(S)]];
            return f;
        end if;
        error if prec eq maxprec, "Unable to distinguish newform within newspace";
        prec := Min(Ceiling(1.25 * prec), maxprec);
    end while;
end function;


// To make the Hecke irreducible modular symbols subspace (type ModSym)
// containing the newform, type "MakeNewformModSym_232_4_a_d();".
// This may take a long time!  To see verbose output, uncomment the SetVerbose line below.
// The default sign is -1.  You can change this with the optional parameter "sign".
function MakeNewformModSym_232_4_a_d( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_232_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<3,R![1340, 1525, 128, -74, -4, 1]>],Snew);
    return Vf;
end function;