
// Make newform 108.4.h.a in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_108_h();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_108_h_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_108_4_h_a();".
// 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_108_4_h_a();".
// 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 := [4096, 0, 704, 0, 96, 0, 11, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [128, -40, 28, -15, -1, -5, 1, 0], [-768, -160, -88, 0, -19, 0, -1, 0], [-2560, -704, 0, 16, 0, -17, 0, -3], [8704, -320, 1984, -240, 152, 25, 8, -5], [-5632, 3520, 128, 480, -136, 55, -24, 5], [5632, 3520, -128, 480, 136, 55, 24, 5]];
    Rf_basisdens := [1, 1, 320, 320, 5120, 5120, 5120, 5120];
    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_108_h();"
function MakeCharacter_108_h()
    N := 108;
    order := 6;
    char_gens := [55, 29];
    v := [3, 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_108_h_Hecke();"
function MakeCharacter_108_h_Hecke(Kf)
    N := 108;
    order := 6;
    char_gens := [55, 29];
    char_values := [[-1, 0, 0, 0, 0, 0, 0, 0], [0, 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 := 4;
    raw_aps := [[0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0], [-10, 1, 0, 1, -5, 0, 1, 0], [0, -3, 0, -5, 0, -7, 3, -2], [0, -1, 2, -10, 0, 1, 1, -9], [0, -1, 0, 1, -55, 0, -1, -2], [-30, -13, 0, 0, -60, 0, -13, -13], [0, 5, 30, 40, 0, 30, -5, 35], [0, 21, 5, 26, 0, 10, -21, 5], [53, 0, 0, 23, -53, 0, 0, -23], [0, -7, 43, -36, 0, 0, 7, -29], [-160, -2, 0, -4, 0, 0, -2, 2], [162, -50, 0, -50, 81, 0, -50, 0], [0, 51, 0, 52, 0, 53, -51, 1], [0, -87, 174, -77, 0, 87, 87, 10], [10, 74, 0, 0, 20, 0, 74, 74], [0, 70, 3, 73, 0, 6, -70, 3], [-41, -142, 0, -71, -41, 0, -142, -71], [0, 76, -101, 25, 0, 0, -76, -51], [0, -106, 26, -26, 0, -26, 106, 80], [620, 85, 0, 170, 0, 0, 85, -85], [0, -341, 0, -207, 0, -73, 341, 134], [0, 161, -322, 131, 0, -161, -161, -30], [-102, -46, 0, 0, -204, 0, -46, -46], [-5, 184, 0, 92, -5, 0, 184, 92], [255, 0, 0, -139, -255, 0, 0, 139], [0, 35, 85, -120, 0, 0, -35, -155], [0, -427, 164, -164, 0, -164, 427, 263], [-472, 172, 0, 344, 0, 0, 172, -172], [-970, 43, 0, 43, -485, 0, 43, 0], [0, -60, 246, 126, 0, 246, 60, 186], [0, 35, 367, 402, 0, 734, -35, 367], [-115, 0, 0, -124, 115, 0, 0, 124], [0, 406, -419, 13, 0, 0, -406, -393], [866, 217, 0, 217, 433, 0, 217, 0], [0, -89, 0, 267, 0, 623, 89, 356], [0, 53, 0, -53, -805, 0, 53, 106], [0, 526, -198, 854, 0, -198, -526, 328], [0, -167, 435, 268, 0, 870, 167, 435], [-85, 0, 0, 89, 85, 0, 0, -89], [0, 824, -364, 364, 0, 364, -824, -460], [-796, -192, 0, -384, 0, 0, -192, 192], [0, -339, 678, -515, 0, 339, 339, -176], [0, -310, 0, 310, 1265, 0, -310, -620], [-1620, -340, 0, 0, -3240, 0, -340, -340], [0, -1086, 1848, -324, 0, 1848, 1086, 762], [0, -117, 523, -406, 0, 0, 117, -289], [0, 293, 0, -7, 0, -307, -293, -300], [0, 151, -302, 714, 0, -151, -151, 563], [0, 119, 0, -119, -2137, 0, 119, 238], [-660, 485, 0, 0, -1320, 0, 485, 485], [0, -95, -855, -950, 0, -1710, 95, -855], [-1319, -424, 0, -212, -1319, 0, -424, -212], [0, 873, -1368, 1368, 0, 1368, -873, 495], [2390, 712, 0, 712, 1195, 0, 712, 0], [0, -217, 434, -1777, 0, 217, 217, -1560], [2682, -394, 0, 0, 5364, 0, -394, -394], [0, -380, -810, -1570, 0, -810, 380, -1190], [4405, 1054, 0, 527, 4405, 0, 1054, 527], [-3511, 0, 0, -655, 3511, 0, 0, 655], [0, 1509, -3395, 1886, 0, 0, -1509, 377], [-850, 505, 0, 505, -425, 0, 505, 0], [0, -609, -282, -1500, 0, -282, 609, -891], [0, -285, 293, 8, 0, 586, 285, 293], [1645, 1352, 0, 676, 1645, 0, 1352, 676], [605, 0, 0, -1327, -605, 0, 0, 1327], [0, 1199, 0, 533, 0, -133, -1199, -666], [0, 310, 0, -310, 1295, 0, 310, 620], [0, 604, -783, -179, 0, -1566, -604, -783], [1753, 958, 0, 479, 1753, 0, 958, 479], [-915, 0, 0, 1220, 915, 0, 0, -1220], [0, -562, 812, -812, 0, -812, 562, -250], [0, -3249, 0, -1823, 0, -397, 3249, 1426], [0, -557, 0, 557, 1565, 0, -557, -1114], [0, 1173, -624, 1722, 0, -624, -1173, 549], [0, -1723, -569, -2292, 0, -1138, 1723, -569], [4587, 0, 0, 1649, -4587, 0, 0, -1649], [6020, -98, 0, -196, 0, 0, -98, 98], [-910, 1000, 0, 1000, -455, 0, 1000, 0], [0, 26, 0, -26, -13849, 0, 26, 52], [0, 65, 1021, 1086, 0, 2042, -65, 1021], [-9653, -2146, 0, -1073, -9653, 0, -2146, -1073], [0, 2518, -308, 308, 0, 308, -2518, -2210], [8240, -803, 0, -1606, 0, 0, -803, 803], [0, 3051, 0, 2467, 0, 1883, -3051, -584], [0, -1059, 2118, -266, 0, 1059, 1059, 793], [-4010, -1051, 0, 0, -8020, 0, -1051, -1051], [1315, -64, 0, -32, 1315, 0, -64, -32], [4101, 0, 0, -583, -4101, 0, 0, 583], [0, -1501, 3739, -2238, 0, 0, 1501, -737], [0, -2163, 3612, -3612, 0, -3612, 2163, -1449], [0, 1231, -2462, -2925, 0, -1231, -1231, -4156], [0, 2798, -3174, 2422, 0, -3174, -2798, -376], [0, -3040, 2599, -441, 0, 5198, 3040, 2599], [0, 546, 541, -1087, 0, 0, -546, -1633], [0, 2340, -1866, 1866, 0, 1866, -2340, -474], [3954, 2905, 0, 2905, 1977, 0, 2905, 0], [5836, -1609, 0, 0, 11672, 0, -1609, -1609], [0, -2194, 4764, 376, 0, 4764, 2194, 2570], [-694, -608, 0, -1216, 0, 0, -608, 608], [0, -5815, 0, -5626, 0, -5437, 5815, 189], [2430, 4052, 0, 0, 4860, 0, 4052, 4052], [0, 1496, -2219, -723, 0, -4438, -1496, -2219], [-3805, 0, 0, 2264, 3805, 0, 0, -2264], [0, 4908, -5537, 629, 0, 0, -4908, -4279], [-2320, 1345, 0, 2690, 0, 0, 1345, -1345], [0, -3759, 7518, 1888, 0, 3759, 3759, 5647], [-5730, -46, 0, 0, -11460, 0, -46, -46], [0, -6015, -1573, -7588, 0, -3146, 6015, -1573], [7963, -1264, 0, -632, 7963, 0, -1264, -632], [0, -605, -1463, 2068, 0, 0, 605, 2673], [3200, 1398, 0, 2796, 0, 0, 1398, -1398], [-8590, -284, 0, -284, -4295, 0, -284, 0], [0, -4411, 0, -1912, 0, 587, 4411, 2499], [0, 3418, -7914, -1078, 0, -7914, -3418, -4496], [-12961, 0, 0, -2062, 12961, 0, 0, 2062], [0, -4718, 8863, -4145, 0, 0, 4718, 573], [0, -7898, 340, -340, 0, -340, 7898, 7558], [3390, -4223, 0, -4223, 1695, 0, -4223, 0], [0, 3459, -6918, -7835, 0, -3459, -3459, -11294], [0, 575, 0, -575, -12493, 0, 575, 1150], [-15545, -178, 0, -89, -15545, 0, -178, -89], [3555, 0, 0, 1811, -3555, 0, 0, -1811], [0, -4529, -1964, 1964, 0, 1964, 4529, 6493], [0, -2983, 0, 299, 0, 3581, 2983, 3282], [126, -5950, 0, 0, 252, 0, -5950, -5950], [9697, -1018, 0, -509, 9697, 0, -1018, -509], [0, 9366, -4956, 4956, 0, 4956, -9366, -4410], [0, 6019, 0, 2739, 0, -541, -6019, -3280], [0, 553, 0, -553, 14285, 0, 553, 1106], [0, -6549, 11712, -1386, 0, 11712, 6549, 5163], [0, 6589, 3039, 9628, 0, 6078, -6589, 3039], [0, -539, 2641, -2102, 0, 0, 539, -1563], [-11290, -912, 0, -1824, 0, 0, -912, 912], [41138, -623, 0, -623, 20569, 0, -623, 0], [0, -3025, 0, 3025, 9983, 0, -3025, -6050], [13470, -178, 0, 0, 26940, 0, -178, -178], [0, -5003, 4477, 526, 0, 0, 5003, 5529], [-23830, 151, 0, 151, -11915, 0, 151, 0], [-10230, -2839, 0, 0, -20460, 0, -2839, -2839], [0, -1887, 10506, 6732, 0, 10506, 1887, 8619], [13961, 0, 0, -193, -13961, 0, 0, 193], [0, 3895, -6101, 2206, 0, 0, -3895, -1689], [0, 4864, 1384, -1384, 0, -1384, -4864, -6248], [8132, -2286, 0, -4572, 0, 0, -2286, 2286], [0, 325, -650, 1515, 0, -325, -325, 1190], [-6245, 2146, 0, 1073, -6245, 0, 2146, 1073], [-10255, 0, 0, -6583, 10255, 0, 0, 6583], [0, 738, -2357, 1619, 0, 0, -738, 881], [0, 4114, -728, 728, 0, 728, -4114, -3386], [0, 551, 0, -551, 1265, 0, 551, 1102], [-6686, 1862, 0, 0, -13372, 0, 1862, 1862], [0, -5611, -174, -11396, 0, -174, 5611, -5785], [0, 2151, 4913, 7064, 0, 9826, -2151, 4913], [0, -2077, 0, -3628, 0, -5179, 2077, -1551], [0, 8251, -16502, -1575, 0, -8251, -8251, -9826], [0, 4244, 1998, 10486, 0, 1998, -4244, 6242], [1145, 0, 0, 1001, -1145, 0, 0, -1001], [-15460, -4166, 0, -8332, 0, 0, -4166, 4166], [-11722, 7495, 0, 7495, -5861, 0, 7495, 0], [0, -2485, 4970, 12062, 0, 2485, 2485, 14547], [-15270, -25, 0, 0, -30540, 0, -25, -25], [0, 4235, -15293, 11058, 0, 0, -4235, 6823], [0, -14396, 5146, -5146, 0, -5146, 14396, 9250], [-2130, -10262, 0, -10262, -1065, 0, -10262, 0], [0, 7215, -14430, 5779, 0, -7215, -7215, -1436], [0, -5532, 5226, -5838, 0, 5226, 5532, -306], [20545, 9542, 0, 4771, 20545, 0, 9542, 4771]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_108_h_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_108_4_h_a();".
// 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_108_4_h_a(:prec:=8)
    chi := MakeCharacter_108_h();
    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_108_4_h_a();".
// 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_108_4_h_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_108_h();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![4900, 2310, 433, 33, 1]>],Snew);
    return Vf;
end function;