
// Make newform 3.20.a.b 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_20_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_3_20_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 := [-21870, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-3, 6]];
    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_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 := 20;
    raw_aps := [[351, -1], [-19683, 0], [3008070, -4160], [56946032, 63936], [-3325035636, 10995584], [-22036178074, -39982464], [168140735874, 582591360], [301059462548, 1038738816], [1184126082984, 4325606272], [140488625985246, 14942987072], [20805074626856, 20829313728], [318997081994942, 1169925037056], [575019215140266, -1296527879552], [1410259476769100, -1209933369216], [-2801545659750240, -4731612028288], [13768934428823814, 3629613529152], [-27576737210917908, 572349981184], [-43596284533102810, -8516769041664], [249649855438939124, -47573122936320], [42457524218485272, -312831875103360], [-120716855580864166, 219879620692992], [565795733016761720, -1425076089053760], [803871638001791892, 2762772599881088], [2161398813184788138, -4053972006476544], [3951100617649729154, -2571793123864320], [5435547429901122774, 5133614963207744], [-9262388748241511680, 11762889016117824], [4286435186297170620, -24346305086208768], [-9239246287224252442, 28190717122755456], [51433069345551669042, -4002366373121792], [-106447970440112414056, -21169417720950720], [-166205674048507087500, -48599468870810624], [21238163092529353386, 148725960281454464], [-130789147955588987908, 118730845223737344], [186734513981955988854, -21497549854240832], [-327158499370807007488, -115752630591858240], [614758609892940670886, 339841957176244224], [325330097240161536068, 140580774873290880], [-1361508998315030082648, 1351374251931091456], [-216152017187953438818, -3470276468276767552], [-301327701964690332060, -766799004927920640], [-1502039725656850366594, 1863757015224444288], [-1166884175256068382336, -4466907696436097536], [-5231511584297645648638, -5068341968700920832], [1179939606614249562198, 7331238014333782848], [1006165592954944837184, 4002741942065725248], [-4678636542252734630524, -14036422745711688192], [6432334242177573970136, 28577428558725784896], [24895947673814776766532, 768005014141636736], [-27670560573729065108818, 6002472581609445504], [-5759243099792616124710, 3646449826523122944], [25793529289848897349968, 15223939202475801856], [-32412792241340627629006, 13995542532562769664], [-5451457067052184603908, -49546893811912947840], [54333748941585777276930, -41020751993825896448], [11938776659779267270728, 16341012692689617920], [-12196734025796064984402, -56861927728467735744], [-22931542131484320665656, -66962896035100053696], [160637729095132224505118, -20210954707367079552], [-92281300921111607955702, 153248626071385152512], [-27461548736136614455924, -242303113052840945664], [149571342238214756912598, -149941207730327491520], [-480686471091637187713180, -263341674453489550848], [351003961643474148234264, 26910868863684193024], [84640196698549394370218, -325444649510575595520], [-166394492634204421452450, -121763581183099377088], [76330282263405770552732, -347027293025712311040], [595020645182016922877618, -795948653418045484032], [985206031085136623071644, 1206885819259482843520], [-1433932396273147064479354, -361756603365810179328], [-708023430383392938665214, 1723686020950600653056], [1279261384826279632078392, -844770936740469396096], [-2167875478604346384142792, -150929946554885888832], [435599535131489593823630, 1368095148526960099584], [3260653320808108650954620, 117079421631330579840], [-770431014099472086346752, 2617584068393329223680], [-2352522217442008479589818, 2516044963395225089984], [2191781850180938088192470, -3865485007627151954688], [-7449040312685165110614750, 1009983405044436950656], [-1171756902143339891534038, 10977197605913707202304], [-2708791292829300473436732, 12181303476260179470976], [9954664326326390663308238, 48251466071670771072], [-1342303141820691324590784, -3668395932597227743872], [-871472600070688941415342, -7486863293575618767360], [-10205795957211039618953200, -11511023265829182813120], [-7958340539852083867425924, -11805964929485057778304], [-1459464701312009801087406, 10464845229497718979968], [14826304758439408252932602, 7590207293910595742976], [9667502499444539658330942, -5792711317473415470400], [-7637010244051075341970360, 21291380811590362691904], [26562992511558126027649140, -10350074869683193826688], [19898784517259638510631280, 25674044241579871963520], [26876319402999982528415504, -37694622907474509464640], [47238372342898464129951420, 5836085371711535140096], [-32575173742206864426975772, 7957236839005896523776], [-2976266420038529324208504, -60824232898453455609984], [-38596701634446677442644898, 6659306317759734282304], [-47349277431045703194928374, -51493616748468958207872], [905197849252970398339340, 53977403532387420918144], [73305029578240009549194806, 12713420028780529066368], [28401649402542430110871652, -55516563298443726370944], [12392359858712516920803774, -27441934753572275173440], [-13288753047336480926100108, -155322593454265584244352], [-94140623923423333896615462, -42588391249189439565184], [70713002976064214376749324, 219229455499627216161024], [-200828778758322841365314686, 113706209558905142999040], [-125284075718001951022648740, -73491030122631640384768], [-168544055233432579958261550, -77902936139716240064256], [-252325939008319898054433336, -63843224396592750591872], [-367488710307171538252970806, 119411618395292431363584], [-34472502154176211117542856, 99439863875088197198400], [318220317756805518079782302, -2404583624847293920512], [148270213243338246635629626, 56678938029517579692544], [-247631665094112985580786788, -265249919678450351417856], [-98445166541574092535881248, -596459562893238703740480], [385418719665116253430648146, -191030182244729672520832], [570845020334926765103520260, -115028231539379743933056], [-284344786617130014974217576, 82851722118530215344000], [399592076223541471557312798, -125544951838818537596480], [-701545107267027556299714780, -38932619824879289616640], [128860975136201694150624782, -110802715174266478801920], [-345313871368565939363412766, -695728693628144469116928], [808706122828867028917474758, 429420757948011648698048], [-812134539378930921103009332, -789198393461589193077120], [211443279012407855919274964, -1818874377485644929480576], [-684051571327580288355472290, 1519435539702506970363456], [-412970120064819923629004722, 1631233261368607872606336], [884206905047088034261235904, -1176119920069334522385792], [272496940868005297897651136, 1564371979912370838066624], [343442152116568079503844630, -1920602279558622812985216], [1231755508177997676165161012, -306510465868749464138496], [352741611177681385775473800, -1730628850557429822523136], [-102288630932555786933435176, -1038562763231394590769216], [984202193192285447422346846, -1078264182640844979052416], [2146873008149150838690401658, -286792616397763524372608], [-2719218860610751095773860606, 879700463460654887029248], [-1926234594357028857382224042, 2162248967715856572267840], [-195643551863125586148735820, -4978794441920613026779008], [-547436399415043306461957810, 1757685757415049213748672], [2661194002698388815909274890, 391449121483378406048640], [2935898421447614005541718092, 689303157524527454190720], [897170275967462811333154278, -5843626201877908566232768], [-319650959126351315676417088, 3971806266748312183059648], [724507975989490748064395724, -5349197245852319089332480], [-367714433664629440724447530, -1376476515473819017864320], [-7041583933465250005201839240, 1942323609712486323328640], [1475159813458954025394630158, -3473827485727094416857600], [8491566562582799245206014010, -263432004529014848595328], [-8070075082134708877116255460, -1401981391504558050675840], [4177723190856686190048420000, 2791389113960436518736384], [-5387693617342679348260725898, 4853923887732495667681536], [-8031488126782415386300110702, -6561906104038818090674688], [651958294801428416563663700, 6887522172009618194500224], [438080720237125893355531320, -18627359287719586864099328], [5104282241112349761407199500, -6302168948492152996411008], [-1564883618855946943215421008, 24864147638302381112887040], [6079725468743845623109991840, 1445220158851645629186240], [-6981715708545643912432039662, -2486971950253965556610944], [6237448451423353217777447738, 10508126754744419072283648], [-847300800325285243746839394, -3792724194077514288487232], [5232286664792059209930907236, -4083362087366691776221696], [16811861110510159172201674266, 3674304333345726558681216], [21235846221207421580185564064, 17721723095148334715334720], [-852456491653566056127895764, -27673122643367796593361792], [774314970418636343353683234, 8733886596606158346325120], [25296133933582722749489257944, 6382284156250915737247232], [6284963536024301562986958152, -40313285751443669467513920], [-22222798858176224479126809634, -12037434228515351813803776]];
    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_20_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_3_20_a_b(:prec:=2)
    chi := MakeCharacter_3_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 20));
    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_20_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_3_20_a_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_3_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,20,sign)));
    Vf := Kernel([<2,R![-664128, -702, 1]>],Snew);
    return Vf;
end function;