
// Make newform 225.12.b.f in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_225_b();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_225_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_225_12_b_f();".
// 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_225_12_b_f();".
// 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, 3390, 0, -30], [-450, 0, 12, 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_225_b();"
function MakeCharacter_225_b()
    N := 225;
    order := 2;
    char_gens := [101, 127];
    v := [2, 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_225_b_Hecke();"
function MakeCharacter_225_b_Hecke(Kf)
    N := 225;
    order := 2;
    char_gens := [101, 127];
    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+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, -1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 2895, 0, 176], [309088, 0, 880, 0], [0, -170713, 0, 4288], [0, -65897, 0, -42176], [-2662660, 0, -9152, 0], [0, 2947197, 0, 11152], [47070190, 0, 76608, 0], [122271732, 0, -240240, 0], [0, 1050161, 0, 6344576], [372871658, 0, 755040, 0], [0, -31497505, 0, 4636368], [0, 70103077, 0, 6835024], [0, 56916029, 0, -62251328], [3658757780, 0, 5860576, 0], [-758212838, 0, -1785600, 0], [0, 786714507, 0, -30563824], [-16469235772, 0, 1826800, 0], [0, 1499142443, 0, -113205952], [1651411560, 0, 19187872, 0], [0, 664955121, 0, -366939408], [-6337385430, 0, -48509376, 0], [0, -154035187, 0, 1515290176], [-43118460702, 0, 103684160, 0], [0, 487275991, 0, -1218168272], [0, -14827160775, 0, 61005424], [8108731270, 0, 397653824, 0], [0, -22922695447, 0, 85930112], [0, -15286249241, 0, -367246224], [431249652768, 0, 181614480, 0], [0, 3083764899, 0, -435141376], [21666125980, 0, -664254624, 0], [924273719650, 0, 176483520, 0], [868794124252, 0, -511998960, 0], [0, 79544685245, 0, -2415217024], [0, -77903859113, 0, 6534787088], [0, 163375340793, 0, -18720243376], [0, 74903599317, 0, 14329697152], [-142249751860, 0, 2403996448, 0], [-2024990248018, 0, -2896124800, 0], [3737955510308, 0, -952073840, 0], [0, -346554784745, 0, -4183114432], [0, 230852584647, 0, -17330070976], [-2645579186200, 0, 2038064640, 0], [4053832556912, 0, 3948342640, 0], [0, -517645985117, 0, -22074969552], [0, -595455700639, 0, -27792548176], [-3605577513990, 0, -11470123008, 0], [0, -11355427839, 0, -141881436608], [-1480945470280, 0, -4519706656, 0], [-5118617279858, 0, -10645439200, 0], [-8499532462752, 0, 4608846000, 0], [0, 603108841095, 0, 82280471424], [0, -1146673925447, 0, 7102111312], [-12876374355190, 0, 34231306112, 0], [1058656645372, 0, 16831378160, 0], [0, 2617546082829, 0, -55308714624], [-27178583660982, 0, 27161700640, 0], [0, 929900492619, 0, 8286427408], [0, -2293579025055, 0, -606579776768], [0, -354775335365, 0, -326677792624], [42944218312188, 0, -41735696560, 0], [0, -2676225437513, 0, -745495530112], [0, -5093261748037, 0, -342317645376], [9539232167832, 0, 96257736880, 0], [0, 2824967499421, 0, -1455550327424], [0, -5567692886003, 0, -1145800045776], [30880259434850, 0, 92167606400, 0], [0, -4194402964971, 0, 196918291072], [-19505926968120, 0, 240558945536, 0], [0, -14798865266493, 0, -644861446224], [0, -630451613677, 0, -1048287873152], [-174951505636540, 0, -145063082688, 0], [0, 10708790000181, 0, -1111078674608], [-217099562743230, 0, 99096573824, 0], [0, -681336459047, 0, 606246893376], [49300384860798, 0, -83700209920, 0], [315044811955570, 0, 165597096224, 0], [371786087869660, 0, 194001383712, 0], [-395507050960478, 0, 6544148160, 0], [99646338864468, 0, 311143606480, 0], [0, 43457340304739, 0, 1698366531008], [-32093314391320, 0, -127030404864, 0], [0, 15446065166985, 0, 2424412266032], [278766447290150, 0, -524842052960, 0], [0, 25932956366545, 0, -5973024487424], [15644846809338, 0, 486869744960, 0], [0, -20052086927073, 0, 2403208866288], [0, 61955768808053, 0, 1598067629424], [308612783574840, 0, -878940779552, 0], [0, -7280595456349, 0, -3454012529424], [-300174480066592, 0, 852254972720, 0], [-695424367984900, 0, 556918835840, 0], [0, -54741199700951, 0, 7151243573072], [-1096427185874770, 0, 548941921536, 0], [-208453684250122, 0, -395446568960, 0], [0, 61574746350203, 0, -4428035319152], [1195136775326742, 0, 17419885120, 0], [0, -8492622588977, 0, -22541084975024], [0, -63379345894665, 0, -2451171176576], [0, -42591716721747, 0, -6351106078288], [-207058311595890, 0, 1038307437152, 0], [-439184274871528, 0, 2220885052080, 0], [0, 46273042925009, 0, -29394900269824], [0, 100759877875449, 0, -25568574245776], [0, 100241288046085, 0, 29292988831232], [1054192307502400, 0, 1101512469600, 0], [-1113459935079898, 0, 2673550050400, 0], [0, 281080682330515, 0, 1337002240176], [0, 287940321070127, 0, 14576925873088], [0, 50863099291263, 0, 12706141369024], [940111201298740, 0, 4518164480768, 0], [2729136620643532, 0, -720399642160, 0], [1495393658151858, 0, -1119840478240, 0], [0, -43844709626925, 0, -40586511325232], [0, 191455026223237, 0, 2854685486224], [0, 127792579962349, 0, 47231195246272], [757551780381980, 0, 759255020896, 0], [-2944713244585838, 0, 663821426560, 0], [0, -57589655074197, 0, 19484830083648], [0, -44049784497369, 0, -19795828243776], [0, 25900665539121, 0, -35397716134608], [-4202996166280808, 0, -3260153816560, 0], [-1096032534452602, 0, 2573379359040, 0], [-3424880494195030, 0, -926371094336, 0], [-1125729986746440, 0, 4414091786592, 0], [0, 99877760620919, 0, -75998027724624], [0, 608812672002499, 0, -29022720340992], [4530310531234580, 0, -8879399673824, 0], [0, -550893419509555, 0, -22343038253168], [402106419657652, 0, -891591072240, 0], [0, -635866170504875, 0, 9292016453376], [-6114091486087962, 0, -3361092880640, 0], [-3509957552231810, 0, -12014565058112, 0], [0, 834671326358817, 0, 3797996661952], [0, 166618898255071, 0, 138708453024976], [0, 1051553228939267, 0, -56755380701376], [7928743033849930, 0, 3690286708736, 0], [13175778647288112, 0, -8655096649520, 0], [-15276928441267122, 0, -6826269189440, 0], [0, 796269245198323, 0, -82389030756752], [0, 507012521404141, 0, 80704558987824], [3998578876123110, 0, 6039965640192, 0], [9269145734351920, 0, -5378436599136, 0], [0, 351920502461031, 0, 12457298187328], [0, 1908489533526355, 0, 29776361066624], [-2183194093990180, 0, 9221867182944, 0], [0, -275851731167627, 0, 120160333928912], [0, 283226090633829, 0, -25766705799424], [4892535016086418, 0, 10460378174240, 0], [0, -2049888435398621, 0, -17967890626992], [0, 1251680147027529, 0, 198031209439824], [0, 2810656217670315, 0, -53407449490224], [14622622353980188, 0, 8381746919280, 0], [11794170715568240, 0, 1310840977248, 0], [6785946428311990, 0, 26881795632288, 0], [0, -1709951657204199, 0, 48397868182976], [3647871907970858, 0, -42345985240320, 0], [0, -2193547604489043, 0, -331839551522576], [0, -578459419991311, 0, 149960639542272], [0, 154804595020667, 0, 404509002395376], [7358602534659528, 0, 44578595724880, 0], [0, -1777756325064869, 0, 459632849218624], [0, -1641645148423959, 0, -237167869455408], [-10650329825322508, 0, -42294790352560, 0], [0, 1165081739073213, 0, 377650838118976]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_225_b_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_225_12_b_f();".
// 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_225_12_b_f(:prec:=4)
    chi := MakeCharacter_225_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_225_12_b_f();".
// 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_225_12_b_f( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_225_b();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,12,sign)));
    Vf := Kernel([<2,R![28472896, 0, 11072, 0, 1]>,<11,R![-325428448256, -618176, 1]>],Snew);
    return Vf;
end function;