
// Make newform 29.4.a.b in Magma, downloaded from the LMFDB on 17 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_29_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_29_4_a_b();".
// 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_29_4_a_b();".
// 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 := [-8, 20, 18, -14, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0, 0], [-2, -8, 1, 1, 0], [2, 12, -1, -1, 0], [-6, 0, 1, 0, 0], [14, 6, -13, 0, 1]];
    Rf_basisdens := [1, 2, 2, 1, 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_29_a();"
function MakeCharacter_29_a()
    N := 29;
    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_29_a_Hecke(Kf)
    return MakeCharacter_29_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 := [[0, -1, 0, 0, 0], [1, -1, 0, -1, -1], [3, 1, -1, -1, 2], [8, 2, -2, 0, -2], [3, 7, 10, 5, 9], [5, -3, -9, 5, -6], [10, 0, 10, 4, 0], [44, 8, 0, -2, 4], [46, 0, -2, 14, 24], [-29, 0, 0, 0, 0], [93, -19, -14, 7, 5], [48, 22, 30, -22, -28], [-216, 18, 16, 22, 44], [-49, -29, 22, 25, -11], [45, 75, -16, -41, -7], [-109, 75, 17, 23, 10], [90, 52, -6, 30, -16], [114, -20, 66, 60, 12], [280, -88, -140, -44, 0], [-122, -58, -96, -122, 6], [-384, -106, -66, -38, -32], [27, -139, -140, -63, -177], [146, -96, -42, 14, 60], [196, 66, 100, 10, 152], [296, 34, 48, 78, -32], [-228, -126, 58, 30, -40], [70, 314, 132, 50, 2], [492, 158, -38, 80, 2], [-101, -35, -237, 71, 22], [-62, -220, -256, -184, -340], [-616, 48, 92, 242, -108], [468, -252, -32, -262, -220], [-124, 62, 394, -122, 64], [1090, 60, -50, -74, -88], [225, 121, 51, -111, -210], [-392, -462, -126, 180, 166], [-780, 254, 48, -222, -244], [-389, -203, 480, -147, -39], [-1262, -290, 96, -174, 254], [662, -580, -664, -100, -128], [546, 318, -32, 302, 214], [1233, 43, 305, 481, 46], [-1368, 128, -104, -414, 48], [-720, 710, -28, 38, 160], [-654, -148, -316, -436, -456], [1096, 650, 578, 88, -158], [1039, -303, -172, -295, 161], [486, -690, -516, -662, -426], [-706, -954, 32, 86, -322], [1540, 2, -460, -550, 276], [-85, 63, -133, 291, 238], [830, -256, 498, -666, 24], [813, -183, -39, 49, 862], [-539, -289, -88, -149, -769], [2713, -161, 707, 405, -34], [-143, -359, -898, 75, -59], [166, 356, -482, -40, -516], [791, -273, 594, 453, -497], [-1058, 268, -124, 4, 824], [875, -37, 183, 667, 562], [2294, 444, -14, 654, 1424], [2450, -1404, -164, -400, 84], [-1485, 1683, -230, 541, 409], [-1464, 896, 88, -110, -768], [-2587, -561, 415, 177, 418], [-4302, 96, 198, -372, 408], [3247, 453, 0, 161, 341], [-7078, 364, -82, 460, -8], [-2582, 110, 980, 494, -774], [1211, -69, -79, -601, -778], [2542, 1776, 628, 768, 1692], [-369, -543, -1812, -59, -89], [-716, 656, 956, -106, 1128], [-3963, -365, -1451, -67, -182], [3240, 484, 1728, 1474, 1152], [-4268, -282, 538, -976, -1166], [1652, -562, 246, -1050, -664], [-2747, 223, -1663, 61, -530], [2591, 1699, -1485, 751, -278], [2366, 260, 1152, -28, 804], [7506, -910, -476, 6, 470], [-6510, -460, 662, 284, -1048], [1742, -412, -982, 302, -292], [-2860, -1678, -750, -322, -616], [-2142, -396, 2390, 14, 696], [4676, 596, 692, -1710, -704], [2518, -2036, -484, -868, 224], [-6914, -1264, 20, -136, -1020], [2774, 1464, -936, -60, 1740], [-2550, -672, -346, -2, -2356], [5359, 1379, 1214, 57, -795], [-1637, 1247, 1874, 721, 411], [-28, 1278, -1114, 956, -206], [-6787, -119, -342, 443, 503], [-1594, -1584, -1546, -2514, -576], [587, 639, -1702, 2369, 115], [1095, -2069, 629, 635, 62], [-2925, 2201, 2821, 1051, 350], [-1676, 4060, 1984, 788, 3112], [-2672, 1106, -302, -1542, -2876], [-1404, 42, -2838, -1936, -10], [-710, -1412, -1412, 1012, -28], [-11501, 441, -488, 813, 873], [4678, 204, 1756, 836, -388], [8464, -780, 2352, 1400, 984], [-3918, -1120, 502, -2708, -756], [2046, -1756, 422, -1310, -1164], [-1433, 201, 2213, 1719, 2310], [-5797, 333, 1304, -695, 1999], [10164, -1446, -1100, -310, -1636], [-8405, -2377, 794, 961, -2141], [-4669, -1915, 1727, 655, -1850], [8908, -3530, -2846, -578, 104], [9923, -3067, 20, -875, 833], [2794, 2766, 2744, 162, -454], [6538, -1368, -1778, -1004, -2580], [10908, -118, -178, -588, -2098], [626, 2912, -522, 1414, 672], [9860, 1630, -1996, 706, -212], [-10019, -889, -2052, 2675, 1439], [-2054, -1656, 1248, -1640, 1956], [-9891, 2069, 3177, 449, 3826], [850, 484, 2840, 1816, -312], [896, -3260, 112, -976, 2060], [2928, 604, -1044, -264, -4508], [11101, -2359, -1317, -555, 1662], [-979, -2935, -2293, -1587, -5510], [15974, -1682, -1104, -478, -1566], [3736, -1168, 416, 3242, 5512], [304, -554, 194, -862, 640], [-10267, 7227, -488, 1235, 1523], [-15944, -2396, 1124, -1466, -1900], [10812, -8, 3444, 402, 1712], [-10546, 1944, -938, -2176, -200], [-4966, 340, 1704, 3588, 252], [-1506, 5280, -2622, 2632, 1344], [-10460, -3830, -992, 658, -1356], [-1014, -710, 1064, 4798, -674], [14378, -1364, 450, -2220, 956], [-1180, -3166, -5378, -962, -1036], [7476, 4150, 2110, -1956, 1526], [-11315, 5069, 7659, 2109, 734], [10816, 312, -1012, -598, -1908], [-2009, -195, -800, -1215, -2023], [-2786, -5588, -5590, -3456, -2136], [5805, -153, -2448, 1471, 3405], [-3506, -4108, -2628, -5596, -6768], [18205, -1, -2873, 249, -1074], [389, -1811, -1098, -5893, -5065], [17158, 2342, 2780, 2150, -2662], [-4621, 8467, 3745, 1599, 3842], [-12338, 1308, -2692, -1772, -4828], [-884, -726, -1730, 3076, 5450], [14549, -2315, 78, 383, 2397], [3212, 988, 716, 1682, -2928], [8063, 2135, -2670, 4501, -433], [12846, 1782, -312, -430, 690], [-11014, 3084, 2468, 1380, 2168], [1202, 5156, 308, 3692, 1588], [-22037, -3483, -2973, -5801, -8418], [1215, 6079, 6034, 3745, 5041], [15863, -921, 87, -5561, -2346], [11133, -4085, -2400, -2449, 1025], [3564, -5548, 316, -522, -3360], [-12123, 6031, -925, -943, 1042], [-13415, 1307, 148, -4165, 2293], [14342, -2138, 4828, 1910, 2566], [-4472, -3974, 5278, 1026, -856]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_29_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_29_4_a_b();".
// 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_29_4_a_b(:prec:=5)
    chi := MakeCharacter_29_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_29_4_a_b();".
// 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_29_4_a_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_29_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![-256, 192, 28, -33, 0, 1]>],Snew);
    return Vf;
end function;