
// Make newform 8.51.d.a in Magma, downloaded from the LMFDB on 24 January 2026.
// 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_51_d_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_8_51_d_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
        Kf := Rationals();
    end if;
    return [Kf!elt[1] : elt in input];
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 := false)
    N := 8;
    order := 2;
    char_gens := [7, 5];
    char_values := [[-1], [-1]];
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    values := ConvertToHeckeField(char_values : pass_field := ISA(Type(Kf), Fld), 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 := 51;
    raw_aps := [[-33554432], [-1357246255682], [0], [0], [-216566032867586063515304626], [0], [11484333194425479818498080615682], [-101750491668668099890091086635874], [0], [0], [0], [0], [-30490943576570305325097526558911137086126], [-111409311987059022761513629469659116638386], [0], [0], [-130885310902277473186937781461662575640682002], [0], [-4619012503980257606885070447298279180095842818], [0], [-69994247752061998294033733980392006291536999182], [0], [115552090148733990836824537145935185395928788318], [-9615826823133397140723005163574167862048168091374], [-7412272971804212073669633541486217764746038123614], [0], [0], [590570644170817229534125284093262089138614570391182], [0], [-4146241684283323431413811242163515362590832664513182], [0], [-52224311430959463846290527511884212990611664372778498], [-483606924765086761564305220581369947103490375126270318], [679412250648653006787759085443760157366826741780890126], [0], [0], [0], [28713354497790622602276744495315672884786390578221896318], [0], [0], [-289876585163761677610299978801027060555549544228037355874], [0], [0], [368503993853788620498294920330888806976869980552743646818], [0], [0], [-25590352382702469490309628343752523247251328821542551790626], [0], [-1946932246965393714011842035265830611435691585005470570114], [0], [-303723789968344913460604070463269612351390429174495480967886], [0], [-569873429875329545583531428856272680024702677149581581400126], [1952852396189111857875776200148382413076735971096690528523374], [2422219556398215608493785878049920058560529438663333653248386], [0], [0], [0], [0], [32947146777360939982629227216160192554545451856360942401754002], [18658936049447065832160867015022072410406366449174831260942318], [0], [284592295951625149785526444215998036876614426593797195594409182], [0], [91883751215571357100894973278713182473709555824618460255168114], [0], [998951938310037099814812274262676443649394266889765197072855374], [-2350494184747571039294216501912054963549889208165460242581316318], [1492434225450434686900605342577251093476923362691660166463819182], [0], [6191075176019645690870729405769946706925062899793426028545426114], [0], [0], [0], [-639438835098856925220505315841678026168076792321503489654617874], [0], [0], [0], [-78808092140473951207128316164512262744722932863965719248022384126], [348283732639831863688809214635852570925290754846884998843194296626], [515313194164528885145514604353893296216725963014483399184690632126], [0], [0], [-896147152917267641293440836547356871194999376054964168936294421182], [0], [-2821487470573307792710361471966921960549899058056448192873430873682], [3710638146212272245918503531155129498354409336183753341429256886626], [-1875473952579658956039124997347135473236139087103700463632449150318], [0], [0], [-8538778813495807676178151231681633186327398733440817678215849142114], [0], [0], [-32624822399906125015071022689865103248830391818889910931387063640498], [55219199598123948067898070999650490475422854172969699230680048899998], [0], [0], [-158894212073853763307090106878680177420074221689137629168506396630126], [-60071932834536503012527975605720978670045835483521451726940989925682], [0], [-537409105569562896745978290673767424420940402563091521408708003658818], [0], [1091908802241819505913800960525167377524955733079143784710037576155614], [1375491975990818555131081302497683586885219937339422893057498105680626], [-575452027527007831069638487258012369118543262114683626104619223356498], [92694474561878284975165300164315854667744031852474160808701051335682], [-3278868765798451302341754570240845007171103731264293274047560155392818], [-4227215850421942884345148648017990401520818912778228148430521893977182], [0], [2269859595994676571343149180158667648632028584739276239384034337657874], [0], [0], [-6158963203011122275507826281823403944579686882954787299544487856049614], [8773581681695034369553062670236450596381512447091491692385766341065998], [0], [-6229178809721402021831031848227543987427162620618905760498540900307998], [-16803875065087066659760773897157827917649752882226104793405294311168386], [0], [0], [-35007615112131702089824725386022324795168018295675778098143448377219874], [0], [96617222290332498651719717021463692521154884053560978218826668062350114], [0], [129804831378610132001223961358174918052603088588076748012653307835994318], [192200541329691804381843977805989528983163980201463758928137541078313374], [0], [0], [0], [0], [0], [740853921955442727491367880773649919529229598422537494608968184276751998], [0], [0], [0], [-1343800110733495612994889737068556393201451320453494943050571003489050126], [-73203267491325705209395292351824393187058178209026818587874482092921374], [0], [-81366592147787922813587609702432835426408167693067384798801707378398114], [0], [-5402865588532647449602822267290288734635464524007134791871195033474019502], [-4066427001927341170761487279239512261147906055070792084483242944459824498], [0], [0], [4998129216031416298782377409690498260609554395595155601089011665909947182], [0], [0], [0], [23151804364143701791853370436269436819487715997237425522329776165947685682], [24923658953423153030403445969992797121042171500141960252820272000091326126], [0], [0], [80345730970761791350274168075584859278610966929175020259289028013569884002], [9976010984381159351563559604514852734309880590833876006596880143801700318], [0], [81359394039293996531909092340521925802000228905609572743348847711349215886], [0], [0], [169244527513546825813194480050573355336889485558027098123557473674847806498], [154891851955837068967281817969334015288877124777249630019087984288064277682], [0], [-485813063181364789488526578995204627221516427148544799341268049788639566114], [-574613679992019075950006399331774865640395717180787040963530759637826439182], [0], [515700480145028297780597306998599727195461187254828874227461162023117359374], [-104853143233570178075772841018089121230859321317233140092543510353054152318], [0], [0], [0]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_8_d_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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