
// Make newform 441.4.a.e in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_441_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_441_4_a_e();".
// 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_441_4_a_e();".
// 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_441_a();"
function MakeCharacter_441_a()
    N := 441;
    order := 1;
    char_gens := [344, 199];
    v := [1, 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_441_a_Hecke(Kf)
    return MakeCharacter_441_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 := 4;
    raw_aps := [[-2], [0], [7], [0], [5], [14], [-21], [-49], [159], [-58], [-147], [219], [350], [-124], [525], [-303], [-105], [413], [415], [432], [1113], [-103], [1092], [-329], [882], [1379], [679], [-457], [-1125], [1538], [72], [2149], [1125], [-252], [201], [1619], [-679], [-467], [1204], [-2821], [3253], [-1582], [-2557], [-397], [-2914], [-3339], [1780], [1400], [-2205], [-287], [-4587], [-1668], [3409], [-4760], [-805], [257], [3591], [-1393], [415], [4954], [4277], [7742], [7364], [9975], [4753], [3477], [3341], [7366], [-7415], [3878], [1267], [-4685], [4641], [-8797], [13680], [9765], [-1731], [-10983], [-6603], [-10955], [6636], [-16630], [-4923], [-8974], [4179], [12927], [2826], [8479], [9338], [-4016], [-5859], [6503], [-16049], [-8864], [-10211], [-1680], [-9457], [-18081], [-20377], [-6193], [-18464], [9413], [3199], [-21583], [20267], [-13951], [-20972], [-189], [10281], [6090], [-4949], [-15797], [9378], [24353], [-12640], [1041], [-9548], [-3241], [8853], [-7044], [12089], [982], [-30513], [-11475], [28315], [-10614], [10299], [32529], [-29456], [-27867], [19539], [-1248], [28093], [35954], [-861], [-24710], [16499], [-16471], [-36470], [-35751], [16492], [41473], [-25065], [-9732], [-27755], [21112], [21238], [-35609], [-2177], [32247], [27631], [24402], [-19612], [2261], [-23833], [-31824], [-16819], [1799], [-14154], [12047], [24379], [52330], [-12416], [36813], [-34995], [-14301], [-2665], [-24871], [41806], [-27349], [39513], [13566], [-9585], [53615], [12061], [39326], [44872], [-62239], [43008], [-43183], [-18583], [-2268], [-1090], [-31801], [9441], [-17689], [-53093], [17717], [-21173], [36715], [-19327], [-492], [51809], [41559], [61157], [41139], [22115], [-71433], [-44730], [1113], [65917], [-43064], [-36435], [-48475], [-36148], [-69769], [30471], [-53769], [2070], [-6055], [23571], [-49518], [59320], [-40187], [31283], [-39235], [31019], [-11333], [86315], [23322], [-48025], [24332], [-28919], [50717], [74228], [-57958], [-87437], [72385], [-15701], [-38733], [-1433], [31913], [-13648], [1685], [-40068], [-27657], [17885], [-102671], [72924], [15932], [-13071], [92631], [79905], [-73757], [101346], [88753], [115640], [60179], [3523], [-67020], [45362], [-64785], [-128347], [95690], [80479], [-9305], [50423], [-41643], [-32214], [114205], [-86833], [-72956], [60949], [114982], [26411], [-127001], [95646], [33166], [2788], [57965], [-9919], [36563], [-87451], [-100651], [-66430], [42679], [16595], [-48249], [73327], [55601], [-15589], [108915], [-44968], [83006], [59479], [-142725], [-149105], [79854], [109585], [-18354], [-53587], [-102389], [68409], [-81312], [88258], [99211], [-98749], [-21574], [-95011], [-85232], [71841], [62193], [-9749], [-39412], [37137], [-124122], [68577], [-153594], [-93781], [56359], [-68103], [113209], [88149], [134535], [61864], [155869], [-33852], [121413], [-64918], [71874], [-109235], [-117605], [22554], [-1132], [44721], [-127015], [-86819], [28483], [134671], [-22122], [-53093], [20109], [110824], [-205569], [-144149], [-154364], [48050], [83643], [-52010], [32543], [18475], [62746], [-126966], [61168], [-41603], [-148276], [-55111], [-26591], [106428], [118979], [-125293], [-19269], [-199306], [-98343], [112387], [123242], [-83559], [-63021], [181333], [172968], [-111774], [-55013], [-167379], [-127493], [-17423], [-43181], [15554], [-59477], [143754], [-40455], [53151], [-65277], [94386], [-57827], [-42005], [-148421], [189824], [29869], [249879], [31626], [-55405], [94050], [6568], [125641], [-177660], [-50197], [73439], [34937], [74405], [161952], [79186], [107247], [-174183], [30499], [-11909], [-24281], [-279559], [-43890], [121620], [-49611], [-66059], [-133163], [191893], [91623], [-67893], [-14833], [13071], [-292742], [146125], [-251643], [272377], [15181], [151996], [-209543], [-112194], [101283], [239979], [-100667], [-46410], [-99099], [243801], [142373], [-101264], [-282436], [15106], [-181713], [5087], [-250518], [34545], [306243]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_441_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_441_4_a_e();".
// 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_441_4_a_e(:prec:=1)
    chi := MakeCharacter_441_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 4));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(2999) - 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_441_4_a_e();".
// 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_441_4_a_e( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_441_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![2, 1]>,<5,R![-7, 1]>,<13,R![-14, 1]>],Snew);
    return Vf;
end function;