
// Make newform 2352.4.a.be in Magma, downloaded from the LMFDB on 25 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_be();".
// 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_be();".
// 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], [4], [0], [20], [-4], [24], [-44], [-72], [-38], [-184], [-30], [-216], [164], [-520], [-146], [-460], [628], [-556], [-592], [1024], [104], [324], [896], [-920], [1108], [-1448], [-1316], [-86], [1778], [928], [-1404], [-1370], [-516], [1390], [-136], [-148], [1212], [-1976], [-2692], [2580], [-2036], [-3960], [2], [3774], [3560], [2692], [-4528], [3652], [-4804], [2758], [-6528], [-56], [-4900], [-6784], [4544], [-4052], [2752], [4366], [7734], [4052], [-3420], [-7324], [4192], [-6840], [6630], [6868], [-7378], [2676], [-5124], [4560], [-3656], [1616], [2734], [1380], [-6888], [-2046], [3116], [2958], [7944], [-4084], [-6306], [11824], [-4504], [-13056], [-132], [4866], [10106], [-18036], [-5288], [-15164], [-7896], [-2920], [7932], [2004], [-4496], [12620], [18008], [-13292], [-8570], [1916], [19926], [-4244], [-22794], [-14028], [8368], [-52], [5808], [10464], [1184], [-13152], [-18334], [-8122], [-5980], [-12528], [20798], [1932], [8424], [-17750], [27580], [-9292], [11486], [7116], [7612], [21572], [-1702], [6370], [8808], [-17768], [-5564], [17564], [38280], [-36192], [-14], [-26504], [40184], [-35340], [14852], [19788], [16986], [26596], [-34898], [-12928], [43164], [-41228], [1368], [5276], [840], [26028], [29448], [25866], [9472], [-49372], [11160], [-22708], [16192], [46320], [-2280], [49056], [-24876], [-23428], [-6678], [-15544], [31124], [50062], [-328], [20872], [-46924], [13522], [33612], [22812], [-37764], [19680], [-1242], [4424], [47696], [-13220], [27618], [4240], [53380], [-16944], [34780], [-32670], [48144], [47888], [-17524], [-45754], [-9516], [42118], [-71336], [20720], [22636], [56212], [37212], [37684], [46864], [47182], [7066], [80992], [768], [44950], [58936], [65444], [67040], [13428], [-55932], [-46120], [-65508], [38618], [-53300], [-65586], [-90732], [41816], [-84876], [13376], [-39112], [-71320], [58200], [-6336], [101146], [43330], [-14400], [-7614], [99712], [-34956], [-22990], [-23552], [47056], [13680], [-71292], [90378], [33884], [25736], [17050], [-37212], [25184], [-9416], [52718], [-37748], [19280], [4348], [88436], [27856], [-89482], [59232], [2472], [-48064], [53748], [-53740], [-5960], [-92346], [-110768], [54192], [75520], [-81612], [-98044], [-89038], [71756], [-4620], [-32536], [-89504], [-53156], [-120556], [-62940], [36168], [-6740], [15222], [-51360], [71212], [-101566], [-142500], [96428], [368], [-143584], [109280], [5392], [-51580], [52678], [-117350], [108372], [53488], [-30080], [-153896], [-154588], [-153244], [44784], [-69838], [-2418], [79640], [-32208], [81558], [74708], [85014], [78068], [43830], [43820], [-9664], [-19508], [-163572], [-82468], [-4952], [-83574], [60056], [127404], [-118524], [49118], [-68620], [-20956], [108504], [-124706], [-152496], [37266], [-49890], [-84692], [-21104], [177152], [-47380], [-26344], [-55808], [-59890], [-85604], [130358], [-168156], [-32152], [-39014], [8808], [122220], [-133932], [171696], [-153278], [139574], [-62982], [-48744], [-69716], [200572], [-158540], [155386], [115472], [-195760], [-184008], [34670], [-139146], [45932], [56544], [32986], [160236], [31932], [86612], [197232], [164436], [28908], [-212710], [-129962], [-155720], [143630], [35728], [-114168], [-96316], [-84334], [1928], [107294], [-111648], [33984], [39916], [135764], [114822], [-15780], [92680], [48362], [-177036], [-124292], [131240], [-236882], [43232], [-179450], [99284], [-112640], [-201280], [-100184], [97960], [62460], [-233094], [-101376], [48994], [-109796], [35904], [-77496], [20388], [163564], [-125064], [52382], [-121708], [-264196], [183836], [195880], [182134], [-34872], [146328], [940], [-19662], [12932], [76610], [-272744], [60584], [-9636], [280600], [-22730], [4434], [220876], [226284], [27104], [3282], [154772], [-69100], [-169722], [23196], [131256], [190232], [127304], [298224], [-171686], [-114092], [-58248], [189084], [123400], [-130108], [-92532], [-68682], [-302020], [260264]];
    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_be();".
// 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_be(: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_be();".
// 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_be( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2352_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![-4, 1]>,<11,R![-20, 1]>],Snew);
    return Vf;
end function;