
// Make newform 880.4.a.n in Magma, downloaded from the LMFDB on 02 June 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_880_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_880_4_a_n();".
// 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_880_4_a_n();".
// 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_880_a();"
function MakeCharacter_880_a()
    N := 880;
    order := 1;
    char_gens := [111, 661, 177, 321];
    v := [1, 1, 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_880_a_Hecke(Kf)
    return MakeCharacter_880_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]];
    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 := [[0], [5], [5], [-1], [-11], [18], [-113], [-55], [-190], [-69], [255], [51], [-314], [484], [-470], [-545], [102], [129], [664], [1029], [-758], [-634], [654], [-511], [1736], [-434], [248], [92], [-1870], [432], [-2696], [317], [-1908], [2868], [1953], [-1530], [3211], [1297], [-3673], [-1062], [-2780], [182], [2764], [-3261], [-176], [-1731], [2733], [-1506], [-5418], [-4410], [5735], [-78], [-7030], [-670], [4866], [-483], [-2364], [2200], [-1064], [5114], [2486], [-1706], [2126], [-505], [7090], [-7687], [5396], [2161], [5802], [7234], [3750], [2560], [8396], [-6418], [-8134], [5734], [14814], [-10546], [3027], [-5432], [13132], [2724], [152], [11260], [11432], [-10164], [5354], [-8675], [-2323], [15722], [-8587], [420], [-6132], [1033], [7984], [-16512], [9600], [10678], [6492], [-6241], [-16756], [-13862], [-198], [5548], [-17089], [-14294], [-15801], [10714], [-3329], [13718], [-9819], [-16402], [24340], [2536], [3077], [12231], [-4911], [-24426], [-15351], [9907], [8626], [-30205], [-29160], [-13533], [-20002], [-35903], [31030], [7275], [-374], [1712], [18056], [17799], [6051], [-5562], [-406], [7458], [36283], [13368], [-17894], [-10662], [-20805], [5834], [-8948], [14156], [-18940], [-17960], [-39698], [-15865], [-29922], [-41098], [562], [31058], [36251], [-40104], [25757], [-17623], [-12688], [20091], [-43222], [199], [26087], [-40695], [-34463], [-9604], [-22880], [1038], [12040], [-19368], [10298], [35691], [20417], [-47302], [-2618], [-45821], [1024], [-67029], [948], [-58584], [-8451], [28949], [19382], [-35723], [10885], [-41421], [-22758], [20750], [-61036], [7540], [39406], [7740], [-10568], [-18036], [39182], [64188], [-29456], [21938], [-12440], [13786], [34830], [13037], [-20509], [44542], [24229], [-41548], [-79472], [67995], [-28544], [89840], [8274], [-57532], [84701], [-33052], [-80248], [7927], [-47468], [-27869], [85157], [80758], [65288], [-6579], [54602], [-53774], [-61251], [32932], [-85624], [-61103], [-56814], [-18831], [-28480], [62844], [53378], [-18773], [104662], [75814], [-91764], [-94275], [-63101], [-63978], [47240], [75899], [42783], [40564], [8568], [115310], [2158], [120846], [24824], [38046], [-120627], [-40859], [96694], [1080], [-95182], [13259], [-22412], [-34995], [5632], [-47518], [31206], [60641], [102584], [29164], [30829], [-19390], [-9484], [-35260], [-123268], [-64847], [-39364], [-76294], [-48454], [-103653], [-96812], [-12262], [-21033], [14850], [4464], [88110], [-140994], [59295], [-151281], [-74092], [-32776], [138505], [-81316], [82287], [-42210], [-20290], [-123799], [86094], [808], [118164], [-21933], [-137413], [97198], [-113602], [-24184], [41757], [-160620], [75574], [-92843], [-31384], [-77968], [-76764], [-130122], [160136], [-115820], [30336], [74795], [-25720], [-126428], [11310], [-94972], [-25447], [109615], [-42350], [101018], [64908], [137346], [156756], [164035], [-22362], [46974], [-80298], [-66383], [110283], [8978], [102316], [32643], [-12184], [-159017], [-22366], [-29884], [50626], [12713], [-105491], [-101166], [138591], [107197], [-87981], [-129926], [-43986], [166855], [90757], [68287], [2159], [48680], [34799], [79748], [-69399], [186997], [28138], [-29580], [-131963], [-34663], [-50807], [-145701], [90499], [51706], [81812], [-107134], [-99732], [96156], [172075], [159209], [-181624], [43470], [143011], [-49228], [85080], [61816], [63128], [-37535], [-143690], [9070], [142356], [80946], [-30033], [-193020], [-88891], [91596], [187390], [127932], [208209], [144592], [47392], [173032], [-151803], [-29728], [-7970], [-84939], [57217], [180440], [-157528], [-120592], [-7242], [-84394], [-232921], [42622], [-57407], [-56945], [51966], [128676], [103460], [49698], [146990], [-120407], [157278], [-81997], [107286], [-139242], [-257616], [-198940], [120284], [238706], [-140468], [79020], [2080], [-6426], [177483], [-155764], [134836], [-38844], [118489], [-279614], [-265239], [254231], [-15084], [83936], [118650]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_880_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_880_4_a_n();".
// 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_880_4_a_n(:prec:=1)
    chi := MakeCharacter_880_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_880_4_a_n();".
// 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_880_4_a_n( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_880_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<3,R![-5, 1]>,<7,R![1, 1]>],Snew);
    return Vf;
end function;