
// Make newform 2160.4.a.j in Magma, downloaded from the LMFDB on 14 May 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_2160_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_2160_4_a_j();".
// 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_2160_4_a_j();".
// 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_2160_a();"
function MakeCharacter_2160_a()
    N := 2160;
    order := 1;
    char_gens := [271, 1621, 2081, 1297];
    v := [1, 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_2160_a_Hecke(Kf)
    return MakeCharacter_2160_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 := [[0], [0], [-5], [34], [-48], [-70], [27], [-119], [-51], [30], [133], [218], [-156], [88], [-516], [639], [-654], [461], [-182], [900], [704], [1375], [915], [1116], [-16], [-348], [412], [-900], [-115], [-966], [-1406], [246], [-519], [-1316], [-372], [1456], [956], [2446], [-3111], [2397], [-540], [2333], [-2730], [-4570], [-675], [3112], [-2441], [3418], [-4377], [4187], [1098], [6474], [3251], [1728], [5469], [-3216], [8010], [3805], [3224], [4530], [3292], [7953], [5290], [5358], [5600], [-7341], [-380], [434], [8004], [1109], [7662], [-8478], [-13286], [3080], [-10109], [-8727], [2712], [-8818], [-3306], [6401], [-2256], [1811], [-5454], [2990], [-9371], [6171], [-4122], [7076], [-762], [-8822], [-4977], [10104], [-14924], [1146], [14965], [15525], [8196], [-4932], [5938], [-6730], [17656], [-7974], [-25332], [1038], [-15671], [-916], [9141], [-5247], [-24162], [14357], [-3152], [4592], [7359], [15712], [3175], [-96], [18070], [1341], [24495], [-12378], [-24442], [2378], [-5478], [8595], [31615], [-29790], [3818], [-28314], [-56], [-34432], [1051], [39144], [1735], [6698], [-38766], [23501], [3591], [20716], [42981], [2268], [-11756], [-8646], [-10784], [42597], [-26458], [-11496], [21548], [-6261], [3355], [19701], [16292], [-9270], [-38486], [1893], [-44876], [23802], [24784], [-9060], [6176], [4182], [44079], [-12726], [-45218], [-3978], [-23466], [47913], [-31997], [-45628], [27299], [-8679], [31596], [-45313], [-39894], [53804], [11275], [21462], [-25715], [63306], [43612], [56882], [2608], [9384], [-35134], [-58698], [29595], [10236], [-47734], [-5384], [53273], [7254], [-57202], [43845], [6271], [-3336], [1323], [46725], [72677], [-48544], [40746], [10584], [62196], [21868], [-5650], [-37285], [18882], [-15642], [-1820], [42987], [-37140], [13228], [21098], [-18264], [-33320], [2076], [54588], [57917], [-26444], [-14568], [53973], [-29793], [-42982], [-28451], [86226], [47140], [11487], [-70369], [52293], [-67860], [-26822], [42612], [-49480], [-22223], [4768], [76974], [-8102], [53727], [19865], [45045], [-65994], [-108576], [-53940], [107485], [-88958], [-6667], [38310], [-97914], [448], [-3066], [-26732], [-22149], [5690], [-93798], [-63285], [-56671], [99651], [57744], [-27511], [33046], [90099], [2918], [37924], [52017], [-81493], [95276], [60045], [87532], [-85896], [69510], [-57206], [-56406], [128639], [-41366], [10964], [-42491], [-85048], [24622], [-130119], [90461], [6977], [-33708], [-33576], [96505], [-28911], [-144421], [33028], [88110], [72218], [73086], [63691], [-62136], [-44952], [127521], [-75810], [-126942], [51140], [10860], [-148619], [138882], [-8568], [29266], [134804], [142119], [156688], [15123], [-11981], [-33244], [-17220], [75107], [-133656], [-70252], [-46461], [-138636], [3576], [77002], [60471], [-87757], [-136920], [142140], [162146], [-104754], [19411], [-29608], [21420], [-103880], [-71133], [-92770], [-19037], [-151040], [-8040], [-71127], [-120310], [-46074], [44728], [-165612], [-4160], [-58860], [-135025], [52755], [-192202], [-178904], [-180592], [-81033], [216546], [-95573], [58098], [-105516], [-4129], [-173900], [101508], [204489], [48292], [-127978], [-11946], [145960], [-36430], [-27621], [-139542], [23094], [110994], [12273], [13322], [-45006], [-91440], [-8058], [42172], [63146], [-166281], [166966], [26642], [-182406], [148777], [79527], [44616], [-98219], [-242368], [176934], [-127890], [-84328], [-230094], [8750], [-156588], [66093], [-60374], [217119], [-33500], [140508], [53647], [67034], [-51032], [215616], [-224710], [-41613], [157374], [117466], [255066], [-146860], [177379], [238350], [-91217], [-90732], [-164950], [70218], [196126], [-35670], [254142], [-113375], [126614], [150330], [70828], [-44310], [-40138], [-184155], [126765], [86857], [57602], [-47286], [23670], [-209072], [55125], [34023], [122844], [192962], [112911], [-88206], [-136402], [-66063], [36465], [243018], [-92045], [-169860]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2160_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_2160_4_a_j();".
// 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_2160_4_a_j(:prec:=1)
    chi := MakeCharacter_2160_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_2160_4_a_j();".
// 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_2160_4_a_j( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2160_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<7,R![-34, 1]>,<11,R![48, 1]>],Snew);
    return Vf;
end function;