
// Make newform 1176.4.a.r in Magma, downloaded from the LMFDB on 18 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1176_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_1176_4_a_r();".
// 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_1176_4_a_r();".
// 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 := [-126, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rfbasis := [Kf.1^i : i in [0..Degree(Kf)-1]];
    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_1176_a();"
function MakeCharacter_1176_a()
    N := 1176;
    order := 1;
    char_gens := [295, 589, 785, 1081];
    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_1176_a_Hecke(Kf)
    return MakeCharacter_1176_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], [-3, 0], [5, -1], [0, 0], [5, -5], [-10, 1], [0, -4], [62, -7], [72, 4], [-45, -5], [-181, 2], [-26, -1], [-76, -18], [188, 27], [202, -36], [351, -5], [-279, -27], [-594, 28], [80, 73], [346, -76], [-440, 63], [-377, -48], [-175, 67], [-918, -22], [837, 55], [-274, 76], [-406, -35], [1791, -9], [-460, 47], [356, 22], [469, -20], [1409, 107], [-882, -14], [1504, -73], [2430, -94], [3249, 37], [-72, -234], [2088, 172], [670, 32], [-1746, -14], [1616, -118], [2170, 97], [2012, -18], [1369, -226], [1962, -162], [-36, 332], [-1926, 206], [2619, -153], [-2597, -99], [-1466, -83], [-3100, 98], [3668, -82], [3949, -285], [-423, -103], [-2506, -392], [1134, 378], [2587, 113], [2493, 305], [1810, 369], [-1422, 90], [-2060, 115], [-2133, 207], [-170, 747], [-4396, -518], [-395, 502], [747, 495], [1898, -153], [-4159, 468], [-3636, 216], [5994, 296], [-1004, -58], [-4734, -162], [-5831, -110], [-3986, -821], [5318, -737], [-738, 342], [-6854, -692], [-1358, -801], [-72, -216], [2107, 350], [-7924, -442], [568, -765], [8464, -58], [8272, 477], [8109, -207], [-5427, 265], [9832, -26], [-17261, 54], [-13662, 198], [1286, 675], [-14000, -274], [-1278, 986], [2213, 758], [-7947, 117], [-13168, -313], [-3344, -1286], [12739, 689], [12906, 126], [5842, 55], [-3880, 1559], [3240, -692], [-4315, 99], [1409, 459], [-3784, -590], [10252, -317], [-377, 1520], [-4113, 1139], [364, -1822], [-5166, -1858], [-23365, -268], [17981, 974], [-1116, -422], [12514, -904], [11224, -991], [-15705, 35], [-17154, 122], [7228, 963], [-17042, 716], [17005, 927], [1368, -608], [-4888, 765], [-15119, -558], [1053, -1395], [-6813, 1431], [10486, 1087], [10827, -1885], [3582, 280], [-12514, -1616], [3043, 1960], [980, -385], [11800, -117], [-13630, 1376], [-10295, 2140], [13822, -420], [13500, 792], [-11359, -142], [5342, 1800], [-466, 2870], [8613, -2043], [-2668, 2506], [12238, -3058], [13019, 337], [-3960, 2240], [-7447, 1975], [-20386, -1503], [12744, 324], [25424, -1015], [-4158, 1818], [-2842, -2818], [-12290, 972], [14580, 242], [6246, 2714], [12430, -2241], [4244, -1850], [-1954, -2265], [-35190, -1282], [-13402, 1595], [14602, 928], [2035, 908], [-11259, -351], [37228, 1126], [13878, 1526], [-4393, 460], [-18549, 2183], [-9454, -140], [-2988, -1260], [-73, 406], [-24632, 1377], [27035, 1054], [30933, -103], [-21825, 2147], [12526, -376], [38844, 432], [7613, -1096], [10729, 3860], [-9468, 508], [12988, -2027], [9697, 4343], [19296, -872], [-18604, 3377], [25651, -2178], [-24705, 3595], [21716, 3647], [31626, 2786], [17114, 4432], [4905, -2079], [29142, 1160], [-48860, 1321], [-9017, 3590], [16160, 2038], [-15679, -1944], [-25277, -175], [2932, -908], [5310, -2610], [2709, -4711], [48582, -666], [14624, -655], [50814, 584], [2246, -4284], [-37746, -1138], [40477, -1557], [9206, -1421], [-44226, 3104], [64458, -368], [9788, -266], [-8537, -967], [-19440, 440], [-23485, 3793], [-13608, 796], [-9558, 2782], [-36244, -2375], [50733, 2385], [22169, 3473], [-13185, -4437], [29484, 1804], [-26452, 1945], [-40365, -3681], [-30744, 940], [17766, -6066], [17302, -3608], [-5374, 5545], [-53054, -2871], [-22046, 1116], [9981, 441], [-18545, -1151], [-5004, -2638], [56430, -2394], [35672, -3970], [14059, 6012], [-11120, -4414], [-49024, 407], [36144, -4804], [-43993, 1712], [-42314, -4544], [-58508, 735], [-26896, 2218], [14471, -2214], [-5215, 4567], [53244, -688], [29300, 3406], [86648, -730], [-20926, 621], [14453, -432], [76610, -2116], [-55404, -1188], [6660, -796], [-91513, -1756], [26176, 3258], [36448, -304], [-30528, -3704], [-17432, -3737], [50454, 562], [20254, 100], [-66664, -377], [-49329, 6107], [-57519, 333], [-40832, -2141], [602, -2601], [491, 7897], [279, -8091], [-76490, -2369], [-37827, -4887], [21916, 3707], [-18766, 6443], [56218, 2804], [-19880, 2131], [36689, 891], [10616, 2322], [29700, -5544], [-7879, 4423], [-99818, -657], [2466, 8614], [9053, 1944], [9397, -514], [-31473, -4887], [-2968, -3468], [-75325, 5489], [-15938, 387], [-100160, 1105], [-29016, -2988], [40302, 846], [1171, -596], [9976, -1858], [-30430, -5849], [7254, 8882], [77180, -122], [-131221, -1142], [-35087, -4877], [19889, 2332], [-104216, 1130], [-23130, 10386], [6183, -3937], [-71096, 6174], [20628, 2696], [-41030, 7891], [25681, -3257], [22834, -10387], [14670, 22], [112496, 1606], [7316, 5961], [22230, 368], [-20327, 9203], [12791, -9425], [58797, 3429], [-27784, -5129], [-120680, -65], [-94991, -1705], [54820, -3825], [30042, 554], [138968, -567], [-19134, 5314], [-24314, -6408], [-60664, 5166], [30688, -168], [8424, 7312], [27676, 12015], [-73211, -5021], [52560, 3956], [49789, -4932], [-2164, -4910], [-10342, 1953], [-79172, 673], [130783, -1435], [78526, -621], [45796, 7254], [-28745, 3430], [47528, -2635], [16424, -7729], [-53010, 1746], [-36931, 12631], [-52552, 10603], [29569, 5459], [-60398, -6219], [21596, -3510], [108424, -2063], [-6008, 16434], [22536, -242], [-139878, 2966], [-26855, 6748], [-36235, 8912], [1232, 6589], [-87660, 1908], [113787, -9189], [64621, -6608], [41935, -13023], [172111, 3173], [-7964, 1215], [-41706, 5434], [41018, -6732], [110767, 2673], [-109980, 5120], [14913, 8947], [146902, 2516], [-197217, -1485], [92384, -9467], [75874, -7348], [-35294, 15008], [-82071, 12757], [44460, 4968], [132574, 3128], [-122886, 728], [-156820, -4262], [50674, 9140], [116888, -1706], [-18566, 2429], [61137, -793], [-29070, 7722], [116362, 3581], [30843, 2521], [-17361, -19301], [81962, 6033], [-91202, -8968], [-32593, -12987], [148670, -9277], [7874, 11413], [183456, 4172], [-31284, -1512], [117873, 8927], [89766, -14846], [142804, 6903], [-166554, -2686], [64098, -6746], [-128304, 7336], [192420, -2052], [49230, -766], [-22050, 4410], [113662, -1541], [-11088, -12214], [28378, 15451], [194728, -5138], [10457, -432], [15386, 468], [-231363, 45], [147176, -1835], [28318, 19396], [-85707, -793], [-8737, -2881], [-6134, 7480], [-57986, 2187], [29561, -7709], [-90992, 1154], [67248, 12712], [-88380, -2340], [-47246, 824], [173867, 5741], [-10331, -6860], [-92898, 8216], [-85410, 11930], [72352, -15265], [-191331, -3411], [106661, 1015], [98865, 2961], [79371, -16673], [35262, -15542], [-16984, 1099], [54131, -13739], [-179168, -7298], [25930, 20205], [-80568, 3132], [26622, -3622], [122913, -495], [86320, 3517], [-149490, -1458], [-69863, 2615], [77346, -16092], [-86026, -5360], [66659, 5913], [250200, -3096], [-96102, 13070], [2700, 6908]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1176_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_1176_4_a_r();".
// 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_1176_4_a_r(:prec:=2)
    chi := MakeCharacter_1176_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_1176_4_a_r();".
// 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_1176_4_a_r( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1176_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![-106, -9, 1]>,<11,R![-3150, -5, 1]>],Snew);
    return Vf;
end function;