
// Make newform 3.22.a.a in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_3_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_3_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_3_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_3_a();"
function MakeCharacter_3_a()
    N := 3;
    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_3_a_Hecke(Kf)
    return MakeCharacter_3_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 := [[-2844], [-59049], [3109950], [363303920], [14581833156], [113350790702], [-8589389597982], [-29202939273796], [-155899214954280], [2400788707090758], [2239820676947000], [-30785069383298890], [-103207571041281030], [-165557270617488124], [-66587216226477408], [435422766592881630], [5534365798259081316], [-7176205164722961202], [-15755449453068299812], [26457854874259376232], [13471249335464801450], [-16886125085525986840], [-170687980457962587972], [-312592486939587043686], [949014545286007636418], [144797966936465366286], [2196268356005856547616], [-163086727234969180908], [224852099648466415214], [-4241184922644579319662], [1663119584635126200968], [6406626943174785796188], [-19831373582543603686854], [-5201431696866569638444], [-74763064725158135311218], [111043915386868322093792], [43656275092431663773966], [285661055237987043608204], [266950221434746318563480], [-228495520456896819906522], [-12915091594579588230420], [-875337691831691541387370], [1339614635354755152264576], [-213969872796478791110782], [1428953848040498669654094], [745856081100532126063712], [-2650895976765822429305140], [3971736341211046584736712], [-2146895129881716267556980], [3660235758446474375399846], [-2909208944403038650675734], [-4802244057233268675608016], [7862626263583078505602706], [-19952484830695479792554028], [13358005454748528162926082], [-5836371575541279170837256], [53529698495309537385305334], [-10440317510635193014283944], [31488416345591940289384694], [-11588677110280698813465606], [-48039948855419838692612668], [-79671418853465699676913266], [151498201886355635293292012], [141406064525637549460247976], [49959766526850986323931354], [181534816900659238926260742], [144090009883374727754225972], [-363050840760190749776987566], [-70962232684219340553931212], [-703938710640162315443738002], [-108084659925007045398399678], [-167492452351415878588271544], [983666535205578900964365224], [100058104077546946723970726], [92390491245979816211211860], [-2136767846148989664959287296], [-1255811170851210818438210754], [1781653326478219686924040862], [1401814892561044434767028738], [2174932516355163800770892186], [-6076361497487251720591607796], [-1899928366540988390282852026], [-8085722813462985686605440], [-5604390904391624719433122126], [-8511100637744858839564701040], [-6631336547663318692888265388], [13039379624751340181607258642], [4729487013042004789030728650], [4927221610561934308538950662], [12020710853915829658701459416], [10996896998656579124138231772], [-13271725522850033768588529840], [26257574791900548633983190608], [-25406622806937150074138377452], [-13004832262400455488550883476], [1349927624715443294469171192], [-40490179154093602019522405754], [54037816465667698116463596570], [15406647815308458550036086596], [-75447812062891023139332645730], [79052378213327911492261647980], [117728847706728643108962353478], [-92080651293441332460906172452], [-2717950160516900791245167286], [12808629186962748126010211396], [149329213647889636415379004418], [26297527504233086155943796852], [192293652256902686216959162866], [-245874485087913523785277643208], [74725211795250990946311962426], [-123465859081265683877340775192], [-159244012889755836138477565162], [123255763933214530896091718346], [-51899045422183214005431677644], [-20520758622325500998791952128], [514341673925425495936907294610], [-88576640057443531017152305204], [546915845827024506153227127528], [-566153070579920695859113513626], [-148653317679971486874699762900], [-404668682110360485370536290458], [-154590348354120774869165982430], [-988421304780460766917416385026], [-141168607871413737317907187836], [711584911003032474348581496956], [-880753950510790472325239889402], [-279000304075186639694437821946], [1214036240479613268213746028672], [-654831108106742648834368006624], [220664978872118581299333922046], [-407297184790509149785458111844], [397217788719231255803939645496], [-1868897711578501644115688161144], [-2991027206626765463645936415754], [1513411627711926824878802503914], [2534008321911850634475219836162], [-1695448238484716837565489389106], [-1873316698206639889522743829348], [-779663579584201989745528881738], [882261569728995612434799408090], [-2060437782680048693396881068028], [-1838463279112783669755043069506], [773766406431206671529168612768], [-4599886174645058148497117201532], [7930000903500407793759684299390], [4840331464359903947977409053320], [2969034951288097050671468511974], [-3700089836652179758895175727638], [775384600028408699615761836980], [-12954376280742464325734578913184], [-15735465337159559293318733151490], [-14752636237283930780735649189006], [-5644525096855524288816598298884], [5892995231204967233820299240712], [8327824993921946744840382783812], [10808582900870360111547573338832], [6552047854342853154420234587840], [10403594516071414912178713211154], [-20983058971505218873975145598646], [22096717275978605008204295448870], [-25960417718078185135363491576084], [-29472939783498516996798598906998], [6980768429573798278185387502208], [-1302336125015588671537637749980], [30659903704370034212635896919938], [8313249124068693551710414260840], [-13256804146031798626654463777128], [34204793844835207033683397301846]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_3_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_3_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_3_22_a_a(:prec:=1)
    chi := MakeCharacter_3_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_3_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_3_22_a_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_3_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,22,sign)));
    Vf := Kernel([<2,R![2844, 1]>],Snew);
    return Vf;
end function;