
// Make newform 147.4.e.n in Magma, downloaded from the LMFDB on 18 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_147_e();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_147_e_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_147_4_e_n();".
// 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_147_4_e_n();".
// 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 := [36, -144, 582, 12, 25, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [-3600, 144, -582, 625, -25, 1], [234060, -3600, 14550, -1219, 625, -25], [150, 57618, 1825, 2475, -99, 100], [231696, -936438, -14212, -40225, 1609, -1601]];
    Rf_basisdens := [1, 1, 14406, 14406, 14406, 14406];
    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_147_e();"
function MakeCharacter_147_e()
    N := 147;
    order := 3;
    char_gens := [50, 52];
    v := [3, 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_147_e_Hecke();"
function MakeCharacter_147_e_Hecke(Kf)
    N := 147;
    order := 3;
    char_gens := [50, 52];
    char_values := [[1, 0, 0, 0, 0, 0], [0, 0, 0, 0, -1, 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 := 4;
    raw_aps := [[0, -1, 0, 0, 0, 0], [-3, 0, 0, 0, 3, 0], [0, -1, 0, -1, 4, 1], [0, 0, 0, 0, 0, 0], [-12, -1, -1, 0, 12, -3], [-19, 0, 5, -1, 0, 0], [16, 0, 0, 0, -16, -4], [0, -7, 0, 1, -65, -1], [0, 24, 0, -4, -80, 4], [26, 0, 25, -5, 0, 0], [-39, -22, -22, 0, 39, 2], [0, -19, 0, 1, -81, -1], [-82, 0, -2, -14, 0, 0], [143, 0, 69, 3, 0, 0], [0, -72, 0, 28, -46, -28], [-154, -69, -69, 0, 154, -11], [358, -69, -69, 0, -358, 29], [0, -100, 0, -20, 10, 20], [215, 17, 17, 0, -215, 47], [66, 0, -120, -12, 0, 0], [363, 101, 101, 0, -363, 23], [0, 36, 0, 48, -299, -48], [-156, 0, 51, -27, 0, 0], [0, 170, 0, -22, 532, 22], [-24, 0, -53, 49, 0, 0], [794, 20, 20, 0, -794, -68], [0, -51, 0, 45, -865, -45], [0, -23, 0, 1, -862, -1], [-519, 331, 331, 0, 519, -47], [686, 0, -26, 22, 0, 0], [573, 0, 80, -4, 0, 0], [0, 311, 0, -61, -944, 61], [-1000, 42, 42, 0, 1000, 94], [-39, 0, -353, -143, 0, 0], [0, 6, 0, 14, -1736, -14], [334, 129, 129, 0, -334, -117], [-1562, -158, -158, 0, 1562, 166], [0, -596, 0, 20, 980, -20], [142, 0, 404, 176, 0, 0], [0, 406, 0, 162, -828, -162], [2890, -26, -26, 0, -2890, 86], [1265, 0, 317, -97, 0, 0], [0, 646, 0, -62, 458, 62], [-1703, -18, -18, 0, 1703, 66], [-364, 0, 310, -50, 0, 0], [-192, 236, 236, 0, 192, -52], [-1040, 0, 874, -146, 0, 0], [-358, 0, 491, 41, 0, 0], [2884, -369, -369, 0, -2884, -43], [0, -87, 0, 189, 2375, -189], [0, -270, 0, 14, -1298, -14], [-3558, 0, 186, -162, 0, 0], [-2860, -15, -15, 0, 2860, -21], [-3458, 0, -511, 191, 0, 0], [0, -260, 0, -120, 2706, 120], [3960, 122, 122, 0, -3960, -186], [-2360, -333, -333, 0, 2360, -31], [0, -403, 0, 241, -1574, -241], [-3727, -1291, -1291, 0, 3727, -241], [-1640, 0, -262, 266, 0, 0], [-233, -395, -395, 0, 233, -101], [-310, 0, 667, -479, 0, 0], [-3313, 0, 275, -163, 0, 0], [1462, -354, -354, 0, -1462, -22], [0, 654, 0, -618, 995, 618], [0, 21, 0, -175, -3254, 175], [0, 1449, 0, -63, -2393, 63], [3037, 0, 52, 52, 0, 0], [2296, -20, -20, 0, -2296, -136], [4358, 0, 416, -40, 0, 0], [2166, 2302, 2302, 0, -2166, 342], [0, -814, 0, 162, 4080, -162], [-4089, -886, -886, 0, 4089, 290], [0, -63, 0, 165, -3989, -165], [-4323, 0, -1135, 167, 0, 0], [0, 1626, 0, 118, -1960, -118], [-2026, 1824, 1824, 0, 2026, -572], [0, 1363, 0, 527, 4413, -527], [0, 372, 0, 440, 268, -440], [-751, -1830, -1830, 0, 751, -834], [-5538, 0, -90, -246, 0, 0], [4823, 0, -1671, -285, 0, 0], [-10, -150, -150, 0, 10, 826], [9311, 0, 377, 299, 0, 0], [0, 1837, 0, -271, -12438, 271], [0, -1281, 0, 335, -3926, -335], [-2286, 0, -2682, -666, 0, 0], [0, -686, 0, -742, 2255, 742], [1184, 0, -2738, 874, 0, 0], [1273, 0, -1019, 979, 0, 0], [0, -510, 0, 46, 1490, -46], [-736, 1298, 1298, 0, 736, -86], [4769, -1534, -1534, 0, -4769, -358], [3646, 0, 479, 509, 0, 0], [0, -287, 0, -31, 617, 31], [750, 0, -750, -570, 0, 0], [0, -1655, 0, 609, -2532, -609], [472, -1086, -1086, 0, -472, 782], [0, -1537, 0, -497, -1511, 497], [0, 1629, 0, -39, -9059, 39], [-4268, 0, -812, -788, 0, 0], [-15588, 623, 623, 0, 15588, 861], [6972, -2147, -2147, 0, -6972, 291], [0, 2734, 0, -386, 1286, 386], [97, -789, -789, 0, -97, -411], [7879, -464, -464, 0, -7879, 400], [2362, 0, -577, 533, 0, 0], [0, -558, 0, -446, -12418, 446], [4088, -2442, -2442, 0, -4088, 1186], [-159, 0, -2060, -1220, 0, 0], [0, -1182, 0, 702, 3527, -702], [-5086, -646, -646, 0, 5086, 182], [-198, 0, 984, 1032, 0, 0], [-6887, -2729, -2729, 0, 6887, -359], [-490, 0, 2529, 1635, 0, 0], [9380, -3282, -3282, 0, -9380, -314], [1489, 0, 891, 597, 0, 0], [-142, 284, 284, 0, 142, -1124], [0, -5331, 0, -895, -4112, 895], [8028, 0, -1236, -1680, 0, 0], [11665, 3247, 3247, 0, -11665, 925], [-9869, 0, -146, -398, 0, 0], [0, 3225, 0, -803, -14074, 803], [12278, 1359, 1359, 0, -12278, -239], [0, -5457, 0, -1161, -4339, 1161], [-11202, 0, 2013, 771, 0, 0], [0, -568, 0, 1624, -1974, -1624], [0, -648, 0, -896, 14582, 896], [-1847, 0, -2388, 2088, 0, 0], [0, -4877, 0, -97, -2289, 97], [-1515, -437, -437, 0, 1515, 2461], [15282, 0, -384, 384, 0, 0], [0, -2336, 0, -1180, 11567, 1180], [4298, 0, -684, -84, 0, 0], [0, 5292, 0, 232, -12280, -232], [4861, 0, 3714, 222, 0, 0], [-25618, 2576, 2576, 0, 25618, 88], [-6380, 1594, 1594, 0, 6380, 2662], [-19322, 0, -5899, -853, 0, 0], [8822, 2358, 2358, 0, -8822, -1274], [-4604, 0, -3138, -798, 0, 0], [0, 1775, 0, -1569, -1500, 1569], [-9288, 3472, 3472, 0, 9288, -800], [9360, 0, -3807, 639, 0, 0], [-11557, -3477, -3477, 0, 11557, -783], [-3788, 0, -4444, -868, 0, 0], [-12125, 0, 2997, 1431, 0, 0], [-16236, 3694, 3694, 0, 16236, -966], [0, 1662, 0, -1362, 16724, 1362], [0, -924, 0, -1564, 7750, 1564], [0, -50, 0, -1618, -8470, 1618], [-5076, 0, -2610, -2250, 0, 0], [12197, 0, 2673, 1143, 0, 0], [0, -1538, 0, -138, 35826, 138], [-27605, 1167, 1167, 0, 27605, 1569], [11868, 0, -5202, -930, 0, 0], [0, -2403, 0, 549, -14561, -549], [0, -6020, 0, -864, -16074, 864], [20865, 0, -4436, 4, 0, 0], [-9562, -7537, -7537, 0, 9562, -1535], [0, 6482, 0, 906, 24438, -906], [-8672, 0, 3830, -2650, 0, 0], [-10745, 0, -6872, 1468, 0, 0], [0, 6759, 0, 31, 11594, -31], [8522, -4860, -4860, 0, -8522, -2132], [30532, 8208, 8208, 0, -30532, 884], [10279, -7254, -7254, 0, -10279, -774], [2773, 715, 715, 0, -2773, -1487]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_147_e_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_147_4_e_n();".
// 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_147_4_e_n(:prec:=6)
    chi := MakeCharacter_147_e();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 4));
    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_147_4_e_n();".
// 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_147_4_e_n( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_147_e();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![36, 144, 582, -12, 25, 1, 1]>,<5,R![1527696, -237312, 50460, -360, 313, -11, 1]>],Snew);
    return Vf;
end function;