
// Make newform 1584.4.a.bc in Magma, downloaded from the LMFDB on 19 April 2024.
// 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_bc();".
// 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_bc();".
// 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
        poly := [-3, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [0, 4]];
    Rf_basisdens := [1, 1];
    Rf_basisnums := ChangeUniverse([[z : z in elt] : elt in Rf_num], Kf);
    Rfbasis := [Rf_basisnums[i]/Rf_basisdens[i] : i in [1..Degree(Kf)]];
    inp_vec := Vector(Rfbasis)*ChangeRing(Transpose(Matrix([[elt : elt in row] : row in input])),Kf);
    return Eltseq(inp_vec);
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)
    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+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, 0], [0, 0], [-1, 2], [-10, -1], [-11, 0], [40, 5], [62, 3], [-36, 15], [-49, 9], [-72, -14], [17, 7], [27, 2], [-268, -1], [30, -4], [-136, 30], [246, -14], [317, 33], [420, -46], [-377, -5], [-339, -19], [-200, 117], [-158, 164], [234, -30], [921, -82], [1097, -36], [-566, -105], [880, 122], [174, -95], [490, -80], [855, 166], [604, -103], [-222, 199], [-905, 102], [1466, 207], [-530, -427], [1870, -102], [1409, -154], [2060, -96], [1608, -163], [-2058, 36], [-2871, -225], [1303, 304], [2321, 87], [-572, -276], [4322, 116], [-408, 60], [-1500, -232], [1973, -283], [1422, 461], [3495, 228], [-2304, 302], [114, 606], [1456, -354], [409, -99], [1226, 290], [3194, -431], [-3010, -292], [-3032, 223], [166, -58], [-198, 738], [4964, 34], [3276, 809], [1588, -13], [-1956, -798], [3263, -566], [-109, -18], [-3607, -711], [5726, 861], [-632, 755], [5106, 233], [2589, -1202], [-7808, 533], [-8215, -209], [-2726, 373], [1829, 143], [-4585, -253], [2847, 860], [9262, -714], [2950, -478], [2514, 968], [-12100, -406], [-170, -1922], [2658, -325], [-6755, 720], [2000, -1418], [10885, 113], [-8315, -1250], [-13380, -406], [-6660, -278], [2243, 819], [-5019, -1463], [10784, -113], [5641, -1831], [-10472, -412], [3580, 2380], [8974, -172], [-2487, 572], [5859, -1944], [-9356, -447], [-2348, 1683], [7984, 438], [7910, 593], [-9332, 82], [2472, 1126], [7180, -1412], [-17607, -306], [484, -1530], [-3740, 88], [11632, -224], [-6994, 1699], [-9650, 1764], [4592, 1172], [3246, -2812], [4393, -2461], [-8791, 1839], [-6375, 1988], [-8189, 2985], [-6031, -641], [-13183, 988], [2338, 1856], [2797, -72], [11006, 1760], [-5538, 1109], [-21688, -1134], [-8993, -2715], [-5126, 3583], [15215, 564], [-15393, 2487], [4029, 509], [10308, 242], [22750, 634], [-9020, -2916], [-3937, 1847], [5666, 4340], [-21432, -1871], [10616, -3207], [24126, -1652], [-5656, 1454], [9571, 2520], [-14772, -1281], [-23842, -1392], [8618, -1620], [-1887, -4343], [-1864, -5181], [1897, -438], [-37781, 59], [10238, -4724], [-13064, -4380], [-19425, -1459], [2352, 1732], [-11760, -4545], [-11645, 1130], [-48940, 22], [25394, 2324], [-29652, 1160], [18348, -2122], [-4066, -3928], [8310, -2146], [-29524, 729], [-28626, 1906], [-2955, -4357], [-10102, 4451], [27176, -2742], [-12865, -1113], [-12117, -350], [1815, -4489], [4304, 4876], [-29374, 371], [24350, -446], [16617, -2936], [32102, -4154], [4126, -2612], [23132, 3507], [1988, 8301], [42691, 2867], [-13001, -3448], [54874, -607], [-1979, -3530], [-28364, -4304], [53212, -808], [4000, 804], [19910, 3050], [17277, -274], [-39006, 470], [-12627, -1243], [50382, -2246], [660, 2353], [-22464, -858], [3470, -1993], [37490, -1018], [-5743, -3238], [-16658, 665], [46011, 371], [-15990, -2300], [32280, 1537], [2133, 2290], [-18970, -3459], [-17177, -772], [28290, 1722], [-1006, -6281], [47376, -4265], [37050, 2408], [8442, 2108], [-46400, 1078], [24983, -789], [8663, -3986], [30327, -1645], [-32988, -6138], [32568, -5518], [10544, -10034], [-10848, 6832], [-23691, 2594], [-71343, -2541], [20884, 2286], [13710, 8853], [-27481, -476], [18544, 7409], [71196, -1358], [15672, 4138], [-41751, 4512], [-7784, -4293], [-27552, -4685], [-47673, 7484], [11515, -9051], [-27864, -8659], [8978, -6546], [-8502, -1860], [12288, -5670], [22280, -4627], [97192, 277], [47425, 4850], [-34696, -5747], [6674, -9148], [38008, -3390], [39263, 1977], [39562, -3982], [-3903, -7570], [8160, 5047], [69295, 553], [-55499, -2617], [-35513, 6931], [29632, 5300], [13908, 4458], [46161, 9398], [52424, -1696], [-7332, -10026], [15460, -650], [-10300, 5712], [-38178, -182], [-33446, -7884], [10432, -4344], [26098, -4039], [-4311, -10411], [-13330, 5978], [43674, -3979], [-8828, 3218], [-27314, -1084], [-27450, 8555], [-10737, -8190], [19546, -11813], [-22876, 8058], [12276, -2091], [38846, 12271], [-71970, 3293], [-37134, 994], [-32224, -5254], [-46395, 4614], [66603, 7356], [29206, -8372], [-29538, -11674], [-28519, 11400], [45273, -4427], [21418, 4646], [-30116, 3189], [-12748, -7641], [-15227, 16099], [22263, 10933], [13186, -17202], [78784, -2121], [76080, 8749], [74524, -2895], [-27149, -4739], [84704, 713], [64118, -662], [5132, -182], [-53235, 7561], [24714, 8692], [-80094, 265], [-86485, 4571], [-3154, 3037], [90595, -1766], [-78700, -12010], [80436, -11948], [-72006, 1825], [-125478, 4673], [-13460, 18805], [40703, -457], [-1543, 9050], [-51990, 9781], [64894, -8836], [-23790, -2699], [-7692, 987], [-96580, 4870], [34180, -15384], [-63275, 1183], [-7097, 1122], [16023, -1213], [-30579, 15882], [-13620, 23122], [-151104, 1187], [-43104, -12274], [-33454, 2096], [44994, -15240], [-73481, 7355], [-111312, -1904], [31322, -16607], [-26005, -3293], [53314, -9288], [25522, 6138], [-97904, 6669], [-23920, -4785], [34969, 15824], [-91994, 1991], [78019, 3697], [-43822, 9566], [20195, -20296], [-32907, -11691], [82369, -12629], [133428, -6791], [44972, -9036], [49654, -5456], [-27534, -4250], [-70046, -15103], [-118640, -7318], [360, -6654], [-16755, 8923], [26185, -2972], [332, -27100], [-14177, -2], [114166, -8023], [-50947, -15822], [117345, -3624], [44976, 1459], [-37499, -441], [56317, 15802], [106378, -8578], [180763, -4520], [-25643, -12527], [-29196, -12943], [50553, 13916], [-6416, 10205], [-11949, 23108], [14682, 6988], [41700, 21296], [77338, 9635], [-61134, 19634], [-27795, 2915], [147806, -4886], [75886, 15030], [-70039, 7883], [-70834, 3384], [14970, 9961], [-119685, 5523], [-64094, 18923], [-91107, -15387], [-18347, -23380], [-87204, -3525], [-102374, -5088], [29412, 3843], [-9975, -10153], [-34728, 6110], [-161498, -3277], [43208, -26359], [19586, -14710], [12637, 3668], [-91444, 1682], [67970, 10245], [-29938, 1904], [-44490, 8690], [18966, -8339], [-35734, -16426], [-131967, -406], [-12602, 26293], [-64298, -23433], [-64216, 21600], [-141225, -1255], [-10632, -21118], [-83527, 10220], [175420, 9607], [151175, -14383], [-49027, 4360], [-17191, 29896], [-6535, -22325], [37193, -3225], [-43905, 31763], [-112148, -3287], [191170, -5355], [121050, 15506], [66668, -978], [-101750, 13824], [-11146, -26811], [-207193, 11460], [163680, -4520], [91170, 25042], [-202900, -1454], [-17958, -19569], [154878, -5900], [85304, 22891], [86932, -9488], [41279, -21343], [15282, 24434], [-176350, 8821], [152452, 4100], [145954, 11511], [121082, 12315], [-129225, 652], [41456, 10218], [4665, 33881], [118186, -1012], [-54114, -21024], [142657, 7532], [-36704, -18418], [183192, 2202], [103210, 25849], [171466, -19652], [36357, -19648], [-123033, 17433], [-121042, -28667], [173765, 21615], [-85040, -5104]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1584_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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