
// Make newform 1.22.a.a in Magma, downloaded from the LMFDB on 24 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1_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_1_22_a_a();".
// 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_1_22_a_a();".
// 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
        Kf := Rationals();
    end if;
    return [Kf!elt[1] : elt in input];
end function;


// To make the character of type GrpDrchElt, type "MakeCharacter_1_a();"
function MakeCharacter_1_a()
    N := 1;
    order := 1;
    char_gens := [];
    v := [];
    // 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_1_a_Hecke(Kf)
    return MakeCharacter_1_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 := 22;
    raw_aps := [[-288], [-128844], [21640950], [-768078808], [-94724929188], [-80621789794], [3052282930002], [-7920788351740], [-73845437470344], [-4253031736469010], [1900541176310432], [22191429912035222], [-20622803144546358], [-193605854685795844], [146960504315611632], [2038267110310687206], [-5975882742742352820], [6190617154478149262], [16961315295446680052], [-5632758963952293528], [-43284759511102937494], [-51264938664949064560], [48911854702961049156], [-504303489899844009030], [808275058155029184482], [-1002018079349702950698], [-589747054476306481144], [1122100836768400472892], [1723939397379244815230], [495809929052605094706], [1636093498211141405312], [-13864963308265839166668], [-40078919621811128507478], [44758479808291059117020], [49328908894524903236550], [57041480281980994831352], [63562335234693291666542], [86848360806012005785556], [-189411168573448801125048], [-418507989542345072272194], [476751571771182829691940], [-28862734509184028216218], [886377892508974169952192], [86350861419370594951106], [-699007897302572286502218], [-1245423293022700543384600], [3508414568865110558396612], [-4723499876938725919843744], [-5443168797133335298442988], [6906769890393014065423190], [4536502138132360491188106], [-2734929976785810304038480], [-8089068534967740784314958], [6639265576003324440330252], [1572784572582880285431042], [-34007704831734243878665944], [-35797484585908924151848290], [24610355301559536092347472], [-61167930197964617291422138], [17371006954434479553698682], [75723743460270764544477356], [48868444165733855376762006], [-217987303913841181562767708], [-40464448729200819848147688], [-8741736495920098775109094], [-31975828554853721823734898], [-252214821588073220443373668], [-153126867676011786188538478], [323436088129753442457201132], [-677854422495976101280925650], [684291443640449529403335906], [-68550020504461629496003320], [1135754326884411482171208752], [382975272769427563667540006], [71476681765193129726476940], [-1384251778002467070147567744], [1632131566081847956928241270], [1210289951770833802578359582], [-651358092672234306844957998], [-4452509308640009615484926470], [4929117920066309934786331860], [1501451475964271757135865622], [-7192208408787252836263540368], [4231039979486647937142977906], [4532345507950689721889204120], [-4611861758580901269978709044], [-125691710634107392937298750], [11592375120690064099596363242], [10251364377141043522143968862], [-5728005750190077010592015344], [11265794999774759881781786052], [-11737295436000615389604761760], [4752717872642987025249185672], [-25983670171031766454922026308], [38450776510836865272391897700], [-32744550835279659331248859944], [-20247200613982617886769365170], [4752074954635301477500711722], [-128180197215053244081351844], [34274656328077303421562536942], [-73032853601376943572884637868], [-33259714798117503240689822658], [-82833166386840180402048689244], [73541432034222675440706774810], [109130626920792725089300727372], [13072697119255384430631063362], [-171459462862893571896113347428], [235277286506353728692049564306], [-133384412823451582627272515400], [-36447416902986319326209315398], [271227627181215540047395469792], [-202698916028143257089926173994], [304169265740427497878453505802], [121487484873224131263384454460], [-179118323410746278123102310568], [-341742425780992412389179071358], [75758164069647994355240322356], [-299088493885343953698667892568], [54050657891124307079175461406], [22660638043214718006135714180], [-187482826359076091819735585338], [753000691407057420241379913506], [-812051875824678056735287260138], [469972897548632796837487826556], [358805596844034670680933510692], [-733109594156634430617996768498], [1209091792279360098319100495030], [-525189439062659479431490752240], [723318091782840375543685184312], [-2114087495493409671682372595794], [-742068891536737542377897606380], [1699679357057511219743864530056], [590225070899380377343532741552], [1333076245417286181881105272742], [-786217296234752404551865196838], [-1650825843831149027017656897790], [3779302894002331949030614345206], [-3582189155895850005156403346428], [-4459013991509129674821903456018], [3091556302581578909161041725130], [-985710954571375834730784163588], [-5819295509980003569677765623578], [1828477660915060538310548748056], [-3809967436089866256476934878388], [924246936816516492950713531790], [2180574840713560389663470012520], [-4277540661459166671682864143994], [-176321978256569215028208889158], [4740092804763513487964459545580], [810823601157008814082791788256], [1552548727521538775021916955262], [-5757216249646820376137356256718], [-12913360687045683307151349167644], [-4227522565906801827046787439528], [13478618410502600169967727606492], [-12888619206142565685594630762288], [1250178927398570334618210919160], [-14124505231588636986777423084510], [-7128507429613373822931851972278], [-107253668033184700395005678658], [29293479178428793583046597808932], [30432047879175387280562346071706], [-37848488080891056648372326612248], [-16233440423927458231915611821028], [2988581693960192100230788268562], [-24137102462439152330833908223944], [-22943625633260040059279850383008], [35503639024038538087336360874582]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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