
// Make newform 336.6.q.e in Magma, downloaded from the LMFDB on 14 May 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_e();".
// 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_e();".
// 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 := [441, -21, -20, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [-441, -20, 20, 1], [0, 41, 1, -1], [-41, 20, 0, 1]];
    Rf_basisdens := [1, 420, 21, 20];
    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], [20, 20, 0, 7], [91, 7, -7, 14], [0, 568, 1, -1], [467, 0, 9, 0], [0, -88, -148, 148], [1169, 1169, 0, 27], [952, 952, 0, 308], [-1086, 0, 45, 0], [0, -2531, 768, -768], [9127, 9127, 0, -855], [-6006, 0, 846, 0], [2407, 0, 2043, 0], [-11882, -11882, 0, -604], [0, -16702, 1751, -1751], [0, -18590, -3917, 3917], [-19754, -19754, 0, 2544], [0, -13151, -4461, 4461], [-51750, 0, -1404, 0], [0, -11665, -5247, 5247], [-5815, -5815, 0, 6834], [-29640, 0, 1899, 0], [-14596, -14596, 0, 130], [-5404, 0, -1017, 0], [0, -65782, -12304, 12304], [-32635, -32635, 0, -17337], [-60626, -60626, 0, -4567], [0, -83593, -27, 27], [-114474, 0, -8766, 0], [37393, 0, 14382, 0], [-50348, -50348, 0, 13889], [0, 22904, 1826, -1826], [-147113, 0, -4869, 0], [-1384, -1384, 0, 22786], [0, -266414, 14865, -14865], [0, 285734, 33378, -33378], [-455572, -455572, 0, -3024], [91362, 0, -17748, 0], [58268, 58268, 0, -14426], [0, 345526, 27418, -27418], [231023, 0, -41715, 0], [-164702, -164702, 0, 59102], [0, -269521, -34302, 34302], [192276, 0, 113670, 0], [0, 532432, -47268, 47268], [662392, 0, -39186, 0], [320854, 0, 103005, 0], [0, -294056, 35047, -35047], [-241847, -241847, 0, -38049], [242174, 242174, 0, 16510], [-520422, 0, 20106, 0], [0, -806800, 122421, -122421], [-703602, 0, 87345, 0], [591590, 591590, 0, -37856], [0, -810152, 7282, -7282], [0, -282112, 113477, -113477], [859382, 859382, 0, 37989], [0, -1245217, 100515, -100515], [82056, 0, 60930, 0], [0, -1235873, 187941, -187941], [142206, 0, 63297, 0], [1820977, 0, -63945, 0], [0, 2443630, -120026, 120026], [1893565, 1893565, 0, 127626], [1406162, 1406162, 0, -43001], [692711, 692711, 0, 82929], [-735139, 0, -329508, 0], [0, -858920, -348428, 348428], [-1436494, 0, -205920, 0], [0, 2184686, -214498, 214498], [-486632, -486632, 0, 327002], [0, -1034141, 180420, -180420], [-2289941, -2289941, 0, -168927], [184093, 0, -268281, 0], [-304688, -304688, 0, 394166], [0, -1586710, 168236, -168236], [409483, 409483, 0, 273501], [665516, 665516, 0, 239020], [0, 545825, 719970, -719970], [3506610, 0, -412650, 0], [828743, 0, -358965, 0], [0, 376450, -406778, 406778], [-592603, 0, 41589, 0], [2942054, 2942054, 0, 190821], [-3076274, -3076274, 0, -274609], [2674098, 0, 49734, 0], [-1079153, -1079153, 0, 382074], [-5099712, 0, -237798, 0], [-1077083, 0, -549585, 0], [-1160066, -1160066, 0, -463018], [0, -304928, -80306, 80306], [0, 2316835, -744264, 744264], [-2904774, 0, -32463, 0], [4571297, 4571297, 0, 291525], [3802770, 0, 764262, 0], [9390188, 9390188, 0, -74855], [0, -1587760, -308902, 308902], [3592943, 3592943, 0, -1467], [5877109, 5877109, 0, -95895], [-8575988, 0, 13680, 0], [0, -2615092, 1056335, -1056335], [0, 9424840, 295549, -295549], [-497338, -497338, 0, -56726], [0, -8687225, 187221, -187221], [0, 1225943, -1417320, 1417320], [9774042, 0, -385713, 0], [-10383838, -10383838, 0, -729806], [0, -1126832, 1778650, -1778650], [6398087, 0, 167004, 0], [-3321091, -3321091, 0, -32376], [0, -10594378, 424098, -424098], [1224042, 0, -1046808, 0], [0, -1638239, 976047, -976047], [2624038, 0, 578169, 0], [0, -16325020, 46610, -46610], [13864231, 0, -134577, 0], [0, 21130, -1549688, 1549688], [14757896, 14757896, 0, -213509], [3263244, 0, 1088460, 0], [0, 4579265, 321531, -321531], [-18633541, 0, -46710, 0], [14082338, 14082338, 0, 753085], [0, -12661058, 488425, -488425], [18043739, 18043739, 0, 189849], [137862, 0, 2006073, 0], [-3474350, -3474350, 0, 255480], [-4802150, -4802150, 0, -1808608], [-12150149, 0, -73098, 0], [-5344199, -5344199, 0, 1144569], [0, -9059021, 5409, -5409], [14520450, 0, -775152, 0], [-13042981, -13042981, 0, -2036406], [-10752838, 0, 888336, 0], [9069536, 9069536, 0, -1174088], [3090923, 0, 1713258, 0], [0, -192274, -416380, 416380], [0, 22428556, -995694, 995694], [-3890766, 0, 1624383, 0], [0, 440786, 44546, -44546], [-5814452, 0, 815130, 0], [-5641540, -5641540, 0, -163007], [0, -4999160, -1435920, 1435920], [10255932, 0, 1533303, 0], [0, 20246651, 135855, -135855], [-13529964, 0, -1520712, 0], [-1716331, 0, -3709179, 0], [0, -14125924, -1475002, 1475002], [-3139228, -3139228, 0, 4006338], [13962742, 13962742, 0, 255524], [4213018, 4213018, 0, 1447950], [-32220, 0, -5011686, 0], [-17948531, 0, 393039, 0], [18296638, 18296638, 0, -65842], [0, 3522685, 318453, -318453], [-2873028, 0, -3324258, 0], [13118651, 13118651, 0, -283743], [-19835062, -19835062, 0, 2108908], [14905703, 0, 3067452, 0], [0, 18853934, 1621613, -1621613], [-8747354, -8747354, 0, -1941166], [-29818872, 0, 37746, 0], [-9278981, 0, -762678, 0], [-4622654, -4622654, 0, 2720705], [0, -42630826, -1933468, 1933468], [0, -22378220, 449416, -449416], [0, -35309267, 1262700, -1262700], [0, 3848189, -2599125, 2599125]];
    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_e();".
// 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_e(: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_e();".
// 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_e( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_336_q();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,6,sign)));
    Vf := Kernel([<5,R![7717284, 91674, 3867, -33, 1]>],Snew);
    return Vf;
end function;