
// Make newform 800.6.a.h in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_800_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_800_6_a_h();".
// 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_800_6_a_h();".
// 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 := [-10, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [0, 2]];
    Rf_basisdens := [1, 1];
    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_800_a();"
function MakeCharacter_800_a()
    N := 800;
    order := 1;
    char_gens := [351, 101, 577];
    v := [1, 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_800_a_Hecke(Kf)
    return MakeCharacter_800_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 := 6;
    raw_aps := [[0, 0], [0, 1], [0, 0], [0, 7], [0, 114], [146, 0], [702, 0], [0, -432], [0, -647], [-4010, 0], [0, -722], [14778, 0], [-4350, 0], [0, 1965], [0, 951], [18154, 0], [0, 3116], [-42130, 0], [0, 2559], [0, -7186], [-26266, 0], [0, 1372], [0, -15615], [30570, 0], [-66882, 0], [42798, 0], [0, 1661], [0, 10571], [-111714, 0], [-216834, 0], [0, 9847], [0, -27858], [-99802, 0], [0, 42924], [-413626, 0], [0, -27274], [-179358, 0], [0, 73669], [0, -96381], [-591086, 0], [0, -33396], [-97538, 0], [0, -48566], [-12434, 0], [378858, 0], [0, -121304], [0, 136694], [0, -101147], [0, -155033], [-1012610, 0], [706326, 0], [0, 188772], [404410, 0], [0, -226510], [987982, 0], [0, 326065], [-780386, 0], [0, 88906], [-386758, 0], [1554850, 0], [0, -276947], [-1553094, 0], [0, 411743], [0, 47770], [-2094554, 0], [-1076238, 0], [0, -49490], [-1554002, 0], [0, -351341], [-774570, 0], [2262174, 0], [0, 137496], [0, -198213], [-175206, 0], [0, 126008], [0, -531467], [-5519594, 0], [1747378, 0], [541122, 0], [3796994, 0], [0, 613652], [-6660810, 0], [0, 735762], [6238734, 0], [0, 752216], [0, 912433], [-4227654, 0], [-4313738, 0], [-5948202, 0], [0, 1327717], [0, 839547], [0, -922836], [0, -1384013], [0, 817186], [0, 847760], [0, -832683], [5468470, 0], [-3057622, 0], [0, -1524403], [-4158202, 0], [0, 842159], [-999102, 0], [0, 840985], [6567586, 0], [0, 25958], [-9277618, 0], [0, -860889], [15097774, 0], [0, 1104572], [6169410, 0], [0, 1593303], [-5268854, 0], [13811222, 0], [0, 507392], [0, -960074], [-2027670, 0], [0, 1893717], [0, 228899], [-4824766, 0], [0, 691932], [-7349530, 0], [17569214, 0], [-5603382, 0], [0, -799755], [0, 2330938], [-8833170, 0], [-1931010, 0], [0, -1142172], [0, -1551265], [24081314, 0], [0, -3802924], [0, 743389], [0, 3656886], [12663482, 0], [-4335238, 0], [-364270, 0], [1030506, 0], [0, -3087965], [-7863438, 0], [-10501430, 0], [0, -2969422], [20055750, 0], [0, 1619777], [0, 130843], [-38032786, 0], [0, 5654588], [-970214, 0], [-1864682, 0], [0, -167260], [0, 1303385], [24036242, 0], [36860490, 0], [0, 2646881], [0, -1463129], [0, -1629049], [0, 6045870], [0, -1220876], [3390394, 0], [7674902, 0], [45511542, 0], [0, 3609647], [-46447834, 0], [0, 4158391], [0, 3477990], [-44674962, 0], [0, -3205607], [0, -2358026], [-31703238, 0], [7547330, 0], [-24307974, 0], [0, -4501848], [-32083738, 0], [0, -940070], [-38116346, 0], [0, 5636152], [-17787350, 0], [0, -4435298], [57268782, 0], [0, -3632119], [-35418946, 0], [0, 9749723], [0, 257262], [21593114, 0], [58093158, 0], [0, 9856057], [21601230, 0], [-43286382, 0], [0, 8813237], [-58980174, 0], [0, 2506278], [7094286, 0], [0, -6191], [0, 3867482], [61446030, 0], [0, 8726523], [-41326474, 0], [-5498870, 0], [70379794, 0], [42547518, 0], [0, 1255181], [-23460730, 0], [0, -14467742], [23490122, 0], [-77208670, 0], [0, -2709692], [-74727198, 0], [0, -12918720], [0, -11438171], [40134170, 0], [0, -9974330], [-104586658, 0], [33791910, 0], [0, 14463897], [0, 8535423], [0, -1041796], [-103607710, 0], [0, 5766159], [59143458, 0], [0, 9613275], [59321026, 0], [-113020170, 0], [0, -7031428], [-81553710, 0], [0, -14784679], [0, -48869], [73192646, 0], [-102086826, 0], [0, 21170248], [0, -19960073], [0, 11165598], [100342546, 0], [0, -3597376], [0, -7627270], [83719570, 0], [0, 4414449], [0, 18471039], [142805866, 0], [169173354, 0], [0, 4465968], [0, -27245678], [0, 14352369], [0, 22087234], [0, 409805], [-19848570, 0], [136600494, 0], [0, -2223952], [0, -19310337], [0, 5754418], [0, -1923716], [0, -3890787], [-41732862, 0], [-78699198, 0], [0, -19345805], [71115234, 0], [117636914, 0], [0, -31521592], [-63312802, 0], [0, 25472851], [208121322, 0], [-103498778, 0], [0, 29492025], [0, -22035113], [166101950, 0], [-28784174, 0], [92890382, 0], [0, 34668752], [-42461530, 0], [-12703702, 0], [0, -2961887], [-42082694, 0], [-80410858, 0], [0, 4497291], [27016646, 0], [0, 22652816], [-175621058, 0], [0, 32238773], [0, -21822273], [139972150, 0], [-89593870, 0], [0, -29834258], [0, 18153657], [0, 14586346], [0, 8798991], [26599182, 0], [0, 28426999], [0, -21674946], [-99835714, 0], [257801818, 0], [0, 15708044], [-277888086, 0], [1213150, 0], [0, -22969821], [39352534, 0], [0, -2962502], [-277889806, 0], [-90648114, 0], [0, -25101506], [-83419734, 0], [0, 7938440], [0, -10491077], [140056934, 0], [-45163438, 0], [0, -52107228], [0, -28712051], [0, -15029654], [-176093922, 0], [0, -46902153], [-286613050, 0], [0, 2319024], [-270083494, 0], [0, 7523485], [-355441810, 0], [-69712878, 0], [0, 20986641], [0, -36925613], [-20113990, 0], [0, 16225784], [0, 23209342], [247724686, 0], [-102935366, 0], [0, -10818430], [230376598, 0], [-263601490, 0], [0, 36584989], [-87290746, 0], [116330970, 0], [0, -15133784], [0, -29857319], [0, 30034263], [-84671366, 0], [-432459330, 0], [190529282, 0], [0, 28727404], [0, 2908609], [0, 25853042], [0, 73684683], [-92537714, 0], [-164755634, 0], [-303406350, 0], [0, -53598565], [-389623414, 0], [115194502, 0], [-181662666, 0], [0, -44815810], [98305746, 0], [0, 25090384], [224845270, 0], [0, -66399501], [0, 55326502], [54964698, 0], [0, 15080438], [-99339338, 0], [69582110, 0], [0, 29821265], [72611310, 0], [-18344106, 0], [0, -31218060], [0, 44370358], [10858958, 0], [0, -26709099], [-64325318, 0], [381765818, 0], [0, 6823923], [0, 80190108], [0, 23194531], [345336406, 0], [-372077102, 0], [0, -51256951], [-125135630, 0], [0, 28735734], [0, 41768176], [0, 43551493], [137040294, 0], [0, -65535370], [-161691262, 0], [0, -55129072], [0, -84828522], [-270537026, 0], [416836106, 0], [566624278, 0], [502873062, 0], [-118947706, 0], [0, -75063081], [-219796802, 0], [0, 72958352], [0, 38693745], [0, 9683410], [-268860502, 0], [0, -5643143], [0, 77741455], [-56375734, 0], [154297994, 0], [0, -58834844], [0, 10801723], [0, -106701090], [448071094, 0], [0, 7089476], [-39181110, 0], [0, -86192598], [64111110, 0], [-373371314, 0], [71221006, 0], [0, 67267355], [597332278, 0], [474799766, 0], [0, 14013406], [-98125278, 0], [-336204862, 0], [0, -51454111], [0, -9101268], [-121559986, 0], [453332298, 0], [0, -71881411], [0, -60986178], [557244518, 0], [573432918, 0], [0, 43413840], [0, 6627051], [389286958, 0], [0, 108966925], [214750574, 0], [-250244502, 0], [0, -79782497], [0, 79917860], [-11947114, 0], [-846740558, 0], [0, 105382909], [161926834, 0], [0, -62934682], [0, 123891480]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_800_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_800_6_a_h();".
// 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_800_6_a_h(:prec:=2)
    chi := MakeCharacter_800_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(2999) - 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_800_6_a_h();".
// 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_800_6_a_h( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_800_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,6,sign)));
    Vf := Kernel([<3,R![-40, 0, 1]>,<11,R![-519840, 0, 1]>,<13,R![-146, 1]>],Snew);
    return Vf;
end function;