
// Make newform 144.11.g.e in Magma, downloaded from the LMFDB on 08 June 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_144_g();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_144_g_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_144_11_g_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_144_11_g_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 := [404496, 636, 637, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [403860, -1274, 1274, -2], [45816, 0, 0, 48], [1272, 5092, -4, 4]];
    Rf_basisdens := [1, 101283, 637, 53];
    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_144_g();"
function MakeCharacter_144_g()
    N := 144;
    order := 2;
    char_gens := [127, 37, 65];
    v := [1, 2, 2];
    // 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_144_g_Hecke();"
function MakeCharacter_144_g_Hecke(Kf)
    N := 144;
    order := 2;
    char_gens := [127, 37, 65];
    char_values := [[-1, 0, 0, 0], [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]];
    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 := 11;
    raw_aps := [[0, 0, 0, 0], [0, 0, 0, 0], [-750, 0, -1, 0], [0, 107, 0, -13], [0, -18537, 0, -82], [216034, 0, -294, 0], [13782, 0, -1766, 0], [0, 234907, 0, -646], [0, 81324, 0, -1926], [20197578, 0, 7297, 0], [0, 1119213, 0, -3581], [-53127910, 0, 17604, 0], [136113318, 0, 63270, 0], [0, 23366241, 0, 28406], [0, -36452562, 0, 25238], [222201018, 0, -366207, 0], [0, -9633603, 0, -323912], [-52083814, 0, -461112, 0], [0, -51170351, 0, -194808], [0, -81145176, 0, 1097858], [1220417362, 0, 1409784, 0], [0, -27637235, 0, 863351], [0, -52470543, 0, -1745378], [-5385095634, 0, -2291668, 0], [3741442114, 0, -7560444, 0], [-3031616070, 0, -11513679, 0], [0, -565097719, 0, 3508701], [0, -1789630755, 0, -2085004], [-17481327374, 0, -3322218, 0], [-14292276306, 0, 16004668, 0], [0, 2334186351, 0, -7436951], [0, -3134072289, 0, 19874512], [17845723158, 0, -18867022, 0], [0, -7655323657, 0, 17303600], [-64768127982, 0, -30746633, 0], [0, -483517889, 0, -51722133], [9452651882, 0, 105830148, 0], [0, -17688242869, 0, 31090958], [0, -22078171758, 0, -839288], [-211932432510, 0, 65929375, 0], [0, 22216349643, 0, 53287912], [206635415266, 0, -30349338, 0], [0, -12332933664, 0, 85478888], [23221174754, 0, 276453192, 0], [35865239754, 0, 49873045, 0], [0, 32214552221, 0, 27604897], [0, 19115204909, 0, 45456664], [0, 126321310179, 0, -85450115], [0, 38051141745, 0, 81436394], [-62692504430, 0, 276001242, 0], [796288121646, 0, 77855708, 0], [0, 2886618648, 0, 3537644], [277709586898, 0, -311654700, 0], [0, 168983008323, 0, -208405154], [519895796478, 0, 402444416, 0], [0, 162877127562, 0, 482565312], [-280172897238, 0, 412957817, 0], [0, -23425763177, 0, -300543363], [1392350515714, 0, 230827446, 0], [379467774174, 0, -1627289408, 0], [0, 119932711803, 0, -704006176], [-2773662946086, 0, -961086823, 0], [0, 22726117989, 0, 82087656], [0, 399720554130, 0, 421073204], [-357211263838, 0, 3683003544, 0], [-112160566758, 0, -217265683, 0], [0, 111182482331, 0, 1179816268], [-3689767343342, 0, -3234302664, 0], [0, -761112266949, 0, -1056234858], [-4850135209606, 0, 3151083336, 0], [2322151313166, 0, -4447178916, 0], [0, -872398001136, 0, 2290563394], [0, -877906282807, 0, -1867142973], [-5379583602166, 0, -5745198768, 0], [0, 533656610233, 0, -681696590], [0, -915259839624, 0, -2597268576], [-7061143307310, 0, 7959976815, 0], [-5701165995238, 0, 2983784304, 0], [-618584201562, 0, -3398615938, 0], [9042348134050, 0, 9236703852, 0], [0, -1151233413927, 0, 3425113874], [6329685956098, 0, -418273002, 0], [0, -1820327961798, 0, -998514390], [8689867902002, 0, -9522290328, 0], [0, 230607778149, 0, -1104013347], [0, 1096297861347, 0, -6785840154], [5117647779414, 0, 5610776514, 0], [3299731208866, 0, -19115464764, 0], [-22043395046718, 0, -11516087721, 0], [0, 3203469852431, 0, 5710395733], [0, 1507336241637, 0, 4573639490], [0, -70713986178, 0, 4232567050], [0, 2137630197467, 0, -1241728709], [0, 4921103797509, 0, 7516906820], [0, 1318746725829, 0, 11808742080], [0, -487178126436, 0, -18010959254], [-4169338123590, 0, 43001436597, 0], [39398756577318, 0, 1993016190, 0], [0, -188100588827, 0, -11183403534], [-817235897678, 0, -11686841154, 0], [0, 5999346147815, 0, 15344122770], [-27545137560942, 0, -33592085429, 0], [0, 6830455122513, 0, -26840200962], [30504964503558, 0, -3300373034, 0], [0, -11715413812457, 0, -716132372], [45239951136914, 0, -22795396008, 0], [0, 3703723354821, 0, -17388751204], [10804773451758, 0, -53655852868, 0], [0, 6642463505616, 0, 16349310966], [56731580773298, 0, 26909098608, 0], [0, 2830902996335, 0, 30741710753], [54352593372266, 0, -41135776056, 0], [24636055927326, 0, 46290117704, 0], [0, -11949041905649, 0, 42373971912], [0, -345090172745, 0, 59334974923], [-21706982467626, 0, 9043962074, 0], [0, 10016430630759, 0, -60849359334], [0, 1094565996888, 0, -20835058118], [-4986868152078, 0, -55815176109, 0], [0, -32516149533225, 0, 1450317404], [-93824800368838, 0, -81445727724, 0], [-78121524994510, 0, 14517047472, 0], [-87715531144350, 0, -39252729525, 0], [0, -12525997413021, 0, -32735575078], [0, 5550303581271, 0, 107098677022], [-94242290186118, 0, -29913659251, 0], [-44480297343182, 0, 25614285114, 0], [0, -10993128774018, 0, -47653680586], [0, -10535224733073, 0, -21320950005], [-157856190908126, 0, 51269869314, 0], [0, 35466654531069, 0, -23264125652], [0, 13952131022862, 0, -4028621412], [0, -39524757305027, 0, -29931880097], [53865472698802, 0, 76486819914, 0], [-243510571543530, 0, 69551341010, 0], [60798055447874, 0, 13655681952, 0], [56943720173226, 0, 60510141421, 0], [0, -12183507668201, 0, -55112900466], [215115835730034, 0, -213226355477, 0], [61151890529814, 0, -474694710910, 0], [0, 2851032203721, 0, -216378485482], [182130112998762, 0, -299604320779, 0], [0, 3808366790395, 0, 284138711495], [0, 4439700670761, 0, -160063235940], [-40546518116174, 0, -260754687642, 0], [0, 862669950012, 0, -2998318674], [-371891745301126, 0, -33074496468, 0], [592812854985030, 0, 29604242870, 0], [0, -45057399107647, 0, 33615640970], [0, -28208118219096, 0, 184598823928], [-318424849214470, 0, 408784660272, 0], [-22011339303810, 0, 15609722472, 0], [0, 103183652582975, 0, 34617435478], [0, 7437853917030, 0, 380532565136], [0, -53820292416803, 0, -182401802590], [0, -2146326691992, 0, -267515819260], [0, 87749725491603, 0, 70729168647], [315276784160358, 0, -844002693338, 0], [67094404391906, 0, -345706580592, 0], [-844651041491166, 0, -131808199121, 0], [0, 64825350685371, 0, 161421064200], [-1385654072026746, 0, 20365442126, 0], [0, -86153351433287, 0, -304505096379], [0, 41651204408403, 0, -211554959054], [-72034443972666, 0, -108758594682, 0], [0, -24310219901034, 0, -198589044584], [0, 31429573457033, 0, -139743959721], [-252548497141750, 0, -158750438496, 0]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_144_g_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_144_11_g_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_144_11_g_e(:prec:=4)
    chi := MakeCharacter_144_g();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 11));
    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_144_11_g_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_144_11_g_e( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_144_g();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,11,sign)));
    Vf := Kernel([<5,R![-903420, 1500, 1]>],Snew);
    return Vf;
end function;