
// Make newform 2.18.a.a in Magma, downloaded from the LMFDB on 20 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_2_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_2_18_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_2_18_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_2_a();"
function MakeCharacter_2_a()
    N := 2;
    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_2_a_Hecke(Kf)
    return MakeCharacter_2_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 := 18;
    raw_aps := [[256], [6084], [1255110], [-22465912], [172399692], [-2180149426], [30163933458], [-76275766060], [130466597784], [803134463070], [2045336056352], [33855367078118], [53206442755242], [26590357792364], [-232565394320592], [-163277861935626], [697820734313340], [-898968337037698], [-2667002109080572], [3910637666678472], [5855931724867274], [-23821740190145200], [-13915745478008556], [-30722744829110310], [57649100896826978], [-38015289283832538], [143913437107443944], [91430897410751148], [-374880792922280530], [432401364484427634], [-1200568078635448192], [1755438837068283972], [429230887897242378], [-828361761429289780], [-384278587779009450], [-897915661097577448], [35959613782025438], [11519071073296505444], [-4518833882974266072], [-6307474993492581906], [4694848120770989940], [-7617949948273250698], [-32650101610210759488], [-21646761201094271806], [-45953002510367964282], [57425809577301786440], [-29465078126118008428], [127172704113231060704], [83021355044858842788], [-64028988193084940890], [153412057559380222314], [-53533408978072961040], [71223031745462020082], [-366706105547921092548], [248604329840265400578], [90404222790883328904], [28999591873409482830], [770455387392144871952], [-155171186938776175402], [-497824647101252795238], [1190562858911396608604], [521973002484503237094], [-185651384439843604492], [-1001841369572678082888], [-418946930687589570886], [3021765545147573598078], [-1940907532701432561268], [-179575801380323254702], [7439593169366313733788], [607434951853006832030], [-5666094506267830356126], [-7994855209937620440600], [1365252268133585668208], [-1823166485405416264906], [5954965679482642348220], [2835569583703287060864], [11664131434649953894470], [-2095302500993478432562], [26038481578161621316242], [-27409101336677029061350], [-31578901076239453983900], [29670372697834202954342], [-1926579349541636363088], [3024167599952372724914], [21881909907416429946680], [-2010497759532077871876], [-47896829856712638304830], [64844403660912539357258], [-49463570985221320884978], [3265360606257696227024], [-10983282810178033476972], [58453317514121013850080], [-85408403188491320987032], [47313935993020565091372], [78606274204310732149940], [-144291117894876685030536], [86117496959999531373630], [198567051695357872764042], [121175261292161292287564], [-167081929482354321285538], [41077272515694339019748], [-150463843780112498369682], [-11474436445530061895436], [-409527934088886894970950], [-245794648959547654130308], [-86804934672493441980862], [399551988989782401192588], [225692191391158102683474], [-325463774228753895411240], [308584836256216891701722], [49944395664257318008928], [52037222093435575293734], [-126686672774820027434262], [-74021267303407594775380], [800054371366245871989752], [-273379077303191029646718], [-494746437425303743471036], [585655750334862998560008], [-1338574620303550242981426], [995800411960983973230420], [-355898097287069329549738], [-819644056698949496071006], [-376540584563570392306842], [-1247355207947450250923796], [948313903366779713270132], [-186029275630753709944578], [1932257229801057927972230], [-1377141285872307947384880], [2261379627127382991977048], [-227164895458566545802466], [-637558008056174923812700], [-1435135612817192478997656], [-3459674286794730893532688], [-4541824732464518522747722], [3840401786409213955794042], [5153340484451698746655490], [5289977594208949943613894], [5810690051139018482409428], [1381322058974483638824798], [-3500304168920305099638870], [-2965086257169058539087508], [8298881944958488093710582], [-1893185178307921549229896], [-1231649048982671206775172], [-3320858626476456690255490], [-724116282067551428253240], [-897586637246137335442666], [-10144634243546063139038502], [866798903884055663980700], [2249297908609898815834464], [7322746847361441907564718], [-8734913277156810964925838], [-18086613347893511507767756], [-2953233591237723118975752], [11436081301494647979571148], [-7424709832676348173058928], [2075720552941956715579160], [23129971928158179828903330], [6859993542720766497222698], [10055542987673444470928622], [25415118384595996021146228], [-15254063097487201598566086], [29443714670789084341039688], [44255877744808520327777292], [-4391214607375885904013102], [-32455011645363935430816936], [-13421150107476894893927968], [-20290881928266948168470362]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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