
// Make newform 35.8.a.a in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_35_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_35_8_a_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_35_8_a_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 := [-11, 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_35_a();"
function MakeCharacter_35_a()
    N := 35;
    order := 1;
    char_gens := [22, 31];
    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_35_a_Hecke(Kf)
    return MakeCharacter_35_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 := 8;
    raw_aps := [[8, 1], [-15, -6], [125, 0], [-343, 0], [-3953, -380], [-8909, -418], [-1199, 2210], [-1806, 5542], [6922, 10690], [-63449, -23772], [126384, -22554], [-132930, -43638], [-55960, 37354], [473786, -24578], [135637, -56742], [-633896, -65224], [-680060, 170640], [-906840, 11334], [-1094656, 506344], [-747464, -222048], [3584894, 212396], [-3971487, 187504], [-152356, -939444], [-8971764, 247538], [2129037, -680782], [-4229086, -2258654], [-7521079, 462442], [-379246, 1205004], [-19782299, -28272], [19712690, 916854], [7809692, -2195992], [-3371962, 175078], [-28935764, 3290990], [9868378, -97976], [33839738, -3091996], [-43259847, -3155932], [14940402, 8852248], [2740434, -5699264], [49957425, -7143998], [14642825, 9905174], [122859244, -3460128], [-84189984, -3501208], [-87343217, 9834508], [-144534980, -792666], [4118628, -9215594], [-33240532, -5302916], [-93992943, -6363120], [-136396455, -1708346], [170818925, 22855782], [102191592, 31333306], [-25617928, 31059880], [237831493, 19395844], [68600566, 22783442], [-76987010, -7973216], [-98564982, -29558644], [306296090, 1154584], [-342733582, 7234524], [63684368, -22374162], [191816018, 767756], [-203230645, 80738764], [64267259, 56709786], [-405262163, 15106350], [112923099, -53448846], [-27787310, -5938186], [74056575, -112937206], [-37997730, -64395548], [209180292, 9135600], [-252856998, -56719672], [277432590, -156657338], [-33559218, -44937274], [1030063821, -41102738], [217669288, 188488104], [1388694965, 38812722], [-312870100, -128293086], [595438140, -28293200], [766406564, -8451604], [-437488551, 95364952], [308880153, 191977186], [-2042287879, -14198848], [229115378, -95692156], [1644059856, -85826392], [-1865782123, 155712780], [-1206150661, 183079736], [-2686524066, -63266504], [353081022, -246640944], [-1305336366, -64417674], [1011072287, 129342236], [-313776964, 313942810], [681652704, -141330064], [-1514943016, -403463014], [-51349817, -435840734], [3483520350, 165199430], [-1803192794, 60586480], [-2184529699, -393863308], [-2481132757, 70952684], [-1768808801, 520858826], [-585278062, 334684424], [1713257450, 237092634], [-256964724, 234319592], [-2939530721, 629675476], [-5148391464, 131987870], [569028384, -450493576], [-262997540, -418406256], [2938646986, -12552032], [3005093964, -169814164], [-734330629, 441134130], [2113704144, -1027830476], [5836069635, -326554046], [450733995, -892485640], [5360471186, -394422088], [1578657455, -579284238], [-854534846, -1367772024], [5213885670, -443571988], [-2884985858, 539032626], [-9462881637, -95923292], [4695964786, -579738048], [-5233990655, 1025174074], [5397239344, 785145364], [3436665322, -794951050], [-2892059685, -323185760], [-2144735608, -1598099540], [7502342004, 409590206], [-1277160997, 1762195466], [-1296411960, 1185461994], [7486089172, -458850380], [-3324660061, -693291004], [1047105135, 1239974000], [3183861670, -1306494470], [-6952823664, -342830860], [3127087727, 277626510], [-3614017481, 249225892], [6859794408, 408498988], [868742265, 1092744104], [-10538467008, 215173668], [-1480027834, 2806454342], [3218349658, -3233704136], [-2854117365, -1770227626], [4792845413, 1423571866], [12310707473, -298233474], [-10364800615, -820352720], [13227790742, -1560670340], [-21432201455, 1090084404], [-27812529680, -18518726], [-6433084138, 947427648], [-5544220224, 1437127978], [3516022506, -162678962], [201699106, 202224432], [-2601495882, -1567208824], [-3551823348, -2454273344], [3737344372, 181705850], [-1180117862, -933176554], [9606423856, 20717912], [-8419713004, -2944906238], [-14048719456, -1020443216], [11104937914, 3777219354], [9139600104, 1332899036], [8291480157, -2778241124], [-30297061008, 955273236], [12235725525, -86387338], [9123570096, 3194489542], [18397083308, 1513112586], [2020174316, -6472372498], [-20499081514, -3110591300], [-741893268, 4416511470], [40862746382, -666831362], [4490372327, -6279572790], [3762884024, 2156236016], [-38157107059, 1796445990]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_35_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_35_8_a_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_35_8_a_a(:prec:=2)
    chi := MakeCharacter_35_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 8));
    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_35_8_a_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_35_8_a_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_35_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,8,sign)));
    Vf := Kernel([<2,R![20, -16, 1]>],Snew);
    return Vf;
end function;