
// Make newform 1584.4.a.o in Magma, downloaded from the LMFDB on 30 April 2026.
// To make the character of type GrpDrchElt, type "MakeCharacter_1584_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_1584_4_a_o();".
// 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_1584_4_a_o();".
// 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_1584_a();"
function MakeCharacter_1584_a()
    N := 1584;
    order := 1;
    char_gens := [991, 1189, 353, 145];
    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_1584_a_Hecke( : Kf := Kf)
    return MakeCharacter_1584_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], [0], [7], [6], [-11], [-40], [78], [-36], [7], [-8], [-183], [227], [36], [-322], [-184], [6], [-99], [164], [695], [-987], [-248], [242], [-1494], [905], [-1031], [-630], [-1328], [526], [2234], [1239], [-132], [1218], [2775], [-1222], [1038], [-3042], [-1943], [-2292], [-3832], [1734], [-2295], [-2865], [2441], [-1532], [-2958], [2968], [-60], [-723], [-4466], [-4609], [-4768], [4802], [3920], [6057], [-3270], [-6102], [1166], [-6680], [1014], [-8326], [-1308], [3516], [9652], [-852], [-3313], [3035], [-1655], [-6130], [-696], [-12526], [-7411], [4096], [6721], [-6854], [-12155], [10447], [7863], [6142], [-12074], [-1454], [5308], [13030], [2194], [-5459], [12208], [10997], [-891], [10396], [3708], [2651], [1061], [6752], [13073], [-4072], [16060], [-7650], [3777], [10883], [-12748], [23012], [8400], [-2426], [-14484], [-1784], [3564], [1081], [-9324], [8548], [4512], [-14242], [-24386], [26608], [5246], [-20823], [-29279], [9209], [21331], [-18135], [3193], [31778], [-14747], [62], [12670], [11816], [-3441], [13690], [71], [26503], [18165], [-572], [-17026], [1028], [37527], [29330], [30520], [-25816], [37182], [7848], [6267], [10332], [24926], [-11366], [35337], [-13128], [25185], [-37821], [6638], [-42408], [16591], [8128], [32128], [25619], [-50044], [39938], [49196], [-32644], [-24370], [-2202], [28092], [31070], [33461], [-21702], [8744], [18303], [-34917], [31375], [28064], [-25534], [13758], [56577], [-39450], [-33362], [-14340], [-23884], [48779], [26919], [-1766], [-10851], [-33964], [-2564], [20656], [-43642], [-29883], [-2718], [-45099], [-64578], [15748], [-10592], [-33986], [54850], [-8383], [-43986], [-15829], [-1014], [21240], [-39627], [-16810], [32543], [-23646], [-15166], [-36800], [79594], [28730], [16576], [68391], [-70817], [-33649], [-72700], [-41096], [55632], [-77696], [-33875], [-54647], [5508], [-86114], [-80025], [31600], [64540], [-8712], [39713], [96712], [-92000], [-59161], [90787], [9608], [-54494], [22394], [800], [-52504], [-74072], [7417], [-16264], [-36830], [23064], [-45873], [-73990], [-54879], [46192], [7039], [71405], [34631], [-34560], [4676], [-30679], [14056], [42748], [-67724], [100612], [91838], [-83894], [27296], [62562], [49473], [-13538], [-4134], [-44284], [99534], [-27418], [66103], [-99222], [-14236], [-76780], [19294], [61438], [102946], [37664], [78973], [-25845], [62838], [35278], [25217], [-7831], [80570], [69788], [-34396], [45181], [-51945], [84946], [-39152], [-86544], [80604], [-11861], [-56096], [64038], [-131764], [-71019], [126330], [62178], [-28045], [-68290], [-151813], [33076], [-122252], [38586], [-5382], [-65540], [-135737], [34401], [109578], [-60226], [114882], [134084], [93340], [-56316], [-45371], [42887], [21927], [-61259], [73692], [-137520], [-72960], [91906], [-43390], [-45929], [149904], [31146], [-96309], [154770], [46050], [112352], [94448], [-119399], [-111642], [-19093], [-132654], [-46941], [56565], [76385], [-56460], [131788], [-127834], [45602], [108690], [-53328], [-112824], [179357], [-24623], [-84116], [89151], [-61498], [34357], [-37647], [-175456], [107021], [-102427], [-3510], [74227], [115045], [-95820], [66049], [80], [-35741], [-120918], [31620], [-73190], [-36014], [166405], [-72578], [63342], [-20143], [9246], [156426], [51795], [199298], [86253], [213781], [-203508], [57482], [-177036], [-113783], [201800], [-40746], [-221960], [-114350], [35141], [103100], [96498], [-47602], [-26218], [-83834], [-153798], [213009], [135606], [246246], [-159096], [76463], [34824], [-241055], [118588], [220799], [64253], [-35743], [205577], [-249415], [-156153], [-131204], [-113390], [178858], [-28596], [-76166], [-113642], [14375], [-265024], [-125966], [-237652], [254794], [31038], [9832], [-71052], [-191617], [74482], [-84414], [248164], [-102398], [221866], [122143], [-108624], [-61551], [271658], [-70034], [-44343], [-83808], [217752], [101514], [139450], [-145699], [83927], [-46370], [-37867], [-141360]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1584_a_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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