
// Make newform 320.4.a.l in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_320_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_320_4_a_l();".
// 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_320_4_a_l();".
// 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_320_a();"
function MakeCharacter_320_a()
    N := 320;
    order := 1;
    char_gens := [191, 261, 257];
    v := [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_320_a_Hecke(Kf)
    return MakeCharacter_320_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 := [[0], [6], [5], [-34], [-16], [-58], [-70], [-4], [-134], [242], [100], [438], [-138], [-178], [22], [-162], [268], [-250], [-422], [-852], [306], [-456], [-434], [-726], [1378], [-126], [-1262], [-510], [-26], [1242], [-978], [912], [-926], [-516], [958], [332], [1022], [926], [654], [1294], [2836], [-1742], [4460], [-3782], [-4474], [3608], [256], [-5158], [2226], [-2086], [-5718], [-3624], [-82], [5040], [-2310], [-4110], [-746], [-4596], [2206], [8278], [-1178], [-106], [-8134], [-4396], [4826], [-7026], [-8808], [5602], [6634], [-3198], [-5230], [-312], [10790], [4190], [6980], [13962], [-3810], [9158], [4866], [13486], [-5628], [-7938], [1916], [-16510], [-1256], [12222], [-5946], [1258], [-16422], [2658], [-3686], [88], [-14714], [7344], [-1604], [14802], [22514], [-6710], [-7930], [-4918], [3922], [-17786], [-20266], [13358], [-16360], [-15574], [-6654], [-17742], [15840], [-3002], [-23610], [-23850], [-5334], [2164], [-25220], [-12306], [27414], [-21834], [23998], [32004], [8526], [8178], [16646], [22446], [-35336], [-3482], [19402], [-9896], [494], [-9282], [3252], [-4710], [25764], [30094], [22362], [-30398], [-1290], [-14], [38814], [27402], [28576], [-31762], [20506], [-13014], [22790], [23696], [-5306], [-21054], [-7364], [17226], [-21202], [-29490], [-2570], [36334], [12474], [-41132], [-38416], [41302], [-26150], [-35254], [-18550], [17322], [35190], [40696], [44306], [-18798], [2468], [61086], [-23854], [-10778], [-31100], [3530], [60116], [-35470], [49616], [-7974], [5528], [-9902], [31018], [47894], [7046], [39552], [5326], [50962], [-47398], [16810], [-32138], [-16682], [-42898], [5140], [-9046], [-2802], [9736], [-46874], [-61966], [-39574], [-37650], [-8082], [15458], [-42430], [31698], [-73604], [-3026], [-18798], [-86916], [-338], [-39008], [-74650], [1290], [47752], [32794], [-16562], [21362], [16674], [20560], [-17562], [35614], [-3790], [-12498], [39830], [88894], [92800], [-56750], [-21102], [-71454], [25550], [-23182], [-62656], [-26698], [-6920], [-30538], [-103860], [-38500], [-27098], [50358], [103086], [-16410], [-68370], [85220], [15012], [114686], [87536], [-40598], [-77086], [11714], [54536], [-28994], [-93848], [-580], [67298], [35574], [42130], [-89370], [56702], [46606], [-4020], [26530], [77850], [-7122], [8682], [-94358], [87394], [-99558], [35926], [-97846], [-10708], [-8110], [40410], [-113538], [-91258], [-110726], [37946], [-64086], [-86704], [38666], [11642], [-37414], [5890], [-64234], [-99552], [18810], [21540], [27734], [35906], [-55150], [-105788], [-111526], [53142], [-29040], [158550], [50966], [-25854], [125922], [97056], [-105106], [87222], [13652], [90726], [-71836], [167466], [12162], [21438], [-84904], [118870], [-44208], [36514], [-145494], [-112414], [163464], [-113546], [56698], [35946], [22434], [-47434], [28478], [64666], [8924], [-166188], [43930], [-98186], [-22664], [-106126], [37734], [146866], [-36686], [-112002], [-14260], [-143570], [30950], [179502], [-39434], [174014], [108136], [163838], [-181024], [-89502], [-106730], [8922], [169990], [-100530], [-20906], [-80550], [-94642], [-60340], [202550], [206732], [79262], [154682], [85188], [-182874], [17504], [29274], [63350], [195506], [-126806], [42754], [-5064], [103304], [-156302], [141578], [-131858], [98842], [81542], [121308], [-38862], [-38342], [137958], [-120958], [55430], [201792], [189220], [-43678], [-82146], [-852], [-87818], [33996], [-166636], [42386], [59238], [162674], [-107030], [-135230], [-203274], [-113454], [64188], [53146], [-201092], [-169050], [147678], [-110522], [111670], [-211218], [-192036], [-143062], [182780], [251714], [28472], [-68598], [-19184], [-276690], [-35754], [-172230], [150886], [246018], [67326], [-163188], [-160594], [82674], [-247378], [-95004], [-136910], [-82554], [-19898], [-128080], [70978], [-161670], [114016], [-151970], [209058], [131706], [214374], [93014], [-2666], [129788], [-88422], [212142], [-70698], [-52338], [192952], [-210568]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_320_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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