
// Make newform 121.4.a.g in Magma, downloaded from the LMFDB on 30 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_121_a();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_121_4_a_g();".
// 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_121_4_a_g();".
// 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 := [64, 0, -21, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [8, -13, 0, 1], [-8, 29, 0, -1], [-10, 1, 1, 0]];
    Rf_basisdens := [1, 16, 16, 2];
    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_121_a();"
function MakeCharacter_121_a()
    N := 121;
    order := 1;
    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;

function MakeCharacter_121_a_Hecke(Kf)
    return MakeCharacter_121_a();
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 := [[1, 1, 1, 0], [2, 0, 1, 0], [-3, 4, 2, -3], [11, -3, 5, -3], [0, 0, 0, 0], [-1, 14, -4, -7], [63, -16, -7, -2], [19, 51, 6, -12], [-4, -16, -26, -10], [93, -19, 1, 31], [-45, 48, -40, 41], [19, 43, 17, -35], [26, -22, -15, 62], [-177, 199, -8, -31], [-241, 89, 37, -9], [95, 238, 2, -41], [-31, 137, 2, 32], [-105, 42, -42, 147], [204, -246, 109, -63], [243, -330, -120, 77], [136, -436, -51, -44], [143, 68, -128, 13], [518, -75, 14, -208], [281, 403, 32, 25], [-594, 421, 144, 50], [777, -60, 126, -67], [813, -69, 165, 71], [534, 152, -219, -52], [306, -372, -60, 180], [887, -819, 272, -76], [493, -732, 100, 51], [712, -162, -365, 83], [1094, -763, 264, -162], [129, 231, 47, -63], [-1161, 1758, 24, -139], [603, -291, 421, 107], [-639, -63, -309, 105], [605, -1284, -439, -60], [1141, -1810, -196, 591], [71, -1805, 235, -237], [-269, 1283, -484, 498], [-1219, -980, -970, 273], [-925, -971, -473, 115], [-2495, 1200, 44, -45], [260, -1250, 694, -740], [-1938, -810, -626, 492], [-1320, 453, 730, -1186], [529, 507, 37, -823], [193, 3049, 856, -290], [385, -888, 210, 281], [-1104, 875, -644, -56], [4261, -1881, -323, 73], [-324, -3240, -1107, 351], [273, -2206, -686, 769], [144, -544, 1633, -516], [4230, -710, 708, 362], [-2949, 178, 216, -403], [507, 1173, -1395, 809], [-2925, 78, -76, 1001], [-2836, 2443, -704, -188], [3343, -1183, 121, -665], [527, -2653, -993, 483], [-3141, 4263, 260, 441], [-3363, 4399, -299, -123], [967, -1296, -367, 1742], [-1081, 2426, 912, -1143], [-3761, -2221, -228, -647], [-6177, -1911, -428, 328], [11, -2824, 2151, -492], [573, -1515, 731, 1509], [3696, -3452, 875, 1049], [7083, 625, 1295, -1189], [6129, -6837, -75, 1143], [168, 2142, -1296, 1358], [1422, -1179, 1590, 304], [4629, 38, 1954, 241], [-3403, 8877, -805, 385], [1578, 2340, 1454, -1986], [-5394, 1721, -292, 670], [3413, -1508, -1776, -1137], [7177, -7835, 904, 775], [4287, -6573, 247, 307], [549, 4634, -2182, 1049], [-3921, 705, -186, -1318], [10002, -2874, 794, -732], [-2610, 3096, -2943, 472], [151, -1556, -1387, 2454], [5210, -2743, -1192, 2002], [1938, -3148, 1578, -950], [-244, 2600, 452, -2852], [-8797, 5806, -2414, -1313], [11767, -1138, 1610, 339], [-855, -7745, -431, 1769], [7608, -8018, -5, 1446], [2410, 2580, -545, 1860], [2085, -4061, -1803, 1917], [3783, 6779, 4597, -3063], [3139, -459, -422, -2678], [-3993, -4452, -4009, 1092], [3303, -7206, -3668, 997], [-11329, 5987, 2612, 1850], [-2255, 3473, 4735, 569], [-3444, 7549, -994, 1522], [12691, -8947, 1854, 1770], [-9516, -120, 300, -856], [14419, -1636, -1145, 688], [3585, 3649, -1452, 1094], [-3168, 7348, 4807, -1815], [-5663, -3972, 592, 2803], [-9516, 8424, -2203, 3244], [5317, -8890, 5140, -413], [-1353, -3065, 3121, -3043], [452, 672, 3215, -3331], [-1385, 10319, -1382, -944], [-9211, 1683, 2605, -3113], [6806, 1886, -1315, 2034], [-7940, 1011, -2906, 3342], [715, -7532, -5708, 2569], [1999, 659, -1611, 581], [-948, -13594, -3415, 3997], [-12314, 4792, 164, 4568], [-11877, 1836, -335, 150], [11257, -2036, 984, 1359], [4520, -5860, -2664, -940], [-239, -8712, 7087, -1474], [4211, -5109, -3781, 371], [-6423, 16280, 1244, -3025], [-13767, 6195, 2787, 2765], [-2174, 20106, -2844, 2130], [2137, 5109, -2743, 2015], [-12483, 17028, 2869, -156], [-7071, 25400, 1606, -2179], [11013, -8789, 243, 275], [-11875, 5212, -1510, 425], [10923, -416, -1899, 2510], [-5526, -6420, -6368, 272], [-14031, 16761, -5871, 731], [3195, -14412, 5381, -3450], [1485, -4828, -1998, 5161], [-8937, 4276, -9263, 3918], [-27566, 12940, -707, -2152], [2535, 8583, -6423, -1399], [5855, 16060, -3418, 1067], [-10667, 8304, -599, -2644], [29719, -13641, -1545, -2301], [3861, -20073, 975, -2097], [-17993, -3718, 1878, -3809], [2183, 12953, -4932, -1341], [19680, -15542, -2879, 5381], [22447, -28474, -2536, -859], [15325, 585, 2675, 1265], [-15851, -3001, -9784, 2193], [-12816, -4782, -2223, 2162], [13403, 6801, 2729, -1795], [-18349, 948, 293, -3846], [3037, 11090, -4072, -1965], [8939, 7014, 5474, 2563], [15879, -12908, 4793, -6874], [22071, 6520, -693, 2544], [27145, -21664, -1866, -5095], [9228, -13186, -3731, -467], [16766, 3922, 10977, -986], [21122, -2598, 170, 964], [1863, -8615, -2271, 3131], [14677, 616, 3468, -5181], [-20373, -11399, -1727, -479], [30364, 768, -1766, -730], [4643, 12063, -7951, -1391]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_121_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_121_4_a_g();".
// 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_121_4_a_g(:prec:=4)
    chi := MakeCharacter_121_a();
    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_121_4_a_g();".
// 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_121_4_a_g( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_121_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![44, 38, -15, -4, 1]>],Snew);
    return Vf;
end function;