
// Make newform 270.4.a.f in Magma, downloaded from the LMFDB on 16 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_270_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_270_4_a_f();".
// 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_270_4_a_f();".
// 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
        Kf := Rationals();
    end if;
    return [Kf!elt[1] : elt in input];
end function;


// To make the character of type GrpDrchElt, type "MakeCharacter_270_a();"
function MakeCharacter_270_a()
    N := 270;
    order := 1;
    char_gens := [191, 217];
    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_270_a_Hecke(Kf)
    return MakeCharacter_270_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 := [[-2], [0], [5], [14], [3], [47], [-39], [32], [-99], [51], [83], [314], [-108], [299], [531], [564], [12], [230], [-268], [120], [1106], [-739], [1086], [-120], [-1642], [33], [-1198], [-1542], [-556], [1605], [1334], [-2883], [282], [-2494], [2595], [1229], [-1591], [-457], [-1164], [3942], [-1212], [2288], [-1938], [-1498], [-2124], [-385], [3170], [1388], [-4644], [4736], [2814], [-2202], [3485], [-6345], [525], [5196], [-7479], [-856], [-7054], [1014], [992], [-4950], [-4777], [-7692], [-2932], [8352], [-3070], [-1672], [-5076], [8594], [12711], [-1464], [-7630], [-3883], [-13768], [-14139], [567], [-6685], [4572], [-25], [12453], [5048], [5400], [-6298], [-6208], [-3360], [14394], [-916], [8550], [3734], [9840], [-17280], [-4588], [636], [-11716], [4653], [16479], [3120], [17645], [-2182], [-4033], [-960], [-23754], [-22536], [17726], [17168], [7542], [-15543], [16026], [10469], [-8074], [26855], [24447], [1850], [21728], [23862], [10523], [5484], [-26784], [-12120], [-18226], [-11062], [-9348], [19248], [-17710], [-19437], [-19516], [17358], [24428], [-21418], [-664], [-34209], [6857], [-23719], [-14418], [-4849], [-36258], [-18877], [-16200], [-26760], [-10510], [-28230], [-39868], [32394], [34820], [-1146], [-19393], [-8430], [15470], [5871], [-11299], [29682], [40316], [-21945], [24911], [33264], [-23191], [2160], [2066], [-22233], [-17754], [33891], [51074], [20967], [31749], [47325], [2363], [45569], [59657], [8538], [16113], [62822], [-11418], [-16060], [29963], [57096], [2360], [-63990], [58268], [-826], [10064], [-26280], [-49903], [-25107], [42816], [-42138], [14267], [46055], [59774], [-32430], [-21982], [-9366], [-63004], [-42951], [-24852], [28146], [-8146], [-22501], [15486], [47832], [-58995], [36044], [16730], [-10162], [3045], [-42744], [-84361], [25302], [79470], [45740], [-69064], [-2547], [-42856], [48942], [-62766], [-6121], [76142], [39522], [20691], [62610], [-24772], [-39193], [-33960], [72848], [-16302], [46262], [41937], [-15966], [-93004], [-55053], [8258], [-42766], [-73735], [76470], [93572], [-38028], [17243], [-54492], [-59208], [-12588], [-34260], [15068], [18122], [11054], [-7614], [49020], [106250], [-13035], [-51442], [-76911], [-83275], [-35460], [-83976], [121034], [-56574], [13227], [82508], [18893], [8742], [18686], [78332], [-106230], [32966], [94703], [64971], [20144], [-15306], [9672], [-139813], [-672], [-28156], [38897], [-37798], [-98737], [36074], [-53752], [108384], [47972], [-72259], [46545], [-105693], [108011], [120237], [13376], [-22957], [40554], [-102868], [62874], [33803], [69630], [-71475], [-33648], [133575], [156180], [-32542], [26826], [-23368], [-128142], [-87321], [-87796], [-123400], [33624], [-1825], [63654], [31310], [10334], [-101754], [153806], [-69210], [-140203], [-24963], [99546], [1014], [96395], [47325], [52607], [-131091], [-148560], [42680], [-158946], [91160], [-96064], [122691], [12692], [-57171], [58625], [-60748], [51356], [24141], [27936], [96554], [66798], [6833], [-109602], [-20824], [7710], [-122620], [131622], [141203], [-116278], [-44635], [-20235], [-41466], [93155], [-78180], [111273], [59726], [-190204], [-88260], [115974], [78728], [115676], [-159945], [207542], [62480], [106647], [44916], [-63063], [-172689], [176169], [180626], [-34332], [-175788], [-211407], [3743], [8780], [-43032], [-658], [-128581], [-41823], [62186], [41787], [-16458], [-71200], [-173299], [-95163], [-187176], [-48292], [-83598], [259682], [211755], [-197385], [-43912], [-247065], [-112294], [233751], [-31480], [-179722], [-122221], [-44973], [-222883], [250242], [-130572], [-19825], [-117384], [261788], [-82528], [-226296], [-140470], [-258555], [148412], [80739], [40340], [-108561], [71406], [132824], [-253939], [-286602], [-225988], [37611], [-154258], [-168882], [17370], [-149434], [-196438], [-70170], [-120426], [25916], [169374], [190377], [-130197], [-50146], [110097], [299007], [-46510], [-64818], [22260], [-30660], [306902], [199350]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_270_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_270_4_a_f();".
// 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_270_4_a_f(:prec:=1)
    chi := MakeCharacter_270_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(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_270_4_a_f();".
// 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_270_4_a_f( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_270_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<7,R![-14, 1]>,<11,R![-3, 1]>],Snew);
    return Vf;
end function;