
// Make newform 128.5.c.a in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_128_c();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_128_c_Hecke();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_128_5_c_a();".
// 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_128_5_c_a();".
// 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 := [1, 4, 12, 12, -8, -12, 12, -4, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0, 0, 0, 0, 0], [344, 1528, 1570, -268, -2362, 1996, -638, 152], [-1120, 832, 2740, -168, -2864, 2120, -676, 144], [-2016, 192, 580, 1656, 720, -1624, 524, -176], [-2824, -12120, -10662, 9620, 8406, -9396, 3226, -824], [7768, 32360, 24674, -42620, 6430, 8732, -3742, 1288], [1664, 8144, 11200, 11184, -33720, 22768, -7008, 1488], [-896, -22400, -73968, 10528, 81920, -64672, 20784, -4672]];
    Rf_basisdens := [1, 51, 51, 51, 51, 51, 51, 51];
    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_128_c();"
function MakeCharacter_128_c()
    N := 128;
    order := 2;
    char_gens := [127, 5];
    v := [1, 2];
    // 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;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_128_c_Hecke();"
function MakeCharacter_128_c_Hecke(Kf)
    N := 128;
    order := 2;
    char_gens := [127, 5];
    char_values := [[-1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0]];
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    values := ConvertToHeckeField(char_values : pass_field := true, Kf := Kf); // the value of chi on the gens as elements in the Hecke field
    F := Universe(values);// the Hecke field
    chi := DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),values);
    return chi;
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 := 5;
    raw_aps := [[0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [-6, 0, -1, 0, 0, 0, 0, 0], [0, -1, 0, 0, -1, 0, 0, 0], [0, -2, 0, 0, 1, 0, 1, 0], [-30, 0, 0, -1, 0, 0, 0, -1], [30, 0, -3, 1, 0, 0, 0, 2], [0, -10, 0, 0, -3, 2, 3, 0], [0, -7, 0, 0, -2, -1, 6, 0], [-54, 0, 3, 4, 0, 0, 0, -4], [0, 64, 0, 0, -3, 7, 6, 0], [-350, 0, -12, -5, 0, 0, 0, -5], [-366, 0, -76, 0, 0, 0, 0, 6], [0, 1, 0, 0, 10, -12, 6, 0], [0, -242, 0, 0, 9, 17, 2, 0], [-222, 0, 2, -27, 0, 0, 0, -3], [0, -29, 0, 0, 2, -26, -12, 0], [-1582, 0, -36, -5, 0, 0, 0, 19], [0, 174, 0, 0, 15, 12, -45, 0], [0, -221, 0, 0, 30, -31, -22, 0], [70, 0, -21, 27, 0, 0, 0, -24], [0, -514, 0, 0, 58, 4, -48, 0], [0, -111, 0, 0, 110, 14, -8, 0], [-2874, 0, -181, -53, 0, 0, 0, -16], [-466, 0, -183, 13, 0, 0, 0, -14], [-5550, 0, -298, -23, 0, 0, 0, -7], [0, -241, 0, 0, -102, 17, -54, 0], [0, 304, 0, 0, -17, 24, 55, 0], [7450, 0, -309, -44, 0, 0, 0, 4], [-1134, 0, 68, -116, 0, 0, 0, 20], [0, -268, 0, 0, 173, -69, 78, 0], [0, -308, 0, 0, -203, -24, 109, 0], [6594, 0, 464, 116, 0, 0, 0, 130], [0, -819, 0, 0, 258, 120, 42, 0], [6618, 0, -63, -42, 0, 0, 0, -114], [0, 313, 0, 0, 290, 107, -66, 0], [-21246, 0, 354, 149, 0, 0, 0, 77], [0, 15, 0, 0, 154, -160, -102, 0], [0, 299, 0, 0, -1, 60, 152, 0], [30162, 0, -958, 45, 0, 0, 0, -3], [0, 2419, 0, 0, 212, -2, 78, 0], [11882, 0, -9, -304, 0, 0, 0, 152], [0, -3060, 0, 0, 277, 43, -82, 0], [-8178, 0, -399, 149, 0, 0, 0, -190], [-1494, 0, 1557, 266, 0, 0, 0, 10], [0, 2287, 0, 0, 289, -42, -468, 0], [0, -2365, 0, 0, 72, -142, -642, 0], [0, -1920, 0, 0, 635, -95, -438, 0], [0, -1727, 0, 0, -788, 348, -128, 0], [-27446, 0, -879, -82, 0, 0, 0, 302], [5190, 0, -805, 315, 0, 0, 0, 96], [0, 2858, 0, 0, 618, 400, 232, 0], [19966, 0, 1173, 393, 0, 0, 0, -390], [0, -4213, 0, 0, -126, -434, 76, 0], [-19374, 0, 1204, -404, 0, 0, 0, 140], [0, -3821, 0, 0, -896, -393, 406, 0], [56970, 0, -403, -30, 0, 0, 0, -222], [0, 2018, 0, 0, -395, 25, -654, 0], [30978, 0, 1134, -71, 0, 0, 0, -143], [-22986, 0, -1025, 303, 0, 0, 0, 312], [0, 6312, 0, 0, 65, -158, -249, 0], [-37110, 0, -787, -414, 0, 0, 0, -558], [0, 5378, 0, 0, -723, 158, 231, 0], [0, 5505, 0, 0, -835, -556, -8, 0], [40018, 0, -1164, 128, 0, 0, 0, 38], [-37398, 0, 487, 800, 0, 0, 0, -392], [0, -6224, 0, 0, 1163, 68, -585, 0], [8610, 0, 4224, 680, 0, 0, 0, 308], [0, -2491, 0, 0, -2400, -338, 778, 0], [-44454, 0, 1221, -1246, 0, 0, 0, -358], [78642, 0, 1428, 532, 0, 0, 0, 80], [0, -8481, 0, 0, -978, -195, 18, 0], [0, -8210, 0, 0, 627, -497, -114, 0], [-5518, 0, -228, -981, 0, 0, 0, 195], [0, -3759, 0, 0, 1024, 794, -210, 0], [0, 6640, 0, 0, -1888, 112, -624, 0], [29442, 0, -5404, 1115, 0, 0, 0, 427], [-82630, 0, -4257, -1152, 0, 0, 0, -48], [-82242, 0, -3403, -199, 0, 0, 0, -926], [-124430, 0, 1356, -1288, 0, 0, 0, -874], [0, 3126, 0, 0, 643, -200, 107, 0], [22586, 0, 4023, -1080, 0, 0, 0, 552], [0, 6554, 0, 0, 84, -290, -1964, 0], [39390, 0, 2397, -1583, 0, 0, 0, -614], [0, 8769, 0, 0, 473, 1288, -336, 0], [0, -506, 0, 0, 867, -406, -607, 0], [-41874, 0, 5353, 1373, 0, 0, 0, 298], [-61966, 0, -7140, 264, 0, 0, 0, 822], [-92598, 0, -1703, 262, 0, 0, 0, 950], [0, 2414, 0, 0, 2234, -876, 1440, 0], [0, -452, 0, 0, 1979, 1150, 501, 0], [0, -8240, 0, 0, 3343, 333, 658, 0], [0, -9317, 0, 0, -3083, 846, 2268, 0], [0, -9145, 0, 0, -2224, -984, -664, 0], [0, 4377, 0, 0, -3622, -590, 1200, 0], [0, 1645, 0, 0, -1846, -569, 246, 0], [109890, 0, 2242, -2347, 0, 0, 0, -1331], [-23646, 0, 312, 956, 0, 0, 0, -1454], [0, 6644, 0, 0, -169, 804, 2115, 0], [158674, 0, -11136, -793, 0, 0, 0, 143], [0, 838, 0, 0, -2141, 1896, 4155, 0], [-256638, 0, 12, -1069, 0, 0, 0, -1709], [0, -18366, 0, 0, 2925, 1758, 327, 0], [253026, 0, 1624, -836, 0, 0, 0, -190], [0, 4602, 0, 0, -4233, -30, -99, 0], [-174846, 0, -2520, 736, 0, 0, 0, 1756], [0, -7330, 0, 0, -1351, -2472, 2273, 0], [-167550, 0, -672, 1712, 0, 0, 0, -344], [0, -987, 0, 0, 6303, -1074, 2604, 0], [-316442, 0, -2541, 1379, 0, 0, 0, 344], [0, -28708, 0, 0, -2134, 2538, 2676, 0], [102906, 0, 7911, 1784, 0, 0, 0, -1096], [101142, 0, 7335, 839, 0, 0, 0, 1456], [0, -36702, 0, 0, 177, 948, 525, 0], [0, 31501, 0, 0, 1406, -1117, -834, 0], [-343314, 0, 217, 1309, 0, 0, 0, -2062], [0, -18234, 0, 0, -5585, -124, 795, 0], [0, 1923, 0, 0, -2240, -4025, -3034, 0], [-120918, 0, -7719, 4566, 0, 0, 0, 2934], [0, 13357, 0, 0, -8910, 1022, -1972, 0], [14314, 0, 13851, -1924, 0, 0, 0, 1748], [212718, 0, 585, -3651, 0, 0, 0, 42], [182274, 0, -6264, -2745, 0, 0, 0, -345], [0, -5089, 0, 0, -752, -1120, -2640, 0], [0, -47885, 0, 0, 7172, -946, -1458, 0], [165714, 0, -1776, -105, 0, 0, 0, 3615], [-24030, 0, 12612, -3221, 0, 0, 0, -1397], [0, -202, 0, 0, 1020, -1310, -2996, 0], [0, -6523, 0, 0, -453, 1538, 5076, 0], [290698, 0, 12735, 408, 0, 0, 0, -960], [0, -51295, 0, 0, -260, -1556, 6240, 0], [0, -41349, 0, 0, 285, 966, 3228, 0], [0, 2370, 0, 0, -4544, -2038, -4644, 0], [117370, 0, 3609, 3918, 0, 0, 0, -3498], [366738, 0, -5020, -1904, 0, 0, 0, -2122], [-394834, 0, 14073, -979, 0, 0, 0, 2378], [237378, 0, -3296, -465, 0, 0, 0, 2991], [0, 21663, 0, 0, 2812, 1202, 3666, 0], [-85374, 0, -4474, 5249, 0, 0, 0, -2711], [144786, 0, -2188, -1952, 0, 0, 0, 1430], [0, -4338, 0, 0, -1403, 3236, 273, 0], [-412110, 0, -508, -4221, 0, 0, 0, 795], [0, 19793, 0, 0, 4153, 5176, 7920, 0], [0, 15092, 0, 0, 4113, -98, 6667, 0], [-190590, 0, -9006, -2587, 0, 0, 0, -643], [0, -22521, 0, 0, -5757, 6420, 2232, 0], [184418, 0, -10122, -1247, 0, 0, 0, -4055], [-682590, 0, 12680, -1876, 0, 0, 0, -350], [0, -66647, 0, 0, 2356, 4566, 3222, 0], [0, 28936, 0, 0, 3729, -2677, -2146, 0], [153418, 0, -25995, 4314, 0, 0, 0, 762], [234978, 0, -5424, -3240, 0, 0, 0, -2844], [0, 10892, 0, 0, 5535, -478, 4485, 0], [0, -31215, 0, 0, -3029, -242, 5852, 0], [0, 77175, 0, 0, -3196, -932, 3096, 0], [0, -15430, 0, 0, -6761, -745, 606, 0], [0, -287, 0, 0, -4084, 1169, -678, 0], [424590, 0, 1745, -2891, 0, 0, 0, -1246], [415814, 0, -1029, 3067, 0, 0, 0, 2032], [682170, 0, -10097, -2416, 0, 0, 0, 2752], [0, -86322, 0, 0, -2951, 3910, -853, 0], [734850, 0, -2064, 148, 0, 0, 0, 578], [0, 17079, 0, 0, -7133, -7132, 1464, 0], [0, 30755, 0, 0, 8264, -2244, -11236, 0], [-536706, 0, 6453, -535, 0, 0, 0, 4186], [0, 23101, 0, 0, 4337, 700, -7800, 0], [0, -35020, 0, 0, 13692, 344, -3600, 0], [-363742, 0, 5832, 2039, 0, 0, 0, 5927]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_128_c_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_128_5_c_a();".
// 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_128_5_c_a(:prec:=8)
    chi := MakeCharacter_128_c();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 5));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(997) - 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_128_5_c_a();".
// 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_128_5_c_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_128_c();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,5,sign)));
    Vf := Kernel([<5,R![101392, -2976, -1128, 24, 1]>],Snew);
    return Vf;
end function;