
// Make newform 2352.4.a.y in Magma, downloaded from the LMFDB on 20 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_2352_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_2352_4_a_y();".
// 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_2352_4_a_y();".
// 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_2352_a();"
function MakeCharacter_2352_a()
    N := 2352;
    order := 1;
    char_gens := [1471, 1765, 785, 2257];
    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_2352_a_Hecke(Kf)
    return MakeCharacter_2352_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], [3], [-11], [0], [-39], [-32], [12], [88], [92], [255], [35], [-4], [16], [330], [298], [-717], [217], [386], [-906], [34], [-838], [-1325], [-1163], [-54], [7], [-46], [-1656], [367], [1622], [-736], [-1175], [2541], [-802], [-3110], [2598], [-1333], [1580], [-1268], [-878], [-2882], [-1476], [4368], [-3016], [-1563], [-1846], [3996], [-4182], [-1159], [-1785], [588], [6828], [-2508], [-4297], [2489], [1786], [-2318], [-2749], [-1825], [-304], [4578], [-4302], [6727], [-116], [3792], [-3687], [-8281], [6668], [-8679], [-9092], [11642], [6808], [-1110], [-959], [16], [736], [8414], [694], [11476], [-12040], [13711], [4128], [-8442], [9564], [-13394], [-15513], [-12379], [-8368], [-1577], [8202], [1936], [-13156], [6630], [-4195], [-1107], [-13630], [11760], [-19101], [10590], [-17400], [-6410], [24020], [-26139], [-9171], [-19608], [3674], [-3873], [13743], [16356], [-10782], [25547], [-14299], [23900], [-9246], [-13950], [-15787], [-8438], [-22522], [-17138], [-9963], [8664], [2450], [-6643], [15593], [371], [-8232], [30751], [12318], [-18022], [1279], [-36910], [31226], [17758], [-2019], [-2398], [10440], [-4739], [-34030], [-7226], [4881], [-13112], [-40982], [39843], [-7256], [23005], [368], [5556], [-5674], [-7826], [-3370], [-27734], [45280], [-47610], [28328], [48612], [-4100], [13902], [-45824], [38874], [-1829], [-5855], [-21120], [21650], [-36597], [54187], [36034], [40628], [40431], [-33266], [-41145], [22521], [-43345], [26346], [-13304], [-4299], [-35971], [18268], [38710], [36777], [10008], [-20394], [-24509], [-23961], [-33362], [69058], [1502], [41789], [54010], [-61158], [-10021], [-14264], [-1183], [-8289], [-32560], [2918], [-9299], [24246], [838], [73458], [24598], [-51814], [-18179], [-10144], [5286], [-64094], [37408], [-17625], [-53112], [-11097], [67300], [2590], [11218], [-36431], [-13973], [41959], [-14648], [13218], [19385], [-3620], [90918], [-43846], [-1888], [47272], [-40366], [3407], [-30717], [75832], [-85538], [71092], [74391], [12660], [62862], [-49264], [-6693], [-50190], [46406], [17400], [-83653], [-18783], [25252], [30812], [23604], [-59272], [9673], [-54070], [-57768], [-17484], [-68149], [34860], [83632], [-49288], [6338], [-68310], [-112446], [-84894], [12587], [31785], [-64866], [102916], [97811], [73781], [-79672], [60957], [57630], [-25156], [-82382], [-63350], [32705], [-96024], [98524], [-74671], [-26160], [45454], [108709], [68253], [-92755], [37328], [-12841], [11420], [92358], [-19088], [74450], [110015], [-70080], [20196], [-96014], [152620], [-17177], [-7935], [-46523], [158964], [68414], [-62473], [-44892], [14060], [51064], [24489], [18376], [-178], [49908], [98366], [-95610], [15961], [2957], [-154587], [-100786], [-20222], [-31059], [26870], [-38526], [-92594], [12618], [139386], [5728], [-151728], [-176564], [-25450], [23169], [-92220], [30309], [105704], [-37816], [-97094], [-106193], [5168], [-186600], [-78365], [-44470], [-19414], [59350], [-5835], [136590], [28449], [-51264], [200168], [-102890], [105964], [-2312], [-11482], [31713], [33521], [-3886], [-203736], [54087], [-89727], [105191], [-222765], [-144514], [71498], [-124218], [-155481], [-164296], [104979], [-197022], [48381], [-18542], [175818], [-166302], [-137279], [-95844], [89762], [147390], [-42840], [105870], [65068], [102404], [45523], [-141118], [-61672], [125481], [-32961], [-77600], [-86942], [132775], [-36224], [-47740], [-8680], [-126088], [4395], [-168290], [126142], [27894], [37254], [155024], [-5256], [-36594], [-162662], [-121648], [-108092], [28672], [25800], [181537], [-214170], [175581], [112730], [-81622], [178207], [-88427], [-154050], [140452], [-182247], [279352], [168420], [42676], [-99498], [-66245], [71489], [-112074], [-214870], [-126754], [243285], [100519], [8757], [-55613], [230], [-194606], [112011], [-52980], [71488], [153084], [-136326], [-145307], [246294], [182242], [150421], [55018], [-183870], [-83937], [172164], [-44922], [-100004]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2352_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_2352_4_a_y();".
// 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_2352_4_a_y(:prec:=1)
    chi := MakeCharacter_2352_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_2352_4_a_y();".
// 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_2352_4_a_y( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2352_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![11, 1]>,<11,R![39, 1]>],Snew);
    return Vf;
end function;