
// Make newform 350.8.c.i in Magma, downloaded from the LMFDB on 12 June 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_350_c();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_350_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_350_8_c_i();".
// 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_350_8_c_i();".
// 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 := [4796100, 0, 4381, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [0, 1, 0, 0], [0, 2191, 0, 1], [2191, 0, 1, 0]];
    Rf_basisdens := [1, 1, 2190, 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_350_c();"
function MakeCharacter_350_c()
    N := 350;
    order := 2;
    char_gens := [127, 101];
    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_350_c_Hecke();"
function MakeCharacter_350_c_Hecke(Kf)
    N := 350;
    order := 2;
    char_gens := [127, 101];
    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]];
    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 := 8;
    raw_aps := [[0, 0, -8, 0], [0, 1, -2, 0], [0, 0, 0, 0], [0, 0, -343, 0], [2193, 0, 0, 129], [0, -51, 4448, 0], [0, -75, -18804, 0], [-21842, 0, 0, -18], [0, -1542, 19548, 0], [-5421, 0, 0, 1581], [104036, 0, 0, -1044], [0, -7980, 67546, 0], [135096, 0, 0, -5394], [0, 42, -262552, 0], [0, 603, 254106, 0], [0, 1602, 338898, 0], [-952608, 0, 0, -192], [-33340, 0, 0, -52638], [0, -43320, 2139556, 0], [-248544, 0, 0, -115584], [0, 34128, -1551502, 0], [6296449, 0, 0, 27861], [0, -34164, -1066632, 0], [5565240, 0, 0, 47850], [0, -88719, -5739884, 0], [6547230, 0, 0, 261852], [0, -378207, -1361242, 0], [0, 186870, -6895344, 0], [7733089, 0, 0, 155811], [0, -112044, -3867942, 0], [0, -104088, -30306104, 0], [25836810, 0, 0, 466362], [0, -234726, 14086866, 0], [-40402022, 0, 0, 235722], [-43658778, 0, 0, 474468], [19254983, 0, 0, -980781], [0, 94116, 10768486, 0], [0, -976122, -55886632, 0], [0, 1530327, -22480614, 0], [0, 1266795, -52629852, 0], [23299788, 0, 0, -271608], [50054672, 0, 0, 1094190], [106439529, 0, 0, 219213], [0, -1934922, -82926682, 0], [0, -169542, 121095846, 0], [-58040576, 0, 0, -2747424], [-63463273, 0, 0, 908895], [0, 4209825, 1266038, 0], [0, -2418453, 12763266, 0], [-43722224, 0, 0, 330834], [0, -395094, -7681722, 0], [193805973, 0, 0, 2025777], [-135349210, 0, 0, -2111508], [332263290, 0, 0, 820362], [0, -2638764, -131330994, 0], [0, 299526, 325623468, 0], [133295214, 0, 0, -6027024], [283534472, 0, 0, -4705560], [0, -1877928, 314714746, 0], [122458857, 0, 0, 7705155], [0, 4540875, -472428022, 0], [0, -7859025, 438156588, 0], [0, 7918125, 97981726, 0], [-235726518, 0, 0, -9493110], [0, -5894967, -13015552, 0], [0, -4936440, -589385214, 0], [546234860, 0, 0, 8474352], [0, 89292, 1361220406, 0], [0, -22352802, 68585736, 0], [449840998, 0, 0, -23271048], [0, -1637337, 679644948, 0], [-745940136, 0, 0, 13958736], [0, 21726315, 630653266, 0], [0, -32373414, -381654862, 0], [1103812, 0, 0, -12871632], [0, -18343212, 695168448, 0], [253372461, 0, 0, 36834999], [0, -33201963, 845540476, 0], [707794563, 0, 0, -27237651], [-82453910, 0, 0, 23975340], [-675794148, 0, 0, -27308772], [850089455, 0, 0, -23856243], [-1198682331, 0, 0, -33425007], [0, -7855104, 1771241858, 0], [1369674406, 0, 0, 4298454], [0, 40695786, -553745712, 0], [-1250402205, 0, 0, -31901775], [0, -24107298, 1571845786, 0], [-888531492, 0, 0, 9749154], [0, 19516632, -1334436592, 0], [0, -760791, 3577988646, 0], [-283288842, 0, 0, -40113738], [0, -58192446, 1800168556, 0], [1999563243, 0, 0, 45939819], [686111827, 0, 0, -33388557], [0, -61154985, -55917342, 0], [2013648702, 0, 0, -20490192], [-593175066, 0, 0, 46124388], [0, -15081348, -4035929392, 0], [4979582453, 0, 0, -15163821], [0, 117859356, -251414684, 0], [0, 47864754, -1172701314, 0], [0, 153590844, 1127151648, 0], [-2871487122, 0, 0, -69825768], [2096914676, 0, 0, 49561416], [0, -119916645, -2619169784, 0], [0, 109645608, 1210941456, 0], [0, -80608443, -3284110392, 0], [3366557019, 0, 0, -51341409], [1236847118, 0, 0, 36342564], [0, 84980913, 828628966, 0], [0, -91441116, 1904925638, 0], [0, -5703888, -9565062714, 0], [4691690182, 0, 0, -86624322], [6929457797, 0, 0, -18301455], [1333447170, 0, 0, -44575488], [0, -66367287, 1681651598, 0], [0, -104600616, -3324909024, 0], [0, 22735356, -4811070642, 0], [3224501379, 0, 0, 167794251], [-3525919180, 0, 0, 59202522], [0, 202688574, -5517167482, 0], [0, -216017109, 3492484776, 0], [0, -50390988, -3633034212, 0], [9428588276, 0, 0, -104688084], [-2596318935, 0, 0, -54464433], [1082501467, 0, 0, -18812067], [6011904390, 0, 0, -106084890], [0, -75079896, 3682419376, 0], [0, -121855047, -2406607072, 0], [2745537295, 0, 0, 55089735], [0, -25354044, -14181915192, 0], [-6326550841, 0, 0, 177095163], [0, -139325286, 16980987166, 0], [5761895406, 0, 0, 237049116], [-8272445702, 0, 0, 110918292], [0, -233301483, -3036490992, 0], [0, 20827059, 8868406306, 0], [0, -86720499, 849957756, 0], [-9671444139, 0, 0, -257391741], [2259352394, 0, 0, 187667058], [-13996736901, 0, 0, 339890553], [0, 188105916, 10245934688, 0], [0, -268044042, -8799982704, 0], [-1946558624, 0, 0, 283164114], [-15100417566, 0, 0, -382366854], [0, 158710428, 15511794578, 0], [0, -186837864, -20743961034, 0], [-8427078716, 0, 0, -60455124], [0, 242902272, 12370148688, 0], [0, 5866812, 2752923586, 0], [2586024804, 0, 0, -498070662], [0, -465858936, 3911561468, 0], [0, 447314664, 15162482496, 0], [0, 139556634, 10094807656, 0], [-9560892744, 0, 0, 245401176], [246621661, 0, 0, -771853431], [-5172990528, 0, 0, 332610738], [0, -112571847, 10877398756, 0], [-41630512116, 0, 0, 84416538], [0, -712760748, -2602180044, 0], [0, 596294874, 5187418518, 0], [0, -354990546, 28616589316, 0], [39539160744, 0, 0, -334204872], [0, 535742172, -28246982874, 0], [0, 11063439, 52023190938, 0], [8970275720, 0, 0, 874619232], [0, -449228223, 25606244116, 0]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_350_c_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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