
// Make newform 1296.4.a.n in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1296_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_1296_4_a_n();".
// 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_1296_4_a_n();".
// 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 := [-32, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-1, 2]];
    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_1296_a();"
function MakeCharacter_1296_a()
    N := 1296;
    order := 1;
    char_gens := [1135, 325, 1217];
    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_1296_a_Hecke(Kf)
    return MakeCharacter_1296_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], [-2, -1], [3, 1], [5, 3], [-20, -5], [17, 4], [-17, 5], [-49, -7], [60, -11], [100, -8], [240, 7], [96, -10], [167, 25], [-150, -38], [34, -32], [-310, 6], [100, 35], [703, -11], [-695, 3], [901, -18], [167, -79], [250, 74], [45, 24], [-100, -122], [1344, -30], [1286, 38], [-1188, 16], [1600, 11], [309, 28], [-43, 179], [-809, 85], [1665, 40], [1710, 86], [518, 91], [586, -50], [1186, 225], [594, -282], [243, -159], [1764, -23], [492, 320], [810, 68], [3405, -73], [1217, -230], [-3060, -175], [1760, 60], [-325, -347], [-445, -115], [2643, -39], [2500, -325], [-3485, 74], [2278, -74], [1995, 112], [2251, -363], [443, 374], [3026, 138], [-1162, 95], [3271, 17], [910, -192], [-1405, -550], [-356, 32], [-1218, 355], [5460, -32], [3696, 360], [435, -60], [684, -55], [895, -467], [3420, 230], [-3867, -209], [2568, 270], [-4282, 680], [483, 645], [-6748, -604], [-886, -252], [5440, 420], [8685, -225], [550, 380], [-1222, 69], [3099, 762], [-1815, 1150], [-10908, -124], [-5350, 57], [-8906, 590], [4111, 468], [-4650, 1086], [-9782, -230], [4960, 846], [149, -70], [-12050, -612], [-6374, -642], [11418, -674], [-12545, 509], [-8320, 860], [-1989, -515], [9345, -449], [-7920, -880], [9750, 420], [2420, -510], [-8485, 365], [9150, -1143], [-4430, -790], [3760, -1635], [-13210, 86], [-10325, 54], [1806, -910], [617, 1294], [-22435, 243], [19861, -372], [14160, -1204], [-15455, 58], [-311, -285], [4550, 1400], [255, -1370], [8240, -360], [-25750, -18], [2269, 1320], [5658, -750], [-26897, -131], [-1230, 1080], [-16695, -405], [1160, 983], [6481, -302], [-8582, 904], [25970, 770], [8125, 15], [13596, 865], [-2500, -245], [-4747, 355], [-11655, -1245], [-3274, 608], [10720, 1236], [5756, 272], [-10599, 787], [-5050, 2200], [-24799, 1440], [19493, -210], [-6750, 1459], [-5533, 949], [16090, -605], [7295, -2086], [16064, -2160], [-1320, 577], [-8324, 1008], [22225, -985], [-11630, -1084], [23247, -175], [-3574, 1092], [28815, 810], [5418, -910], [-27709, 637], [20130, -515], [-24340, 1042], [34006, 22], [3511, -2455], [-1732, 3924], [8525, -3933], [27815, -399], [5117, 3000], [-28647, -726], [-6900, -1735], [30003, -1511], [-28185, -510], [-11987, -3289], [11835, 2777], [-1080, 3590], [13284, -372], [239, 2885], [31138, 1161], [-1177, 4540], [-10406, -1352], [-6312, 620], [36030, -687], [47134, 550], [-1001, 1332], [17065, 855], [1040, 566], [49975, -1015], [-27876, 505], [2690, 3150], [22490, -499], [-30350, 1758], [14875, 1161], [2376, -2933], [-5148, 866], [-6750, -3234], [16872, -635], [-21992, -1861], [459, -507], [-14510, -2216], [-21189, -3767], [22249, -4258], [13260, -3476], [-49015, -825], [6310, 1487], [-35781, 1585], [-28594, -2728], [29791, -1120], [43522, -1820], [33593, 2296], [-8355, 5995], [59420, 109], [48529, 1975], [-22672, 3006], [4555, -4364], [-19305, 1445], [17850, 2880], [-24773, -1175], [-23250, -2470], [44060, 970], [20669, -417], [28332, -1754], [-23760, 1873], [-20545, -2675], [-20735, -3625], [400, 3704], [-1324, 5430], [-10793, 2001], [-24281, 590], [-12402, 2414], [41664, 337], [-57760, 2947], [3165, -3369], [51927, -1570], [-17270, 950], [-44148, 5284], [33512, -4685], [17736, 2478], [-5805, 3905], [-44526, 3550], [22970, 3610], [14946, -3863], [23705, 5019], [44305, -3105], [-52925, -3870], [58380, 2680], [-15158, 3166], [-31513, -2940], [6976, 722], [13300, -5420], [49799, 3405], [-14109, 1117], [-42209, -1487], [-46690, -3126], [-25790, -1660], [50760, -5370], [-39125, -3611], [55835, -2063], [15975, -5695], [-19042, 490], [43888, -4560], [-52536, -1785], [-20559, 360], [-52766, 1510], [-41015, 2394], [-54060, 1869], [-9537, -2891], [1640, -6777], [-92467, -1401], [79872, -791], [-126248, 194], [-2512, -3040], [-3384, -440], [9730, 1929], [-4200, 9390], [29614, -1200], [5140, 5584], [13628, -2359], [-31645, 8258], [-5960, 2080], [-3004, -3487], [58534, -3315], [41185, -1065], [-19160, -10590], [-31588, 1120], [61303, 304], [69442, -6750], [28512, 9456], [14210, -1679], [-1271, 7178], [29330, 2350], [41798, 5730], [-37300, 5300], [-10372, 4064], [-100996, 1907], [-79742, -5594], [85580, -3752], [-75655, -4734], [-110034, -1020], [2155, -2751], [26867, 6566], [-91010, -452], [-17835, 10175], [-20909, 12002], [76440, -3748], [25356, -7853], [119020, -2671], [52696, -360], [71334, 4423], [-36045, -6611], [-128342, 2454], [-37579, -10142], [-58048, 874], [112387, 2065], [51029, -413], [-43476, 460], [-57292, -3314], [-63933, 629], [64562, -2780], [16468, -3280], [-15490, -2295], [-31089, -1987], [55590, 11404], [-75049, 3430], [-89845, -1359], [39122, -8206], [-68968, 3490], [-53502, 1350], [-35304, -480], [-19183, 4910], [38520, -12346], [115130, 710], [-156272, 186], [-214, -9045], [32276, 4612], [19420, -12630], [166635, -128], [9405, -7069], [-59151, 11287], [51905, -12565], [-13566, -1088], [18406, 8080], [120660, 2257], [98640, -2936], [-83331, -6437], [-164655, 1003], [-139206, -5850], [109480, 6199], [125259, 5822], [42044, -14370], [-12570, -4110], [21160, 11739], [195252, -334], [-21528, 2525], [123744, -6788], [-71474, 9407], [-92815, 9435], [68874, -6395], [-50596, 9260], [-106536, 1820], [135140, 2285], [57429, -9885], [-21505, 15520], [79300, -1255], [18441, -4137], [-71650, -1931], [49769, -2108], [-86050, 3654], [-122141, -1435], [-18068, -18014], [58845, 3935], [-8110, -15755], [38541, -880], [-104997, -4179], [-3710, 10046], [-77830, 9142], [-3195, 5670], [162690, 1160], [-50020, -11176], [58570, -13808], [126469, -405], [33297, -3401], [-111776, 2392], [80062, -10245], [115166, 6210], [-30778, -12331], [87243, -6955], [112674, -2650], [98635, -636], [93678, 12480], [-58357, -12084], [-67860, -16155], [-147079, 6488], [123294, 8310], [65913, 664], [-58597, 8365], [-104061, -5227], [173100, 2040], [-39202, -471], [-68491, -3057], [-190848, -984], [228925, -70], [-52880, -15435], [-94635, 11435], [-103635, -12997], [132750, 9362], [20023, 13160], [-3747, -17145], [158343, -7374], [108481, 12007], [-122600, -9487], [44738, -1895], [-183120, -8530], [134393, -1181], [-245473, 2274], [-16838, -9725], [18905, -6385], [37018, 3021], [-113529, 14822], [-91295, -5681], [40068, -4240], [170939, -1812], [268492, -899], [-20369, 13917], [-48814, -8090], [-81765, 160], [-133430, 12655], [12048, -1420], [-101528, 10176], [85863, -3074], [3274, -6378], [-160360, 9970], [-169936, 2510], [114070, 1370], [22120, -11936], [-127757, -11500], [-53650, -4293], [14852, -13280], [-140475, 8528], [-35160, -5072], [-100150, -690]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1296_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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