
// Make newform 5.12.a.b in Magma, downloaded from the LMFDB on 17 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_5_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_5_12_a_b();".
// 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_5_12_a_b();".
// 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 := [-151, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [0, 2]];
    Rf_basisdens := [1, 1];
    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_5_a();"
function MakeCharacter_5_a()
    N := 5;
    order := 1;
    char_gens := [2];
    v := [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_5_a_Hecke(Kf)
    return MakeCharacter_5_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 := 12;
    raw_aps := [[-10, 3], [-110, 16], [-3125, 0], [28950, 528], [-309088, -26400], [1707130, -12864], [658970, 126528], [2662660, 274560], [29471970, 33456], [47070190, 2298240], [122271732, -7207200], [10501610, 19033728], [-372871658, -22651200], [314975050, -13909104], [-701030770, -20505072], [569160290, -186753984], [3658757780, 175817280], [-758212838, -53568000], [7867145070, -91691472], [16469235772, -54804000], [-14991424430, 339617856], [-1651411560, -575636160], [6649551210, -1100818224], [-6337385430, -1455281280], [-1540351870, 4545870528], [43118460702, -3110524800], [-4872759910, 3654504816], [148271607750, -183016272], [-8108731270, -11929614720], [-229226954470, 257790336], [-152862492410, -1101738672], [-431249652768, -5448434400], [-30837648990, 1305424128], [-21666125980, 19927638720], [924273719650, 5294505600], [868794124252, -15359968800], [795446852450, -7245651072], [779038591130, -19604361264], [-1633753407930, 56160730128], [749035993170, 42989091456], [-142249751860, 72119893440], [-2024990248018, -86883744000], [-3737955510308, 28562215200], [3465547847450, 12549343296], [-2308525846470, 51990212928], [2645579186200, -61141939200], [4053832556912, 118450279200], [5176459851170, 66224908656], [5954557006390, 83377644528], [3605577513990, 344103690240], [-113554278390, -425644309824], [-1480945470280, -135591199680], [-5118617279858, -319363176000], [8499532462752, -138265380000], [-6031088410950, -246841414272], [-11466739254470, 21306333936], [-12876374355190, 1026939183360], [1058656645372, 504941344800], [26175460828290, -165926143872], [27178583660982, -814851019200], [-9299004926190, -24859282224], [-22935790250550, -1819739330304], [-3547753353650, -980033377872], [-42944218312188, 1252070896800], [26762254375130, 2236486590336], [50932617480370, 1026952936128], [9539232167832, 2887732106400], [28249674994210, -4366650982272], [55676928860030, 3437400137328], [-30880259434850, -2765028192000], [-41944029649710, 590754873216], [-19505926968120, 7216768366080], [-147988652664930, -1934584338672], [6304516136770, 3144863619456], [174951505636540, 4351892480640], [107087900001810, -3333236023824], [-217099562743230, 2972897214720], [-6813364590470, 1818740680128], [-49300384860798, 2511006297600], [-315044811955570, -4967912886720], [371786087869660, 5820041511360], [-395507050960478, 196324444800], [-99646338864468, -9334308194400], [-434573403047390, -5095099593024], [32093314391320, 3810912145920], [154460651669850, 7273236798096], [278766447290150, -15745261588800], [259329563665450, -17919073462272], [-15644846809338, -14606092348800], [200520869270730, -7209626598864], [-619557688080530, -4794202888272], [308612783574840, -26368223386560], [-72805954563490, -10362037588272], [300174480066592, -25567649181600], [695424367984900, -16707565075200], [-547411997009510, 21453730719216], [-1096427185874770, 16468257646080], [208453684250122, 11863397068800], [-615747463502030, 13284105957456], [1195136775326742, 522596553600], [-84926225889770, -67623254925072], [633793458946650, 7353513529728], [-425917167217470, -19053318234864], [-207058311595890, 31149223114560], [-439184274871528, 66626551562400], [462730429250090, -88184700809472], [-1007598778754490, 76705722737328], [1002412880460850, 87878966493696], [1054192307502400, 33045374088000], [-1113459935079898, 80206501512000], [2810806823305150, 4011006720528], [-2879403210701270, -43730777619264], [-508630992912630, -38118424107072], [-940111201298740, -135544934423040], [2729136620643532, -21611989264800], [-1495393658151858, 33595214347200], [438447096269250, 121759533975696], [-1914550262232370, -8564056458672], [1277925799623490, 141693585738816], [757551780381980, 22777650626880], [-2944713244585838, 19914642796800], [575896550741970, -58454490250944], [440497844973690, 59387484731328], [259006655391210, -106193148403824], [-4202996166280808, -97804614496800], [1096032534452602, -77201380771200], [3424880494195030, 27791132830080], [-1125729986746440, 132422753597760], [998777606209190, -227994083173872], [-6088126720024990, 87068161022976], [-4530310531234580, 266381990214720], [-5508934195095550, -67029114759504], [402106419657652, -26747732167200], [-6358661705048750, 27876049360128], [6114091486087962, 100832786419200], [3509957552231810, 360436951743360], [8346713263588170, 11393989985856], [1666188982550710, 416125359074928], [-10515532289392670, 170266142104128], [7928743033849930, 110708601262080], [13175778647288112, -259652899485600], [15276928441267122, 204788075683200], [-7962692451983230, 247167092270256], [-5070125214041410, -242113676963472], [-3998578876123110, -181198969205760], [9269145734351920, -161353097974080], [-3519205024610310, -37371894561984], [-19084895335263550, -89329083199872], [2183194093990180, -276656015488320], [-2758517311676270, 360481001786736], [2832260906338290, -77300117398272], [-4892535016086418, -313811345227200], [20498884353986210, 53903671880976], [-12516801470275290, -594093628319472], [28106562176703150, -160222348470672], [-14622622353980188, -251452407578400], [-11794170715568240, -39325229317440], [6785946428311990, 806453868968640], [-17099516572041990, 145193604548928], [-3647871907970858, 1270379557209600], [21935476044890430, 995518654567728], [-5784594199913110, 449881918626816], [1548045950206670, 1213527007186128], [-7358602534659528, -1337357871746400], [17777563250648690, -1378898547655872], [-16416451484239590, -711503608366224], [-10650329825322508, -1268843710576800], [11650817390732130, 1132952514356928]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_5_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_5_12_a_b();".
// 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_5_12_a_b(:prec:=2)
    chi := MakeCharacter_5_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 12));
    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_5_12_a_b();".
// 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_5_12_a_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_5_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,12,sign)));
    Vf := Kernel([<2,R![-5336, 20, 1]>],Snew);
    return Vf;
end function;