
// Make newform 784.4.a.ba in Magma, downloaded from the LMFDB on 16 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_784_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_784_4_a_ba();".
// 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_784_4_a_ba();".
// 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 := [-9, -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_784_a();"
function MakeCharacter_784_a()
    N := 784;
    order := 1;
    char_gens := [687, 197, 689];
    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_784_a_Hecke(Kf)
    return MakeCharacter_784_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, -1], [7, -2], [0, 0], [-16, -7], [14, 4], [77, -4], [-112, -3], [-34, -7], [-118, -28], [-98, -7], [173, -42], [210, 12], [172, 0], [42, 15], [-219, 42], [-28, -37], [-49, -74], [-168, -7], [-448, 56], [-483, 20], [26, 133], [196, 88], [-147, 60], [210, -76], [511, 106], [1106, -9], [1692, 63], [-1131, -14], [734, 140], [1448, -56], [-532, 233], [791, 224], [252, -152], [-15, -294], [-306, -133], [-329, 330], [76, -273], [644, -4], [2863, 118], [-1596, 357], [98, -272], [606, -231], [-1069, 84], [-878, -140], [2114, 357], [172, -168], [728, 600], [-4116, -165], [-273, -922], [-2513, 448], [-4692, -84], [-4151, 216], [-5208, 84], [-4011, -492], [3498, -777], [2863, -494], [2926, -541], [1733, 42], [646, 700], [-2184, 895], [1890, -576], [2604, -896], [2534, 41], [-2667, 932], [-7095, 546], [-2984, 651], [694, -700], [-3060, 693], [630, 668], [3549, 1596], [-3110, 805], [3794, 429], [5613, 1078], [2736, -28], [-3878, -449], [1649, 1190], [-6013, -470], [-3837, 420], [3745, 648], [-14532, 192], [-3158, 812], [-1998, 1575], [-686, -1308], [-9170, -829], [3980, 623], [4742, -2044], [-8445, -812], [-266, 940], [-432, 2240], [10556, -1351], [9394, 1501], [-9206, 567], [-4224, 2436], [10548, -1225], [6048, -1512], [2163, 1146], [2709, 396], [3332, 417], [-13475, 854], [-6784, -1652], [11957, -238], [4816, -737], [17643, -420], [5624, -623], [-8127, -64], [20356, 592], [21, -1932], [10314, -2457], [12586, 2100], [8890, -1441], [-9095, -1330], [-8786, -2828], [-6300, -2069], [-4688, 1848], [-20177, -1232], [-14308, -2112], [25662, 273], [5265, -630], [1052, -2296], [17283, -1186], [-154, -252], [17535, 822], [1176, 4641], [-12796, 2145], [-17770, 1904], [5213, 3654], [1134, -2205], [16800, -1352], [12887, -2], [-2332, -2891], [-7344, -2520], [-5914, 4417], [-14558, 308], [33761, -16], [28266, -1300], [-10241, 1738], [-11480, 2999], [-15162, -1428], [-20173, 3164], [17220, -3536], [29881, -350], [-9414, 119], [-19284, -1680], [483, 3254], [8344, -512], [5110, 1860], [-7707, -3828], [-22204, -1695], [-2846, -2387], [-11835, -1442], [-7266, 1968], [24316, -1848], [33894, 1755], [18260, -371], [-14160, 672], [-8958, -5971], [-17703, 4248], [-33866, -144], [-10073, -4502], [4444, 511], [-3434, -3668], [4048, -5880], [8232, 5109], [9579, -2436], [3906, -4779], [-15842, -4557], [17227, 5526], [34766, 4284], [6363, -2862], [7660, -1547], [18270, -2140], [13686, -399], [-34565, 644], [-29834, 3521], [8050, 2812], [24440, -3668], [15517, 4690], [-22960, 312], [-16037, -3006], [26066, -4067], [-16604, 4456], [-48402, -1232], [37093, -1004], [22270, 2947], [28707, -1218], [57469, -1078], [-11452, -1965], [5839, -7840], [-24906, -8175], [-26943, -1600], [-12876, 4872], [-37824, -301], [35147, 5330], [-756, 4221], [22673, 6248], [-44917, 1596], [71781, 1246], [16170, -2964], [-13566, 4263], [-13539, -2982], [-5432, -3784], [33523, 7722], [-2779, -5180], [-22260, -7464], [15351, 10986], [29246, 3891], [77328, -2205], [-33942, -6384], [20300, -1581], [-3301, -2436], [8638, -1460], [-20728, -7280], [23576, -8347], [2730, 8589], [1897, -13800], [41634, 2135], [60221, 5420], [2186, 4949], [33478, 448], [1929, 6034], [-33852, -7796], [-3513, -13944], [68790, -175], [-39564, 9288], [29594, 3276], [-7903, 7856], [-53690, -4613], [12670, -13357], [-49848, -6405], [-66527, -2338], [32760, 1447], [17040, -1456], [31335, -336], [46004, 9024], [-50358, 7269], [-26187, -1132], [-10311, 11298], [4812, 3696], [22316, -10876], [8192, 4529], [60620, 3273], [-34090, -5559], [-5639, -3598], [7070, 10832], [71442, -8073], [35896, 8888], [-1316, -11189], [-15896, -3087], [-3324, -7644], [63282, 4396], [44625, -6576], [-69714, -4725], [-5334, 7364], [44807, -5782], [2648, 6923], [19277, 17010], [93688, 3455], [66934, 7732], [33313, 1968], [-42426, -11557], [41332, -1904], [42231, -1726], [-85386, -2020], [9429, -7500], [-17808, -13091], [56130, -84], [49378, -5684], [-28500, 1904], [39585, -4074], [-31717, -1406], [2236, 12957], [77777, -200], [-27002, -15519], [87234, 3860], [28714, -8017], [-12256, 4403], [-36935, 7238], [-49005, 11620], [-58128, -483], [-23562, -7119], [47606, 1939], [-4200, 4080], [89614, -2196], [-13580, 13265], [75710, 8057], [49255, 6776], [26626, -12236], [90398, 417], [1554, -13836], [68925, 11802], [-35364, -1029], [50355, -6300], [-5824, -5284], [5090, 12012], [-31437, 13734], [-16366, 6999], [-63546, -1356], [15120, 18045], [-85232, -1180], [49245, -12340], [-23691, 13902], [-78030, -4921], [-62388, 4536], [-70580, 3759], [83894, 5460], [159580, 469], [-76202, 5292], [25178, -17563], [-71239, -13566], [74886, 4443], [26333, 6146], [-19669, -18004], [37168, 19089], [4072, 21280], [11137, -16296], [12516, 14424], [36442, -6209], [-79814, 11004], [3198, -11508], [42308, 2979], [121815, 1288], [65142, 1692], [35868, 12908], [-56821, 17780], [-63119, -17328], [97612, 3759], [-15456, -5555], [-81142, -7819], [-9686, -18452], [-90415, -12726], [-37451, -1694], [16072, 26792], [6664, 9895], [-158208, -5047], [-115276, 464], [-133838, 9548], [-50267, -6428], [59542, 17808], [9198, 13987], [119057, -8778], [-134874, 12348], [-140490, 10836], [56864, -15848], [44961, -13062], [-1140, -9240], [68299, 8790], [87316, 2583], [72492, -17076], [41139, 8298], [13412, -11007], [139799, 2016], [-17766, -10332], [-129542, -2347], [32157, 3430], [-39802, -12784], [23534, -19549], [-56280, 735], [-34637, -14252], [88616, 10640], [22578, -6188], [76433, -12352], [-48806, 21007], [48680, -15589], [75432, 2407], [55559, -1512], [-47586, -13260], [-41026, 21595], [109914, -5936], [93584, -11599], [133644, -14711], [63846, 28161], [9086, 5936], [103698, 4933], [-15063, 3010], [75516, -11397], [123872, 4928], [-88515, 19100], [-66367, 15776], [130186, -7308], [-157269, -6402], [9806, 25844], [-1512, -26656], [-142377, 9912], [-178836, 3952], [-4942, 36917], [179950, -11949], [30387, -4306], [180408, 875], [78400, 31168], [-18094, -10416], [-125265, 15270], [-150124, 12173], [179900, 5625], [-145862, -6587], [-16037, 19124], [74130, 1021], [-122206, -868], [-103492, -20720], [-10319, -6314], [-16457, -8994], [123771, 17724], [-7890, 26537], [-59843, -18164], [-15897, 18834], [105434, 2079], [-97287, -1610], [150390, -6300], [-132076, 16659], [-230804, -1943], [79233, -22816], [97933, 21910], [-42580, 37520], [13712, -1757], [-13234, -2604], [12887, 25694], [74870, 1169], [-9198, -11339], [138138, -372], [185990, -10885], [-150359, 1750], [27475, 31146], [215216, 14336], [-120708, -10728], [-63854, -11796], [12439, -48518], [89440, -10829], [37782, -33012], [-34916, 17939], [-227150, -8027]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_784_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_784_4_a_ba();".
// 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_784_4_a_ba(:prec:=2)
    chi := MakeCharacter_784_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_784_4_a_ba();".
// 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_784_4_a_ba( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_784_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<3,R![-37, 0, 1]>,<5,R![-99, -14, 1]>],Snew);
    return Vf;
end function;