
// Make newform 1920.4.a.k in Magma, downloaded from the LMFDB on 29 December 2025.
// To make the character of type GrpDrchElt, type "MakeCharacter_1920_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_1920_4_a_k();".
// 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_1920_4_a_k();".
// 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_1920_a();"
function MakeCharacter_1920_a()
    N := 1920;
    order := 1;
    char_gens := [511, 901, 641, 1537];
    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_1920_a_Hecke( : Kf := Kf)
    return MakeCharacter_1920_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], [3], [-5], [2], [30], [-2], [-54], [-106], [-18], [138], [292], [-270], [-466], [32], [-74], [302], [-518], [-86], [448], [-328], [258], [-288], [-236], [1254], [-790], [-70], [1614], [260], [-518], [-1710], [-2346], [-830], [-1022], [-1998], [-118], [-608], [-454], [-2188], [-94], [714], [1574], [2338], [-1140], [418], [4726], [-4220], [1946], [-5198], [-1328], [2338], [2738], [-7120], [-3806], [-5586], [1266], [-3370], [522], [740], [-1390], [1242], [680], [9250], [-5864], [-3880], [-7358], [1734], [-9290], [-7030], [2684], [2922], [-11694], [-6668], [-10514], [8978], [4162], [4482], [-3926], [-4570], [11390], [9814], [-3194], [9522], [5652], [-4310], [6556], [2208], [-1518], [1194], [11882], [5330], [-384], [-3496], [2738], [9198], [4502], [830], [4010], [7290], [-6368], [-10214], [6320], [-22358], [17220], [24102], [-8602], [-15086], [8348], [-4198], [-13308], [25066], [8358], [17678], [6626], [-8854], [16400], [-9198], [13188], [3450], [26686], [-4522], [-28006], [-3294], [3798], [29232], [-26094], [-36054], [-9230], [29856], [7298], [-9798], [26790], [-9810], [-32292], [-7582], [34170], [-25930], [15598], [-16256], [6], [31162], [13286], [38194], [35246], [33932], [18714], [-13956], [-8962], [34074], [-45486], [-4614], [20266], [29022], [20132], [-37126], [27852], [-29060], [-10940], [36930], [98], [-43918], [36936], [55314], [34074], [3350], [-25366], [53238], [-14204], [-46698], [48710], [-898], [-31806], [-44998], [25280], [-7814], [-5336], [-24090], [-49442], [6882], [48982], [-41798], [-32810], [-20742], [47182], [55594], [24154], [34610], [-57446], [58180], [35542], [-37020], [-39118], [77848], [5962], [6426], [-50136], [-49094], [-21282], [56718], [47338], [-64602], [36146], [62772], [1206], [-18126], [10266], [64794], [-45808], [38676], [-1962], [-65786], [20234], [-78374], [13982], [21636], [20156], [-33570], [-7418], [60510], [75890], [-47394], [51962], [39044], [2438], [25378], [-81440], [-38206], [-92622], [43696], [-6958], [32022], [75646], [-32402], [-92420], [-15014], [-30440], [14718], [-97902], [4238], [-27926], [-64784], [18180], [-58930], [57566], [54130], [-27038], [-22292], [-114674], [56802], [46330], [53642], [112102], [38802], [-63966], [-38182], [41466], [1254], [-50422], [-114212], [-88238], [101274], [71866], [-38064], [-21526], [100394], [-61102], [-7722], [115618], [-112722], [-65952], [77794], [-128926], [-36048], [-2486], [57296], [4786], [20494], [-59516], [61178], [-103046], [-40206], [-113126], [-38304], [-107910], [69794], [143996], [-44036], [144050], [-56842], [-80508], [-15242], [-41678], [-101664], [-46878], [18678], [144106], [44474], [-99292], [150578], [-103878], [83736], [118938], [57834], [-144304], [-160180], [-106338], [-108686], [69564], [23978], [-110212], [-42846], [108906], [-46086], [54318], [22492], [-63030], [-82970], [-109242], [78996], [-134102], [-18186], [-97758], [-142214], [17050], [120122], [-36310], [167970], [121118], [39136], [143646], [-172226], [-131998], [-154438], [-80360], [121692], [186502], [-145092], [-85894], [-84758], [181370], [-11346], [50], [-33998], [49554], [-35032], [44682], [25622], [205130], [-201452], [114380], [-40938], [-128726], [169922], [-192318], [-209534], [-101134], [-194662], [89336], [-28362], [-18054], [203118], [86374], [45166], [-25674], [-109374], [96568], [55826], [-30954], [86118], [-177442], [-153318], [238210], [-117606], [-211566], [211728], [52246], [-235610], [77956], [72386], [29874], [150274], [-141134], [13386], [-89238], [-227446], [243102], [-239722], [-60412], [-167326], [-259504], [172662], [-69946], [-253982], [23810], [107200], [224608], [92506], [-65528], [132154], [-188162], [192522], [-277686], [67906], [228310], [67442], [169474], [108360], [-10234], [-163826], [-167660], [-190050], [3754], [-221262], [-69176], [132530], [88850], [-158766], [-14608], [-107534], [-112606], [9238], [178434], [-55898], [86078], [181946], [276378], [-129814], [129116], [-41222], [-63514], [-13140]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1920_a_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_1920_4_a_k();".
// 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_1920_4_a_k(:prec:=1)
    chi := MakeCharacter_1920_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_1920_4_a_k();".
// 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_1920_4_a_k( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1920_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<7,R![-2, 1]>,<11,R![-30, 1]>],Snew);
    return Vf;
end function;