
// Make newform 25.8.a.e in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_25_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_25_8_a_e();".
// 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_25_8_a_e();".
// 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 := [-162, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rfbasis := [Kf.1^i : i in [0..Degree(Kf)-1]];
    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_25_a();"
function MakeCharacter_25_a()
    N := 25;
    order := 1;
    char_gens := [2];
    v := [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_25_a_Hecke(Kf)
    return MakeCharacter_25_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 := 8;
    raw_aps := [[8, -1], [21, -2], [0, 0], [-342, 84], [2047, 250], [8636, 408], [3083, 704], [9655, -1110], [13926, -6732], [21320, 13160], [-153138, 4500], [310558, -11256], [-55243, 2000], [473156, 20088], [887108, 13664], [43346, 44048], [990040, 87520], [403522, -225000], [164583, -73446], [-2389108, 50000], [-627499, -84432], [-3637230, 88260], [5990091, 69378], [-3216465, 442080], [-8498642, -122736], [-1223298, -537000], [-38204, -583152], [-989967, 744534], [119990, 108120], [-8936839, -686992], [344258, -1527876], [20668812, -2001000], [142683, 2884944], [-38676265, 195930], [26012600, -2336200], [19793302, 2245500], [-5214842, -47616], [19852111, -141942], [46794708, 789504], [-20905224, -6674832], [25390795, -421790], [-109680838, 690000], [53581682, -2324500], [-104322869, 7735488], [-53627142, 2554464], [-76255700, -2856600], [-3493303, 981750], [94538476, 7384968], [-43628492, -8805176], [123097620, 5632560], [-238502934, 2970528], [-255707240, -5696120], [-53344343, -23790000], [350377377, 1803750], [-272337342, -13954416], [135882886, -5148092], [137895280, -8747360], [-339458, 31924500], [-168907992, 27782424], [105614862, 21342000], [203141391, 7237578], [522744906, -26115912], [120804533, 7925934], [-10949478, -60685500], [-447141914, 38768208], [-8923292, 5688304], [-71749413, -36822750], [332183933, -61132656], [720075233, -12860986], [51616150, -22903800], [899997546, -7219152], [788222490, -50944380], [501888708, -20847096], [547431326, 20524368], [601181845, -59491890], [256781166, 89260428], [-396220890, -45892320], [-329991892, -43451136], [861892677, 90444000], [-203278435, -30713280], [-43880245, 212282690], [1115345092, -378000], [-2079344838, 39886500], [-72431509, -84826272], [1253186560, -115911720], [-517084869, -117899262], [-2619729575, 67002400], [-1088208217, -52898016], [1355476572, -131982000], [-1338108564, 21379608], [-1679047292, -4257896], [-86391630, 25116060], [-261260942, 216211644], [2307097532, 66491000], [-272901500, -212127000], [3425509396, -94575752], [-2524813910, 46049920], [1729272917, -181888000], [-1263889699, -346582482], [-2842378368, 156414000], [-149662267, -386561586], [991702908, -81549816], [-529337664, 80192208], [-3536597895, -303341760], [-1340896108, -91449000], [-1244534867, 512403024], [-620188317, 404646594], [1880421481, -32620112], [2531124650, -112528300], [-4636130173, -202740000], [5594261408, 42956784], [-3256218214, 270031008], [-3369628542, -284484096], [-4014639820, -449351160], [861344062, -438469500], [2445317082, -349422000], [998009556, 582461688], [7940846108, -254178136], [-5423577254, -287617352], [-3383954435, -371532530], [139302472, 191847000], [-8945100474, 23223168], [-6916492992, -95221776], [-293516259, -266253522], [13686303307, 13049250], [2517607652, -521263000], [-4718262860, -56437680], [-8276116170, 77712540], [12507218008, 276700824], [-5769227684, 934293528], [-9254085740, 664865880], [7355775206, 978972788], [-334038248, 1084077000], [866297408, -1387258416], [-3642202203, 856278000], [-6922284595, 4748640], [-1392115824, -569552232], [-9066632692, 291582744], [4616181358, 1132737664], [11546088290, 634933520], [-3234789228, 409071000], [-7949345358, -1309542000], [18150100876, 40412568], [-4810951117, -180397726], [13566739020, 360050760], [24705478160, -35465920], [8300834046, 1800928848], [17099992283, -575185216], [-20042719385, 503909370], [13888481536, -188529992], [13522466508, 77688624], [-20331459938, 1123342000], [-23899325459, 326499678], [23659099308, -762496056], [-12294055092, 351921384], [-11210818028, -687131000], [5166987130, 1073912940], [-17230003330, 2187668960], [2861619933, -1282095456], [9320328932, 794159000], [-30228166392, -1465261536], [-25996532929, -487315552], [13552626208, -537826896], [-22264874433, 2286170250], [-27451007617, 237813824], [-28780738434, 625130028], [-33449508718, -446389500], [-5430521892, 2057432064]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_25_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_25_8_a_e();".
// 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_25_8_a_e(:prec:=2)
    chi := MakeCharacter_25_a();
    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_25_8_a_e();".
// 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_25_8_a_e( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_25_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,8,sign)));
    Vf := Kernel([<2,R![-106, -15, 1]>],Snew);
    return Vf;
end function;