
// Make newform 2156.4.a.b in Magma, downloaded from the LMFDB on 08 December 2025.
// To make the character of type GrpDrchElt, type "MakeCharacter_2156_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_2156_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_2156_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_2156_a();"
function MakeCharacter_2156_a()
    N := 2156;
    order := 1;
    char_gens := [1079, 1277, 981];
    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_2156_a_Hecke( : Kf := Kf)
    return MakeCharacter_2156_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], [7], [0], [-11], [-52], [-46], [96], [27], [16], [293], [-29], [472], [-110], [224], [754], [-825], [548], [-123], [1001], [1020], [526], [158], [1217], [263], [814], [-376], [-1494], [842], [1281], [1736], [-6], [-1439], [318], [-922], [-1030], [-1017], [-2444], [1452], [-1914], [1293], [-455], [-1115], [5012], [-4146], [1240], [-2820], [-3695], [486], [-4231], [-3336], [3610], [6408], [1787], [354], [-2026], [8750], [5036], [-4306], [-1202], [6620], [-6968], [-7640], [652], [-8055], [-5675], [-2245], [-694], [4092], [-334], [-891], [2476], [-1379], [-6266], [151], [1989], [6817], [4170], [10914], [1102], [-11028], [2622], [16598], [5763], [3128], [6369], [8691], [2260], [12756], [-6887], [1535], [17564], [-7541], [12552], [-8396], [12194], [-18295], [-7101], [4912], [11496], [19048], [10718], [-6660], [-10960], [18596], [21119], [2836], [-18044], [-9264], [19326], [-10082], [13088], [23426], [-23587], [19683], [375], [21055], [6427], [-7617], [-17630], [-4605], [-2818], [-8438], [-17344], [3947], [-7998], [-881], [26093], [7481], [-17788], [-32182], [-32044], [-33779], [-15630], [-1948], [17420], [-11122], [-29648], [23219], [9232], [32286], [-31706], [41139], [-15252], [-369], [10257], [34386], [23464], [22475], [2880], [-11084], [-41797], [23780], [14334], [25716], [-28300], [21410], [-19938], [-26728], [-8634], [24841], [51234], [-26752], [-21155], [-56323], [-24683], [-26816], [-18614], [-38698], [-2503], [-42930], [-7630], [-816], [17904], [-16889], [-28809], [-35606], [26403], [-3788], [8772], [-176], [28002], [-37995], [22346], [-66199], [3846], [56176], [-9368], [530], [-62202], [-57097], [-29878], [60145], [-40710], [33172], [-6451], [-69806], [22823], [-32934], [-8086], [44], [72186], [-49674], [83864], [40117], [-5969], [37915], [26188], [-87792], [184], [-19936], [-52131], [-38773], [-52220], [15270], [-46103], [5204], [-13740], [-80944], [19623], [61772], [44436], [-3799], [-66039], [72460], [85498], [-58118], [21528], [-73836], [67860], [-66967], [-3580], [10078], [-33072], [65755], [-21026], [58615], [71324], [-1173], [-5961], [80187], [102640], [72460], [-32663], [74248], [-79172], [13100], [84348], [-61942], [68586], [23648], [-71186], [-43451], [66778], [-6522], [-5316], [47806], [29722], [-72873], [68210], [129604], [-21856], [52350], [62998], [114954], [12984], [88035], [-82437], [16474], [-32230], [-109257], [-59173], [47886], [5240], [90888], [-117975], [119331], [43754], [-5884], [142660], [77224], [62673], [-64188], [84562], [114276], [-53895], [-39078], [-132926], [31119], [21210], [-65067], [78724], [66844], [-101366], [-121770], [-29064], [-50125], [609], [-118934], [-6002], [-91422], [-28392], [-52068], [-91548], [-1017], [68671], [-109269], [-37685], [-112476], [29076], [17752], [72398], [-98018], [103541], [-97104], [29066], [-98207], [-53502], [1174], [65028], [-29868], [120089], [-38582], [59889], [122022], [154237], [-7329], [-173803], [153296], [-75036], [-135018], [165510], [-80194], [-34728], [124000], [28863], [23049], [-76932], [109529], [-144782], [-104923], [17183], [-190460], [93383], [19803], [-42478], [152021], [2575], [-79280], [-84967], [25724], [-107805], [-76554], [-53916], [26062], [-85334], [40239], [-63350], [-46614], [187853], [87822], [-115978], [69279], [-4746], [154665], [147045], [132752], [-31738], [16632], [-75987], [36992], [98106], [-230468], [72826], [-177379], [-155940], [-19378], [88370], [23214], [16574], [-133518], [-19321], [-145874], [-50842], [-233112], [81501], [13296], [-94425], [98720], [6925], [235037], [137289], [-222099], [-5363], [-217725], [105448], [79246], [130034], [-23668], [213654], [-10594], [-161751], [-159040], [88890], [-213084], [247934], [-103122], [-259820], [-49516], [164101], [162454], [-117326], [-29260], [184890], [244206], [-52201], [187464], [-120571], [-215174], [-96446], [-42145], [-181096], [17904], [-76614], [-21882], [78197], [-169373], [59526], [12073], [-148240]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2156_a_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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