
// Make newform 8.7.d.b in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_8_d();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_8_d_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_8_7_d_b();".
// 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_8_7_d_b();".
// 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 := [256, -16, 6, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [0, 2, 0, 0], [12, -6, 1, -1], [36, -2, 15, 1]];
    Rf_basisdens := [1, 1, 4, 4];
    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_8_d();"
function MakeCharacter_8_d()
    N := 8;
    order := 2;
    char_gens := [7, 5];
    v := [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;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_8_d_Hecke();"
function MakeCharacter_8_d_Hecke(Kf)
    N := 8;
    order := 2;
    char_gens := [7, 5];
    char_values := [[-1, 0, 0, 0], [-1, 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 := 7;
    raw_aps := [[0, 1, 0, 0], [-13, 2, 1, 0], [-2, 6, -4, -2], [12, -20, 8, -4], [187, 114, 57, 0], [-110, 202, -92, 18], [1242, -400, -200, 0], [-429, 130, 65, 0], [-252, 676, -424, -172], [922, -1742, 820, -102], [-784, 1392, -608, 176], [-370, 214, 156, 526], [-30590, 2208, 1104, 0], [47243, 4242, 2121, 0], [2728, -3608, 880, -1848], [-1322, 4862, -3540, -2218], [135835, -654, -327, 0], [-2902, 3458, -556, 2346], [-191581, -11934, -5967, 0], [-14356, 31180, -16824, -2468], [119514, -17072, -8536, 0], [9880, -20904, 11024, 1144], [-869341, 6178, 3089, 0], [202234, -23856, -11928, 0], [-188998, -85392, -42696, 0], [-4690, -3978, 8668, 13358], [51804, -114244, 62440, 10636], [1467387, -35470, -17735, 0], [-66110, 128186, -62076, 4034], [636482, 832, 416, 0], [18624, 2496, -21120, -39744], [-395197, -314462, -157231, 0], [-1429790, 263904, 131952, 0], [2094635, 20562, 10281, 0], [-61562, 59502, 2060, 63622], [65732, -138652, 72920, 7188], [-108710, 245362, -136652, -27942], [1660211, -17406, -8703, 0], [56380, -39012, -17368, -73748], [18018, -32422, 14404, -3614], [1256419, 473634, 236817, 0], [73878, -154050, 80172, 6294], [-115040, 216736, -101696, 13344], [-1496326, 659568, 329784, 0], [102238, -111898, 9660, -92578], [-75092, -37492, 112584, 187676], [5958403, -613918, -306959, 0], [-593776, 1263632, -669856, -76080], [7516819, 490434, 245217, 0], [-236434, 487350, -250916, -14482], [-13075110, 340688, 170344, 0], [920392, -1750392, 830000, -90392], [10914266, -255504, -127752, 0], [-12933861, 417650, 208825, 0], [1416418, -1848384, -924192, 0], [-322932, 712556, -389624, -66692], [-871790, 1530698, -658908, 212882], [-687816, 1225464, -537648, 150168], [869702, -1674322, 804620, -65082], [11993786, 1670992, 835496, 0], [292939, -3451822, -1725911, 0], [1356942, -2660522, 1303580, -53362], [518835, -3489086, -1744543, 0], [-611596, 793364, -181768, 429828], [27285602, 2580384, 1290192, 0], [-276822, -110590, 387412, 664234], [22365403, 458162, 229081, 0], [9115778, -975552, -487776, 0], [25916251, -1408398, -704199, 0], [-1150406, 2823762, -1673356, -522950], [-15436094, 1510656, 755328, 0], [2429404, -4830916, 2401512, -27892], [286728, -1040312, 753584, 466856], [-105866, 938782, -832916, -727050], [35855739, 5694514, 2847257, 0], [-1431744, 2880832, -1449088, -17344], [1276478, -2058810, 782332, -494146], [-819758, 410762, 408996, 1228754], [38149210, 402288, 201144, 0], [60936482, -1380192, -690096, 0], [-38220157, -41054, -20527, 0], [-1696818, 3636886, -1940068, -243250], [-991000, 2999080, -2008080, -1017080], [78548058, -2988560, -1494280, 0], [4408500, -8183084, 3774584, -633916], [-48918197, 4059090, 2029545, 0], [-34593990, -7948048, -3974024, 0], [-124634686, -5588064, -2794032, 0], [4467186, -8078038, 3610852, -856334], [4493784, -7983208, 3489424, -1004360], [34917555, 6757442, 3378721, 0], [-2038768, 4676496, -2637728, -598960], [-778084, 50428, 727656, 1505740], [-83649365, 1776594, 888297, 0], [-39037885, 11160546, 5580273, 0], [-3776364, 6671028, -2894664, 881700], [555914, -1616926, 1061012, 505098], [-99888030, 686048, 343024, 0], [33516059, -7937742, -3968871, 0], [-2109158, 4658738, -2549580, -440422], [33325379, 4558626, 2279313, 0], [-304606, 1119514, -814908, -510302], [174667891, 12203586, 6101793, 0], [179076610, -16873248, -8436624, 0], [-149418229, 7804242, 3902121, 0], [-20230302, 6943168, 3471584, 0], [-203971013, -16878990, -8439495, 0], [-21863774, -25888896, -12944448, 0], [-4302364, 4547972, -245608, 4056756], [77319098, 12431952, 6215976, 0], [3704528, -2773680, -930848, -4635376], [2257966, -8223370, 5965404, 3707438], [7072474, -14650416, -7325208, 0], [-56165221, -14079822, -7039911, 0], [2482772, -7765388, 5282616, 2799844], [134842618, 5640048, 2820024, 0], [-15747997, -33151518, -16575759, 0], [6543308, -11214164, 4670856, -1872452], [-11561134, 24356618, -12795484, -1234350], [228809891, -26609630, -13304815, 0], [7750022, -9255570, 1505548, -6244474], [37790458, -18350608, -9175304, 0], [7173582, -13851370, 6677788, -495794], [-163957461, 21133778, 10566889, 0], [-76567133, -5647966, -2823983, 0], [-19645462, 36329410, -16683948, 2961514], [4863198, -12668954, 7805756, 2942558], [13327192, -25580776, 12253584, -1073608], [-2997340, 7525700, -4528360, -1531020], [-8955398, 21110290, -12154892, -3199494], [-558894381, 11794498, 5897249, 0], [19181596, -32551812, 13370216, -5811380], [16579656, -28495480, 11915824, -4663832], [-16414538, 23997662, -7583124, 8831414], [-264318238, -35379296, -17689648, 0], [-96414662, 81871856, 40935928, 0], [-11651330, 29823878, -18172548, -6521218], [-203636285, -25406878, -12703439, 0], [17393306, -41836366, 24443060, 7049754], [832447362, -13956448, -6978224, 0], [516605403, -15403982, -7701991, 0], [32950614, -68016514, 35065900, 2115286], [11689460, -31811052, 20121592, 8432132], [-259750037, 26142738, 13071369, 0], [2368298, 6225154, -8593452, -10961750], [-39558804, 78260300, -38701496, 857308], [-1186202, 8750670, -7564468, -6378266], [-397553086, 59793376, 29896688, 0], [401207963, 26881266, 13440633, 0], [17446224, -29341488, 11895264, -5550960], [-17476542, 27249722, -9773180, 7703362], [72502594, -49439424, -24719712, 0], [-357237741, 50016898, 25008449, 0], [-3324716, -4523532, 7848248, 11172964], [209628107, 3926418, 1963209, 0], [-18381320, 19357624, -976304, 17405016], [22024516, -35172124, 13147608, -8876908], [189876410, 71702896, 35851448, 0], [920695898, 6291408, 3145704, 0], [5107298, -9867046, 4759748, -347550], [976823155, -44665278, -22332639, 0], [-951730302, 44503520, 22251760, 0], [-13268180, 38487052, -25218872, -11950692], [-781809653, 4029714, 2014857, 0], [-631362662, -24816912, -12408456, 0], [-42287836, 92153028, -49865192, -7577356], [6688784, -6866288, 177504, -6511280], [26512494, -60021962, 33509468, 6996974]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_8_d_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_8_7_d_b();".
// 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_8_7_d_b(:prec:=4)
    chi := MakeCharacter_8_d();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 7));
    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_8_7_d_b();".
// 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_8_7_d_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_8_d();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,7,sign)));
    Vf := Kernel([<3,R![-276, 24, 1]>],Snew);
    return Vf;
end function;