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


// To make the character of type GrpDrchElt, type "MakeCharacter_405_a();"
function MakeCharacter_405_a()
    N := 405;
    order := 1;
    char_gens := [326, 82];
    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_405_a_Hecke(Kf)
    return MakeCharacter_405_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 := [[5], [0], [-5], [9], [8], [43], [122], [-59], [213], [-224], [-36], [206], [-413], [-392], [311], [377], [-337], [40], [348], [-62], [-1214], [-294], [-534], [810], [-928], [996], [-433], [1686], [656], [-1018], [-1361], [-1911], [-654], [-733], [1126], [-2546], [1223], [3176], [-132], [993], [3101], [2846], [-3080], [2588], [1335], [-5204], [1637], [-4480], [3736], [-1380], [2904], [5966], [-3218], [-6123], [1398], [3211], [-4018], [2314], [-4347], [-1551], [4380], [-5049], [5428], [18], [-2116], [-4415], [3480], [6322], [10034], [-2510], [-3726], [10710], [-2160], [3394], [9031], [10305], [3480], [3706], [-2679], [-12499], [928], [7570], [2460], [1648], [15826], [-12774], [-8875], [11524], [8544], [2523], [2902], [-4362], [5723], [13339], [-19637], [5416], [6110], [-20375], [-19010], [3288], [3256], [-213], [-17388], [4353], [-1924], [16832], [2106], [-4694], [-13226], [-13291], [6040], [-23], [3018], [-9439], [-9800], [-23442], [31308], [-712], [-31478], [16121], [-19160], [-13422], [-25905], [9246], [25039], [-32930], [1882], [1962], [-13741], [-32458], [19612], [-36736], [-3746], [5725], [-37323], [-24586], [3078], [41038], [-9362], [45115], [-13512], [4530], [30884], [-12088], [-14112], [-3860], [2862], [32534], [-500], [36595], [40143], [-16414], [-33478], [3633], [20466], [15074], [-36848], [-35174], [-10092], [12910], [48060], [-6316], [7760], [-22437], [3506], [30648], [19232], [38415], [18071], [39421], [46863], [13372], [-28266], [27564], [57610], [-10263], [21285], [22338], [-1432], [23602], [-49144], [56299], [34069], [6100], [15117], [-36298], [55107], [34798], [-26515], [1790], [-19958], [8894], [-6588], [-9070], [-11208], [3196], [41497], [-4185], [4722], [39475], [-24870], [52008], [45975], [-29087], [54156], [-10317], [-39358], [-38854], [12726], [13436], [75614], [56320], [-23589], [27704], [85692], [6683], [-30296], [-27522], [5059], [-58998], [-81122], [1370], [-32469], [39745], [-5876], [-76480], [56238], [-72158], [17311], [17043], [-83157], [-5489], [78536], [94229], [94340], [19263], [33525], [50566], [-52551], [63672], [89496], [-42555], [18829], [-46206], [28422], [5594], [-65029], [8285], [41321], [49580], [-75026], [102935], [85296], [-77181], [17833], [17505], [-53714], [52604], [-34671], [-40828], [-77045], [-98750], [77468], [-63987], [6132], [-20567], [-33166], [21067], [-104920], [-82237], [28154], [29104], [10382], [-22980], [7398], [-89500], [8436], [-64998], [132153], [-48225], [7393], [119380], [85237], [22716], [-67884], [-1524], [-84338], [-14061], [-153760], [-30738], [-105338], [43144], [157614], [48060], [90893], [53190], [50066], [-40110], [79767], [-29086], [-140652], [67079], [1624], [143130], [-65729], [34946], [-7326], [49610], [-10062], [-1506], [160932], [-184614], [137889], [35864], [56296], [-109655], [-145551], [-87432], [-10128], [10494], [93161], [166736], [-73228], [158704], [-77634], [-49841], [-163372], [10348], [-200331], [-42127], [-69582], [116099], [159014], [85462], [-32911], [-118472], [-52030], [-124004], [-48643], [120765], [-15233], [-112988], [120780], [39714], [-124927], [-17676], [129818], [17950], [8454], [58123], [-216801], [-79086], [111568], [130777], [102132], [121506], [-94328], [36609], [21774], [85523], [178954], [-158581], [-219879], [236885], [-172798], [178252], [126549], [75828], [-136165], [65337], [-45579], [-61657], [136260], [-131058], [66721], [-160171], [-159450], [-229552], [-131454], [177376], [-43910], [-8304], [-83345], [148798], [-157560], [-141355], [-197068], [-129451], [28878], [-247179], [-209706], [120875], [25484], [-139834], [-70270], [134894], [242270], [-197253], [-90047], [39012], [-233120], [-173178], [-70175], [-78284], [186346], [61474], [25997], [200077], [103638], [102204], [-119826], [168294], [82172], [37827], [272252], [-46348], [157348], [-180656], [-177450], [-51248], [-228200], [-115025], [-66321], [-101647], [-65284], [-262621], [-33752], [-70437], [152756], [287744]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_405_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_405_4_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_405_4_a_b(:prec:=1)
    chi := MakeCharacter_405_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_405_4_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_405_4_a_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_405_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![-5, 1]>],Snew);
    return Vf;
end function;