
// Make newform 2352.4.a.n in Magma, downloaded from the LMFDB on 16 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_n();".
// 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_n();".
// 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], [10], [0], [12], [-30], [-34], [148], [-152], [-106], [304], [-114], [-202], [-116], [224], [-274], [-660], [-382], [-12], [552], [614], [-880], [-108], [86], [-1426], [810], [1032], [-900], [454], [18], [1072], [-1084], [2426], [684], [3598], [-2680], [-1422], [-220], [1992], [-4286], [4516], [2218], [-3136], [-3198], [-3714], [-3256], [4612], [2976], [-1084], [2746], [-5062], [-320], [6974], [-356], [-4770], [-2712], [-6942], [-4720], [-1490], [-7926], [-8596], [-438], [5140], [4296], [-2714], [-4314], [2284], [9650], [-4068], [3922], [414], [-5160], [-11056], [-7762], [-12228], [336], [1966], [-4606], [-13038], [-7290], [-5836], [2398], [17568], [-4354], [-14616], [-14516], [-14462], [3610], [3138], [-6896], [-1356], [9136], [-4072], [-12420], [13892], [-20408], [3666], [5046], [-18628], [-5594], [-13372], [15478], [12964], [10506], [6268], [5790], [8332], [23310], [-18184], [9398], [-20192], [11758], [-2310], [19356], [7768], [-11102], [22612], [-1656], [16070], [-21740], [31642], [-27518], [7290], [-3684], [24788], [15574], [-24338], [17760], [3704], [32354], [-8860], [-8168], [25600], [14878], [-9690], [10670], [-2326], [10612], [-41166], [-34182], [-10308], [-37362], [30808], [43596], [8578], [-41304], [11498], [-21210], [3580], [10144], [45926], [9038], [30692], [22104], [-42212], [24512], [-19912], [-6802], [-55482], [-3630], [32372], [-43286], [15864], [-9956], [28818], [40920], [-3072], [11306], [-942], [-5014], [31244], [-42222], [-984], [-12518], [34656], [-64010], [21196], [22254], [-2312], [31346], [-27568], [-5548], [-26546], [-4378], [21312], [26346], [28262], [17924], [24282], [-36624], [-22370], [13116], [17092], [77394], [8180], [53574], [-71918], [-60682], [-16546], [25432], [-43402], [49440], [31450], [85214], [53148], [3426], [18032], [17028], [-58150], [85804], [76434], [6618], [55304], [-20244], [47288], [8118], [-3984], [13150], [-86472], [13942], [71310], [-49112], [-39934], [89472], [-106796], [45854], [-37098], [67120], [22360], [-77076], [-55130], [61796], [-93760], [35866], [3868], [-24048], [-14978], [-16242], [-103060], [49464], [-88364], [-36148], [5624], [-24842], [-107922], [14584], [-21728], [-83932], [73068], [-34256], [68678], [-28802], [90632], [70374], [89522], [-25980], [85790], [69116], [49386], [25638], [44272], [-60], [-86166], [67106], [98574], [34196], [91990], [-77002], [-49428], [49038], [-28030], [15188], [21142], [-42864], [-21714], [-76312], [25756], [-95834], [-20518], [-82668], [40416], [-61496], [-36840], [-95286], [7196], [-60288], [-654], [-120530], [68664], [43038], [18390], [-145676], [-16918], [62620], [93782], [-94222], [79488], [-85046], [140892], [68276], [50422], [-74778], [133776], [44820], [-107940], [-60478], [-44244], [104210], [-76888], [30782], [-94288], [1310], [-38270], [-5884], [83560], [-79930], [147364], [106208], [86270], [132978], [70724], [-62614], [67842], [32480], [-164422], [-166466], [-68764], [-184436], [91344], [158286], [-59658], [2646], [137680], [-56780], [92476], [-110740], [-68714], [-71842], [15910], [24832], [-171762], [-176118], [82650], [-56792], [17462], [207108], [93338], [144236], [158032], [-175334], [142772], [-80294], [-124746], [-83232], [-77202], [-72522], [-210576], [-52420], [187794], [221448], [-73378], [-5754], [43488], [192012], [-50940], [-208390], [-118398], [-149448], [237514], [75892], [-1780], [-12816], [171694], [-164984], [35718], [-147884], [-46608], [25630], [-99170], [-55834], [32018], [-203686], [35960], [92322], [3380], [119352], [-28880], [36826], [7468], [93232], [51458], [-61558], [150492], [40452], [-155992], [36842], [41008], [-58666], [230300], [-127650], [192834], [102530], [-87216], [-208602], [97498], [175880], [81206], [-215534], [86052], [-192300], [-129522], [148254], [-265028], [159476], [-2310], [241698], [-174496], [10120], [307326], [186280], [-33066], [-8726], [158832], [83964], [-211530], [184914], [158900], [19146], [-121444], [126712]];
    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_n();".
// 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_n(: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_n();".
// 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_n( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2352_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![-10, 1]>,<11,R![-12, 1]>],Snew);
    return Vf;
end function;