
// Make newform 25.10.b.b in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_25_b();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_25_b_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_25_10_b_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_25_10_b_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 := [63504, 0, 505, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [0, -337, 0, -1], [0, -1265, 0, -5], [5050, 0, 20, 0]];
    Rf_basisdens := [1, 42, 126, 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_25_b();"
function MakeCharacter_25_b()
    N := 25;
    order := 2;
    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;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_25_b_Hecke();"
function MakeCharacter_25_b_Hecke(Kf)
    N := 25;
    order := 2;
    char_gens := [2];
    char_values := [[-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 := 10;
    raw_aps := [[0, -1, 1, 0], [0, -2, 14, 0], [0, 0, 0, 0], [0, 214, -192, 0], [11992, 0, 0, 190], [0, -1352, 6427, 0], [0, -12856, -14213, 0], [148260, 0, 0, 284], [0, 19398, -62160, 0], [1833490, 0, 0, 10696], [806572, 0, 0, 15470], [0, -205296, 1158745, 0], [-13478638, 0, 0, -15580], [0, 25798, 2631586, 0], [0, 523334, -3182276, 0], [0, 1137448, -2520481, 0], [27497780, 0, 0, 154472], [-137289858, 0, 0, -69200], [0, -2416706, 1224282, 0], [-3565468, 0, 0, -627850], [0, -8830952, 10458385, 0], [-3438760, 0, 0, -1877564], [0, -2748402, 71491638, 0], [-415044330, 0, 0, 1338168], [0, -2622216, -30608621, 0], [-976995498, 0, 0, -1020120], [0, -18863202, 44834504, 0], [0, -36853386, 34725318, 0], [-1350842270, 0, 0, 1834872], [0, 29533648, -18382843, 0], [0, 39729974, -18801004, 0], [1359826872, 0, 0, -2741310], [0, -77983296, 182481375, 0], [-1541880380, 0, 0, 318168], [520250650, 0, 0, -18309560], [4640560452, 0, 0, -3271970], [0, -114185136, 118007533, 0], [0, -276824202, 115536302, 0], [0, 132204894, -233907168, 0], [0, -405724752, 395552955, 0], [-6210451060, 0, 0, -803824], [5062684022, 0, 0, -16395600], [-7979350588, 0, 0, -31728070], [0, 879397848, 403430141, 0], [0, 708101784, 1256367609, 0], [-6746065800, 0, 0, 20361920], [12881245592, 0, 0, 34053930], [0, -311819202, -2430462220, 0], [0, 858809374, -2564501494, 0], [29628471290, 0, 0, -106351904], [0, 716232648, 4369793793, 0], [79707693320, 0, 0, 4719308], [-5730071238, 0, 0, -225605900], [5991679752, 0, 0, -38849250], [0, 463250064, -5174813997, 0], [0, -1524558202, -1871435768, 0], [-78646100590, 0, 0, -2380096], [-100741400268, 0, 0, -22271030], [0, 1152407824, 10543645761, 0], [-16830909678, 0, 0, 295737420], [0, -3087770602, 6148004058, 0], [0, 3545108448, -4415281209, 0], [0, -4926579586, -10468222462, 0], [94633517292, 0, 0, -11418030], [0, 1132190448, -15209370823, 0], [0, -176181656, 14780814317, 0], [302722753072, 0, 0, -331564390], [0, -4341842896, 13230453515, 0], [0, 536074934, -33042117266, 0], [-196401016350, 0, 0, 719044400], [0, -8515912752, -7437714531, 0], [100501085880, 0, 0, -655755408], [0, -6889607906, -5785589268, 0], [0, 3788740048, 13020552175, 0], [-111412986660, 0, 0, 1292505356], [0, -7399492002, -21578370492, 0], [15584297370, 0, 0, -15750432], [0, -8369505016, 62344223909, 0], [-288670199598, 0, 0, -23350560], [-40557647570, 0, 0, -2298573228], [592845389260, 0, 0, 365098504], [414305454582, 0, 0, -2101366280], [-347318902428, 0, 0, -34967310], [0, -10921440152, 97346008693, 0], [-690222193080, 0, 0, -1491729952], [0, -14304454002, -71914290054, 0], [-502371543850, 0, 0, 2835605180], [0, 24123517664, -62273994817, 0], [595121601342, 0, 0, 2999841480], [0, 27888077198, 37364499372, 0], [0, -2650742906, 123600958562, 0], [-12270738360, 0, 0, 80123076], [0, 51773943054, -50731282400, 0], [-585657925288, 0, 0, 541999310], [-1524252119100, 0, 0, -3570761380], [0, 29962963598, 45708360784, 0], [891598573730, 0, 0, -1386723808], [-1895557838518, 0, 0, -1832567680], [0, -34849266602, 67393514290, 0], [-49147358738, 0, 0, 3691157240], [0, 18914572334, 34104105674, 0], [0, 44259544464, -226564461627, 0], [0, -26145672402, -26083888218, 0], [1530438889710, 0, 0, -1574825916], [1805967445232, 0, 0, 1732808610], [0, -13098324576, 110538778771, 0], [0, 32968782654, 163390422150, 0], [0, -12015096352, -227441719979, 0], [1153367838400, 0, 0, -11881996100], [-3705529803598, 0, 0, 2076042300], [0, 12727695014, 183947887748, 0], [0, 99312185848, -53454066953, 0], [0, -132122030856, -195454912833, 0], [-1026816711140, 0, 0, 4756720644], [-923046624828, 0, 0, 18065477230], [-121540402038, 0, 0, 19206904980], [0, 114709210598, 261497798526, 0], [0, 49695568334, 383200908304, 0], [0, -71810009752, 162300924859, 0], [-1106186840020, 0, 0, 15212802512], [-3220493030058, 0, 0, 10912216720], [0, -137086434952, 476535054765, 0], [0, 3512367624, -938689831959, 0], [0, 182709810198, -511428131262, 0], [1976679522912, 0, 0, -11379832370], [-3402924345298, 0, 0, 9494351720], [-1323557560470, 0, 0, 2076031592], [7526269205160, 0, 0, -6333934836], [0, 186678243174, 562653342616, 0], [0, -21316169952, 222016285523, 0], [-10442753344980, 0, 0, -9995875432], [0, 144504428398, -532284098584, 0], [4263843944652, 0, 0, 15064134070], [0, 119857979264, -830428240207, 0], [2221219914042, 0, 0, -38188384320], [-2053143251090, 0, 0, -29832813096], [0, -244032904152, -70373760345, 0], [0, -320789049946, -930587469310, 0], [0, 42139092184, -790706612131, 0], [15680814897430, 0, 0, -24054694208], [9904451685592, 0, 0, -5452617490], [4097505101382, 0, 0, 56007507480], [0, -252497677002, 137674023200, 0], [0, -44252520826, -1071278749154, 0], [-6569380461310, 0, 0, 53791572496], [12834240453520, 0, 0, 35892371548], [0, -132888315352, 1675098665199, 0], [0, 330848230064, 1008599089783, 0], [14648799414180, 0, 0, -7383488368], [0, 323862118598, 480539691172, 0], [0, -229808996576, -270772900539, 0], [8628413327722, 0, 0, -47476325780], [0, 316772326398, -2228413785562, 0], [0, -550547810346, -78498188760, 0], [0, 288743952814, -163263316602, 0], [-8548555347908, 0, 0, -46350004610], [4256999817360, 0, 0, 25973070884], [-13103130515210, 0, 0, 16818752956], [0, 333640798504, 1783145075775, 0], [-31872115705138, 0, 0, -48601111360], [0, 751830431934, -2248161380286, 0], [0, -510480611552, -1014089255911, 0], [0, -897017819706, 948039713152, 0], [-8420057165568, 0, 0, 92215840290], [0, -1234956559576, 696819844891, 0], [0, 81345054198, 3528673572528, 0], [-24977396400388, 0, 0, -84633371370], [0, -723043205816, 195069957129, 0]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_25_b_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_25_10_b_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_25_10_b_b(:prec:=4)
    chi := MakeCharacter_25_b();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 10));
    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_10_b_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_25_10_b_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_25_b();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,10,sign)));
    Vf := Kernel([<2,R![968256, 0, 2068, 0, 1]>],Snew);
    return Vf;
end function;