
// Make newform 25.12.b.c in Magma, downloaded from the LMFDB on 25 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_12_b_c();".
// 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_12_b_c();".
// 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 := [1444, 0, -75, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [0, -185, 0, 5], [0, 1130, 0, -10], [-150, 0, 4, 0]];
    Rf_basisdens := [1, 19, 19, 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 := 12;
    raw_aps := [[0, 1, 0, -3], [0, -11, 0, 16], [0, 0, 0, 0], [0, -2895, 0, -528], [-309088, 0, -2640, 0], [0, 170713, 0, -12864], [0, -65897, 0, -126528], [-2662660, 0, -27456, 0], [0, 2947197, 0, 33456], [-47070190, 0, -229824, 0], [122271732, 0, -720720, 0], [0, -1050161, 0, -19033728], [-372871658, 0, -2265120, 0], [0, 31497505, 0, -13909104], [0, 70103077, 0, 20505072], [0, 56916029, 0, -186753984], [-3658757780, 0, -17581728, 0], [-758212838, 0, -5356800, 0], [0, -786714507, 0, 91691472], [16469235772, 0, -5480400, 0], [0, -1499142443, 0, 339617856], [1651411560, 0, 57563616, 0], [0, 664955121, 0, -1100818224], [6337385430, 0, 145528128, 0], [0, 154035187, 0, -4545870528], [43118460702, 0, -311052480, 0], [0, -487275991, 0, 3654504816], [0, -14827160775, 0, 183016272], [8108731270, 0, 1192961472, 0], [0, -22922695447, 0, 257790336], [0, 15286249241, 0, 1101738672], [-431249652768, 0, -544843440, 0], [0, 3083764899, 0, -1305424128], [21666125980, 0, -1992763872, 0], [-924273719650, 0, -529450560, 0], [868794124252, 0, -1535996880, 0], [0, -79544685245, 0, 7245651072], [0, 77903859113, 0, -19604361264], [0, 163375340793, 0, -56160730128], [0, 74903599317, 0, 42989091456], [142249751860, 0, -7211989344, 0], [-2024990248018, 0, -8688374400, 0], [-3737955510308, 0, 2856221520, 0], [0, 346554784745, 0, 12549343296], [0, 230852584647, 0, -51990212928], [-2645579186200, 0, 6114193920, 0], [4053832556912, 0, 11845027920, 0], [0, 517645985117, 0, 66224908656], [0, -595455700639, 0, -83377644528], [-3605577513990, 0, -34410369024, 0], [0, -11355427839, 0, -425644309824], [1480945470280, 0, 13559119968, 0], [-5118617279858, 0, -31936317600, 0], [8499532462752, 0, -13826538000, 0], [0, 603108841095, 0, 246841414272], [0, -1146673925447, 0, 21306333936], [12876374355190, 0, -102693918336, 0], [1058656645372, 0, 50494134480, 0], [0, -2617546082829, 0, 165926143872], [27178583660982, 0, -81485101920, 0], [0, -929900492619, 0, -24859282224], [0, -2293579025055, 0, -1819739330304], [0, 354775335365, 0, 980033377872], [-42944218312188, 0, 125207089680, 0], [0, 2676225437513, 0, 2236486590336], [0, -5093261748037, 0, -1026952936128], [9539232167832, 0, 288773210640, 0], [0, -2824967499421, 0, 4366650982272], [0, -5567692886003, 0, -3437400137328], [30880259434850, 0, 276502819200, 0], [0, -4194402964971, 0, 590754873216], [19505926968120, 0, -721676836608, 0], [0, 14798865266493, 0, 1934584338672], [0, 630451613677, 0, 3144863619456], [-174951505636540, 0, -435189248064, 0], [0, 10708790000181, 0, -3333236023824], [217099562743230, 0, -297289721472, 0], [0, 681336459047, 0, -1818740680128], [-49300384860798, 0, 251100629760, 0], [315044811955570, 0, 496791288672, 0], [-371786087869660, 0, -582004151136, 0], [-395507050960478, 0, 19632444480, 0], [-99646338864468, 0, -933430819440, 0], [0, -43457340304739, 0, -5095099593024], [-32093314391320, 0, -381091214592, 0], [0, 15446065166985, 0, 7273236798096], [-278766447290150, 0, 1574526158880, 0], [0, -25932956366545, 0, 17919073462272], [-15644846809338, 0, -1460609234880, 0], [0, 20052086927073, 0, -7209626598864], [0, 61955768808053, 0, 4794202888272], [-308612783574840, 0, 2636822338656, 0], [0, 7280595456349, 0, 10362037588272], [300174480066592, 0, -2556764918160, 0], [-695424367984900, 0, 1670756507520, 0], [0, -54741199700951, 0, 21453730719216], [1096427185874770, 0, -1646825764608, 0], [208453684250122, 0, 1186339706880, 0], [0, -61574746350203, 0, 13284105957456], [1195136775326742, 0, 52259655360, 0], [0, 8492622588977, 0, 67623254925072], [0, -63379345894665, 0, -7353513529728], [0, -42591716721747, 0, -19053318234864], [207058311595890, 0, -3114922311456, 0], [-439184274871528, 0, 6662655156240, 0], [0, -46273042925009, 0, 88184700809472], [0, 100759877875449, 0, -76705722737328], [0, 100241288046085, 0, 87878966493696], [-1054192307502400, 0, -3304537408800, 0], [-1113459935079898, 0, 8020650151200, 0], [0, -281080682330515, 0, -4011006720528], [0, -287940321070127, 0, -43730777619264], [0, 50863099291263, 0, 38118424107072], [940111201298740, 0, 13554493442304, 0], [2729136620643532, 0, -2161198926480, 0], [-1495393658151858, 0, 3359521434720, 0], [0, 43844709626925, 0, 121759533975696], [0, 191455026223237, 0, 8564056458672], [0, 127792579962349, 0, 141693585738816], [-757551780381980, 0, -2277765062688, 0], [-2944713244585838, 0, 1991464279680, 0], [0, 57589655074197, 0, -58454490250944], [0, -44049784497369, 0, -59387484731328], [0, 25900665539121, 0, -106193148403824], [-4202996166280808, 0, -9780461449680, 0], [1096032534452602, 0, -7720138077120, 0], [-3424880494195030, 0, -2779113283008, 0], [1125729986746440, 0, -13242275359776, 0], [0, -99877760620919, 0, 227994083173872], [0, -608812672002499, 0, 87068161022976], [4530310531234580, 0, -26638199021472, 0], [0, -550893419509555, 0, -67029114759504], [402106419657652, 0, -2674773216720, 0], [0, 635866170504875, 0, -27876049360128], [6114091486087962, 0, 10083278641920, 0], [-3509957552231810, 0, -36043695174336, 0], [0, 834671326358817, 0, 11393989985856], [0, -166618898255071, 0, -416125359074928], [0, 1051553228939267, 0, -170266142104128], [-7928743033849930, 0, -11070860126208, 0], [13175778647288112, 0, -25965289948560, 0], [15276928441267122, 0, 20478807568320, 0], [0, -796269245198323, 0, 247167092270256], [0, 507012521404141, 0, 242113676963472], [3998578876123110, 0, 18119896920576, 0], [-9269145734351920, 0, 16135309797408, 0], [0, -351920502461031, 0, -37371894561984], [0, 1908489533526355, 0, 89329083199872], [-2183194093990180, 0, 27665601548832, 0], [0, -275851731167627, 0, 360481001786736], [0, -283226090633829, 0, 77300117398272], [-4892535016086418, 0, -31381134522720, 0], [0, 2049888435398621, 0, 53903671880976], [0, 1251680147027529, 0, 594093628319472], [0, -2810656217670315, 0, 160222348470672], [-14622622353980188, 0, -25145240757840, 0], [11794170715568240, 0, 3932522931744, 0], [-6785946428311990, 0, -80645386896864, 0], [0, 1709951657204199, 0, -145193604548928], [-3647871907970858, 0, 127037955720960, 0], [0, -2193547604489043, 0, -995518654567728], [0, -578459419991311, 0, 449881918626816], [0, -154804595020667, 0, -1213527007186128], [-7358602534659528, 0, -133735787174640, 0], [0, -1777756325064869, 0, 1378898547655872], [0, -1641645148423959, 0, -711503608366224], [-10650329825322508, 0, -126884371057680, 0], [0, -1165081739073213, 0, -1132952514356928]];
    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_12_b_c();".
// 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_12_b_c(:prec:=4)
    chi := MakeCharacter_25_b();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 12));
    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_12_b_c();".
// 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_12_b_c( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_25_b();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,12,sign)));
    Vf := Kernel([<2,R![28472896, 0, 11072, 0, 1]>],Snew);
    return Vf;
end function;