
// Make newform 1350.4.a.p in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1350_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_1350_4_a_p();".
// 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_1350_4_a_p();".
// 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_1350_a();"
function MakeCharacter_1350_a()
    N := 1350;
    order := 1;
    char_gens := [1001, 1027];
    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_1350_a_Hecke(Kf)
    return MakeCharacter_1350_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], [0], [-23], [30], [34], [42], [-139], [-192], [234], [-55], [-191], [138], [-53], [-366], [330], [-396], [23], [-452], [204], [691], [-709], [-1098], [-816], [-905], [-1278], [-605], [-1488], [593], [-324], [-1928], [2742], [-1326], [893], [-2502], [-2767], [2701], [-1748], [534], [192], [1140], [398], [3474], [2713], [-4734], [5132], [5240], [4519], [-5064], [2573], [-4098], [-306], [6482], [-5850], [-5598], [8286], [-504], [-4489], [-2213], [-2718], [-5615], [-1488], [-7487], [8118], [5002], [-5082], [7625], [3778], [8268], [1379], [-3072], [-7446], [6496], [1633], [6788], [-6582], [2850], [-7451], [14124], [6374], [3948], [12629], [4842], [-3851], [-7435], [5760], [-2190], [-7202], [-13476], [10843], [-6108], [9852], [-7796], [2454], [-2953], [11322], [9696], [-12192], [8491], [-9355], [295], [16914], [12108], [-6960], [-10687], [8329], [25302], [22248], [24252], [-9829], [14155], [-23051], [8352], [-24331], [2216], [-28500], [25252], [28920], [-32268], [-10050], [-4561], [-21359], [-15042], [-27462], [6212], [-13224], [34709], [32070], [-125], [-32222], [-19240], [-30252], [-12517], [-2201], [8742], [-28618], [-6594], [-15881], [26052], [12648], [27179], [11874], [18448], [3234], [-32155], [-21996], [-3278], [21228], [-5767], [5322], [42097], [-17658], [22297], [10542], [-47639], [-10326], [5147], [-47064], [15385], [-34914], [-37434], [-8778], [54061], [-3084], [-12048], [-33618], [25043], [17710], [-60691], [-13902], [-20508], [46403], [26208], [-55733], [34976], [19812], [-60733], [57906], [-36164], [-10477], [62152], [60846], [3979], [39324], [-15948], [-28434], [-16382], [35692], [37841], [27408], [-19733], [-52050], [-49153], [6660], [3120], [-9270], [-1789], [43063], [-47196], [-12558], [-77172], [-58417], [53431], [-32947], [-32106], [-6582], [-21955], [-16002], [48966], [-86092], [13570], [-62106], [-3116], [-4686], [-43206], [21179], [-49157], [86610], [-6804], [67152], [72509], [-12169], [-17022], [9880], [-46644], [-43918], [40212], [-42678], [-1208], [-77448], [59143], [17876], [-91225], [12534], [74275], [63144], [-43855], [-51360], [61596], [14964], [-27750], [40448], [3775], [-97486], [38382], [-105714], [-72149], [-55848], [-11647], [8364], [113434], [-101196], [-11394], [-6190], [-1428], [35850], [-26203], [-16148], [9336], [101194], [95737], [107802], [124661], [-64895], [-23574], [91748], [23352], [93042], [45592], [-288], [64715], [88603], [49498], [88184], [53695], [64201], [-62232], [-21025], [105443], [92430], [63648], [8984], [48654], [52706], [-7508], [-105750], [-141698], [125088], [-101383], [79482], [-146688], [-38292], [25896], [-131796], [-95003], [-38172], [-14233], [-70890], [4332], [-23159], [100861], [-38520], [-29395], [54804], [40853], [-93725], [-41280], [76757], [20046], [90133], [-95088], [-2058], [-27306], [-37823], [168384], [109853], [-32622], [-141786], [-160865], [-125514], [14303], [-107462], [-4962], [-1385], [-28728], [-9871], [-23581], [182017], [49272], [-16254], [-101014], [-127866], [-60856], [-106008], [-82369], [190464], [82535], [-153510], [153521], [-152912], [-77387], [-109404], [209400], [181409], [-123150], [108642], [-59095], [70057], [-8664], [40986], [-16015], [75787], [156060], [150769], [4322], [-62616], [-36318], [26838], [89370], [-42096], [-47651], [-77370], [-202788], [-130920], [71971], [33241], [8388], [119707], [194150], [171852], [61115], [-152364], [-212136], [7193], [-365], [-157680], [-250692], [-131870], [-51204], [-4541], [4332], [-55980], [230605], [-8616], [186455], [-72996], [-12727], [-47441], [181447], [-235470], [-126163], [3060], [34650], [-12404], [-79620], [118147], [-153160], [126510], [-197695], [564], [67538], [-171864], [-57131], [-209454], [-58806], [71264], [-110093], [48018], [79468], [-143724], [60337], [-163560], [-159588], [-41164], [247783], [-11226], [-2928], [-64373], [303222], [-5772], [-189954], [-44243], [-19104], [151230], [110122], [-128064], [-24906], [115926], [-74935], [166956]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1350_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_1350_4_a_p();".
// 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_1350_4_a_p(:prec:=1)
    chi := MakeCharacter_1350_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_1350_4_a_p();".
// 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_1350_4_a_p( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1350_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<7,R![23, 1]>,<11,R![-30, 1]>,<17,R![-42, 1]>],Snew);
    return Vf;
end function;