
// Make newform 882.4.a.b in Magma, downloaded from the LMFDB on 13 September 2025.
// To make the character of type GrpDrchElt, type "MakeCharacter_882_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_882_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_882_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_882_a();"
function MakeCharacter_882_a()
    N := 882;
    order := 1;
    char_gens := [785, 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_882_a_Hecke( : Kf := Kf)
    return MakeCharacter_882_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 := [[-2], [0], [-12], [0], [-48], [-56], [-114], [-2], [120], [54], [-236], [146], [126], [-376], [-12], [-174], [138], [-380], [-484], [-576], [1150], [776], [378], [-390], [1330], [-1500], [-380], [-636], [146], [-198], [-376], [2130], [78], [2338], [1002], [-2752], [520], [1280], [1764], [-768], [-1812], [448], [2136], [4430], [-198], [2284], [4412], [-2072], [-366], [376], [2262], [-2592], [-110], [-1890], [2130], [4992], [6816], [-8192], [2414], [-1962], [-5402], [-4788], [574], [-8808], [2770], [-7566], [-11320], [-4786], [-12648], [-9632], [-3390], [10704], [8584], [-2122], [-4912], [9060], [-8994], [12976], [3522], [-12710], [1638], [-12850], [8016], [-2198], [376], [-7188], [14670], [-5146], [-1512], [7184], [-16518], [10092], [7832], [6732], [18668], [-6048], [11328], [-4146], [1006], [-14722], [-13480], [-6222], [4926], [-22182], [3296], [24334], [1638], [-7446], [6504], [-16058], [-10208], [-14974], [-7254], [-12458], [28352], [-27390], [21490], [17652], [4782], [27144], [11860], [5546], [-14880], [-20964], [-13106], [4590], [-862], [-3540], [4228], [-5420], [1280], [35712], [24464], [30242], [-2154], [-10262], [9084], [19798], [30240], [2346], [29806], [1506], [-20392], [-36108], [13876], [23436], [-8120], [-50010], [-34526], [17256], [8714], [-22806], [40196], [40812], [-13588], [47304], [1784], [-35922], [26782], [4044], [2136], [15174], [25832], [-37686], [54006], [33276], [-3760], [-36524], [-54178], [57192], [-29028], [23128], [7680], [34922], [-17372], [-57582], [14492], [15198], [-56000], [-37676], [19424], [4158], [7562], [63114], [-17688], [33024], [52310], [46510], [-60334], [-11580], [15118], [12780], [-49372], [-64776], [9276], [15762], [74990], [-59830], [32634], [-51672], [12426], [-30548], [-2396], [-35642], [64386], [17148], [24316], [35904], [-42030], [-33878], [-52018], [-76860], [-60352], [82266], [60744], [-1766], [32528], [86070], [13224], [-95202], [68186], [54376], [20910], [79904], [20034], [15626], [20778], [2976], [34144], [54048], [62642], [-20774], [33392], [-26634], [97342], [-6288], [20914], [-12102], [-29556], [-21168], [-51960], [-55442], [-31232], [-68650], [27594], [-84684], [-73136], [-110238], [-89944], [63936], [38558], [-1902], [115872], [82726], [12], [7932], [11738], [-65126], [-41580], [67786], [-21904], [34704], [-54164], [-85484], [-2130], [-43094], [101106], [60858], [-16756], [52998], [74464], [42104], [95902], [62264], [37870], [22048], [45480], [80030], [-41938], [85290], [59736], [3800], [84924], [111076], [-56450], [89832], [35426], [-20358], [139876], [112770], [86010], [52554], [-100806], [109746], [122726], [-145392], [-142256], [-159264], [-110514], [-686], [-138854], [-56706], [1280], [50832], [145928], [7562], [-144696], [-130340], [9192], [-161890], [-83928], [-1938], [-71322], [71840], [-102384], [-146522], [-114786], [138048], [-32186], [110430], [185866], [145298], [84924], [188120], [186810], [-59222], [68312], [106846], [-137976], [85734], [-127618], [-26130], [-11396], [-51018], [56972], [-2142], [-45358], [-57342], [80710], [119068], [-31354], [166122], [-102816], [200720], [40062], [-113976], [170368], [-48112], [50904], [-146676], [-49646], [180074], [-7254], [18412], [172262], [114786], [-114420], [-51270], [-11346], [-85752], [-78874], [-83550], [136536], [118308], [-25058], [-27322], [24192], [171128], [218486], [111084], [63250], [-97152], [-201798], [-167816], [-89314], [-189870], [18576], [99430], [42702], [226618], [105600], [-63702], [75224], [-14034], [29554], [150456], [-102040], [52684], [185492], [-205884], [-209410], [146148], [-91020], [108106], [-158640], [-89566], [-41564], [-96642], [-28852], [-125922], [-26588], [121710], [-167056], [-220890], [-243672], [-183836], [45254], [43650], [-56054], [-208290], [-22682], [13350], [53856], [102332], [8570], [-117192], [96888], [75364], [247086], [-33024], [-287202], [-183836], [-576], [-164682], [-48062], [89220], [118056], [-59418], [127402], [-24684]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_882_a_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_882_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_882_4_a_b(:prec:=1)
    chi := MakeCharacter_882_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_882_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_882_4_a_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_882_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![12, 1]>,<11,R![48, 1]>,<13,R![56, 1]>],Snew);
    return Vf;
end function;