
// Make newform 110.6.a.e in Magma, downloaded from the LMFDB on 21 December 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_110_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_110_6_a_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_110_6_a_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 := [-222, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rfbasis := [Kf.1^i : i in [0..Degree(Kf)-1]];
    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_110_a();"
function MakeCharacter_110_a()
    N := 110;
    order := 1;
    char_gens := [67, 101];
    v := [1, 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_110_a_Hecke(Kf)
    return MakeCharacter_110_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]];
    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 := 6;
    raw_aps := [[-4, 0], [11, -1], [-25, 0], [15, 5], [121, 0], [398, -30], [193, -103], [767, 3], [-506, 206], [3899, -131], [2339, 87], [14251, 73], [5094, -144], [9404, 714], [10826, 994], [-17089, 1141], [-6770, -1558], [2673, -997], [16920, -844], [-44319, 1341], [18470, 2034], [-25062, 2006], [31786, -4000], [-78285, -2103], [58600, -8078], [1266, 11004], [-1748, -104], [-80452, 2386], [-11394, 3944], [41864, 4642], [125156, 12330], [-30933, 19095], [-146632, 16090], [-110036, -2984], [48049, -11737], [-160634, 25018], [46555, 10021], [28271, -22293], [-69857, -25447], [-183378, -6570], [-261948, -22992], [281002, -8072], [-473340, 36924], [490589, 16749], [4888, -29944], [74625, 33533], [369147, -60841], [373898, -1206], [393822, 15168], [-923266, -4200], [-552279, 26301], [-1284950, -5002], [780618, 49460], [-631490, 5210], [167126, -108716], [-10275, 27507], [1631648, 18970], [1199628, 10736], [1055236, -38456], [93758, 79336], [-911246, -18248], [1084758, -112206], [1714494, -34012], [894043, 23711], [1479678, 49124], [-256935, 169923], [-591216, -160228], [1819255, 146935], [2612902, -23476], [2240574, -74452], [-2222170, 31372], [-1146356, 200072], [-1201028, -10964], [-1659130, 174054], [2728686, -27430], [-1823382, -170250], [-481678, -166292], [-1337798, -106040], [141441, 273111], [-2755720, 184638], [-2387672, -116692], [-1416676, 219402], [-48720, -82872], [-4230040, -60366], [1873952, 133536], [-1185940, 276004], [5750842, -69436], [-1375277, -356225], [1406109, -341373], [-5424802, 147102], [4423539, -274365], [5185572, -3264], [-425368, 185880], [3116655, 62319], [-3009092, 252328], [-1146060, 528810], [323720, 338674], [-1929458, -214120], [3641436, -54010], [-5070121, -143979], [-7279060, -133434], [330710, -27122], [3770698, -115516], [-522988, 95986], [5158673, 429921], [-3185562, -288448], [-4879959, 661353], [-180290, 624698], [3034971, 339999], [-12821830, -4956], [5140501, -391001], [-654938, 525478], [10211340, -562386], [-2613116, 147688], [-7803135, 337325], [9255837, 294675], [10253959, -342797], [12025978, 357398], [8669961, -671433], [2371165, -431323], [-5631130, -293688], [-1424883, 804317], [-4295468, -294952], [-4474891, 678565], [-988150, 300510], [2270777, -240869], [-9741842, -955676], [-8940153, 432531], [17640050, 74790], [-5382812, 326308], [-16104120, -233788], [17569519, -6643], [6862895, -766125], [-25965190, 83112], [15924018, 586416], [7174870, -67880], [14821099, -215959], [-22200164, 566098], [3613638, -1752324], [15293586, 1235772], [-7775819, -1454387], [-27518378, 643964], [4644324, 1014680], [17188440, 1015734], [-15146288, -576842], [2799720, -1382616], [-15336958, 627306], [-10892727, 702417], [2172058, 668038], [-21532202, -737686], [-25947898, -311730], [-2658782, -823960], [3370237, 1507297], [11045716, -991078], [-28630349, 1121371], [-29858363, -194551], [-30363676, -545484], [37499825, -170045], [1988070, -2817178], [20713487, -1905851], [6057121, 2745473], [-17079265, -1390949], [-18305423, -1726757], [-20082528, -2194188], [12377416, -454054], [-42669866, 22946], [-18834080, 135880], [-32120212, 144180]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_110_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_110_6_a_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_110_6_a_e(:prec:=2)
    chi := MakeCharacter_110_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 6));
    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_110_6_a_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_110_6_a_e( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_110_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,6,sign)));
    Vf := Kernel([<3,R![-112, -21, 1]>],Snew);
    return Vf;
end function;