
// Make newform 336.6.q.h in Magma, downloaded from the LMFDB on 17 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_336_q();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_336_q_Hecke();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_336_6_q_h();".
// 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_336_6_q_h();".
// 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 := [15876, 126, 127, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [15876, -127, 127, -1], [47754, -32131, 127, 125], [63756, 16129, -127, 379]];
    Rf_basisdens := [1, 16002, 16002, 16002];
    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_336_q();"
function MakeCharacter_336_q()
    N := 336;
    order := 3;
    char_gens := [127, 85, 113, 241];
    v := [3, 3, 3, 2];
    // 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;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_336_q_Hecke();"
function MakeCharacter_336_q_Hecke(Kf)
    N := 336;
    order := 3;
    char_gens := [127, 85, 113, 241];
    char_values := [[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [-1, 1, 0, 0]];
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    values := ConvertToHeckeField(char_values : pass_field := true, Kf := Kf); // the value of chi on the gens as elements in the Hecke field
    F := Universe(values);// the Hecke field
    chi := DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),values);
    return chi;
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 := 6;
    raw_aps := [[0, 0, 0, 0], [0, 9, 0, 0], [-8, 7, 2, -3], [110, -18, 3, -2], [7, 76, -21, 7], [-356, -1, -1, -2], [20, -676, -60, 20], [527, -500, -54, 81], [-2252, 2248, 8, -12], [4021, -59, -59, -118], [-14, 4401, 42, -14], [7327, -7408, 162, -243], [3576, 66, 66, 132], [2866, 63, 63, 126], [22422, -22458, 72, -108], [45, -4686, -135, 45], [377, -2350, -1131, 377], [-21138, 21046, 184, -276], [317, 15409, -951, 317], [-46202, 220, 220, 440], [505, 43085, -1515, 505], [47667, -48355, 1376, -2064], [-16967, 31, 31, 62], [-13692, 13518, 348, -522], [-22041, -863, -863, -1726], [748, -48506, -2244, 748], [-3697, 3112, 1170, -1755], [43746, -42117, -3258, 4887], [145, -138223, -435, 145], [121480, 274, 274, 548], [108671, 2860, 2860, 5720], [165512, -167839, 4654, -6981], [-650, -154088, 1950, -650], [89982, 1403, 1403, 2806], [75096, -74862, -468, 702], [3281, 70522, -9843, 3281], [5778, -69182, -17334, 5778], [163748, -163352, -792, 1188], [-131806, -1360, -1360, -2720], [-195488, 191170, 8636, -12954], [-1878, -334542, 5634, -1878], [-392696, 4919, 4919, 9838], [24930, -22752, -4356, 6534], [666, 510433, -1998, 666], [50246, -4126, -4126, -8252], [5820, 581696, -17460, 5820], [261850, 102, 102, 204], [-530177, 5571, 5571, 11142], [2313, 287532, -6939, 2313], [1171193, -1166244, -9898, 14847], [511658, -506776, -9764, 14646], [-345696, 15342, 15342, 30684], [4653, 828724, -13959, 4653], [-1751307, -1851, -1851, -3702], [3690, -13218, 19056, -28584], [7554, -805008, -22662, 7554], [-1241, -911744, 3723, -1241], [-760206, 767873, -15334, 23001], [-12009, -466631, 36027, -12009], [69638, 9686, 9686, 19372], [4799, -1135433, -14397, 4799], [-932955, -15519, -15519, -31038], [-492504, -25321, -25321, -50642], [-19198, -1215826, 57594, -19198], [-160747, 184569, -47644, 71466], [-1392918, 1367013, 51810, -77715], [1135865, -1132988, -5754, 8631], [-1070591, -32020, -32020, -64040], [-12144, -2725380, 36432, -12144], [-1503822, -20648, -20648, -41296], [5970, 2244246, -17910, 5970], [-2133832, 2142026, -16388, 24582], [10482, 1359983, -31446, 10482], [1341443, -1314840, -53206, 79809], [1510872, 1043, 1043, 2086], [-293852, 269998, 47708, -71562], [-22076, -3862286, 66228, -22076], [-1953861, 1984756, -61790, 92685], [2614824, -2613480, -2688, 4032], [32682, -612209, -98046, 32682], [2910192, 24702, 24702, 49404], [-728174, 71261, 71261, 142522], [3030, 1988622, -9090, 3030], [3310886, 25587, 25587, 51174], [2256498, -2206999, -98998, 148497], [-2405846, 2390977, 29738, -44607], [42532, -62054, -62054, -124108], [-629953, 691887, -123868, 185802], [-2562722, -19598, -19598, -39196], [2303976, 66887, 66887, 133774], [314870, -326740, 23740, -35610], [95434, 253180, -286302, 95434], [13446, -7392937, -40338, 13446], [3065625, -12111, -12111, -24222], [-610433, 543294, 134278, -201417], [-4264596, -6726, -6726, -13452], [55920, 9105, -130050, 195075], [-4878, 6425424, 14634, -4878], [-669799, 542788, 254022, -381033], [-3036675, 2913466, 246418, -369627], [2551064, 110932, 110932, 221864], [-89843, -4204436, 269529, -89843], [-58793, -1226672, 176379, -58793], [-636690, 665772, -58164, 87246], [76111, -8950737, -228333, 76111], [-21536, -12923119, 64608, -21536], [-1678877, 6823, 6823, 13646], [-4820166, 4732896, 174540, -261810], [-83874, -4590552, 251622, -83874], [-7905229, 26796, 26796, 53592], [-10357977, 10425947, -135940, 203910], [-56506, 90450, 169518, -56506], [1633730, 156488, 156488, 312976], [83957, -902519, -251871, 83957], [-2588021, 33375, 33375, 66750], [111614, -4698904, -334842, 111614], [-4809638, 67431, 67431, 134862], [-17604, 2514690, 52812, -17604], [6448536, -6464505, 31938, -47907], [-5132504, 29896, 29896, 59792], [-245, -6010585, 735, -245], [-715411, -74682, -74682, -149364], [1354338, -1278885, -150906, 226359], [63819, 5242758, -191457, 63819], [2942861, -3110072, 334422, -501633], [2172157, 66277, 66277, 132554], [-20958494, 21012566, -108144, 162216], [-7204506, 7119426, 170160, -255240], [-6341655, -51928, -51928, -103856], [-19059855, 19056742, 6226, -9339], [-16793, -12276549, 50379, -16793], [8487678, 65448, 65448, 130896], [4589937, -4735261, 290648, -435972], [13257430, -82036, -82036, -164072], [-14933020, 14824964, 216112, -324168], [-926619, 166966, 166966, 333932], [-8768, -320054, 26304, -8768], [-183074, 15891180, 549222, -183074], [-9781989, -24165, -24165, -48330], [-101618, -5808974, 304854, -101618], [-1733298, -19522, -19522, -39044], [8841416, -8974783, 266734, -400101], [-208000, -6724400, 624000, -208000], [11365929, 226563, 226563, 453126], [186511, -2587075, -559533, 186511], [-9199640, -162308, -162308, -324616], [-7437946, -101025, -101025, -202050], [-28506, 26455260, 85518, -28506], [6370988, -6305042, -131892, 197838], [2432354, -2364982, -134744, 202116], [-4374646, 4113072, 523148, -784722], [-17066838, 296454, 296454, 592908], [6602752, -167493, -167493, -334986], [4454394, -4281840, -345108, 517662], [144451, 30770325, -433353, 144451], [4237530, 5790, 5790, 11580], [19577977, -19651320, 146686, -220029], [-10762434, 11169834, -814800, 1222200], [5399363, -351132, -351132, -702264], [-325049, -6542786, 975147, -325049], [1492994, -1525696, 65404, -98106], [-15108406, 185042, 185042, 370084], [17082853, -38628, -38628, -77256], [12576750, -12392025, -369450, 554175], [-58260, 41727690, 174780, -58260], [-40932, 1260144, 122796, -40932], [170022, -28223407, -510066, 170022], [-69057, 28314691, 207171, -69057]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_336_q_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_336_6_q_h();".
// 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_336_6_q_h(:prec:=4)
    chi := MakeCharacter_336_q();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 6));
    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_336_6_q_h();".
// 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_336_6_q_h( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_336_q();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,6,sign)));
    Vf := Kernel([<5,R![37380996, -103938, 6403, 17, 1]>],Snew);
    return Vf;
end function;