
// Make newform 1344.4.a.u in Magma, downloaded from the LMFDB on 24 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1344_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_1344_4_a_u();".
// 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_1344_4_a_u();".
// 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_1344_a();"
function MakeCharacter_1344_a()
    N := 1344;
    order := 1;
    char_gens := [127, 1093, 449, 577];
    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_1344_a_Hecke(Kf)
    return MakeCharacter_1344_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], [2], [7], [-12], [66], [-70], [92], [16], [122], [64], [306], [50], [-20], [-176], [-526], [-540], [818], [228], [864], [106], [736], [588], [146], [-1214], [-846], [-168], [708], [-646], [1938], [224], [2588], [490], [1716], [2386], [-104], [-1566], [1076], [-2760], [-1558], [3452], [1162], [1928], [-318], [-4062], [5480], [-4892], [4320], [5516], [-1670], [-3926], [3640], [5650], [-4652], [-6006], [5040], [-5478], [-2176], [4658], [-4614], [-1244], [6354], [3740], [-2184], [4442], [4314], [-7988], [-10606], [8340], [10498], [-7878], [11856], [-5488], [7570], [13596], [-8592], [610], [-910], [-8094], [10122], [-4228], [9218], [9192], [-3614], [-4344], [-10876], [-15550], [7834], [-15990], [-12448], [-13860], [-14368], [-17240], [-18156], [-1084], [-1048], [-5046], [-3390], [-13052], [-16966], [11348], [-16118], [15244], [-18918], [19372], [-7230], [7396], [714], [-11536], [4138], [-6848], [12722], [-24726], [-23964], [-17224], [-18190], [-14116], [4056], [16490], [4988], [-4982], [-16190], [23202], [-13452], [-31220], [-33542], [28562], [1248], [-4216], [-12670], [-25996], [-24368], [17600], [-17182], [-7038], [-18254], [-2990], [-10804], [-11238], [35034], [9252], [-18318], [30200], [-9612], [-3806], [-19176], [38234], [34818], [15764], [-1832], [-18374], [40490], [548], [-1272], [15100], [53192], [-53624], [-28966], [50874], [-16566], [38428], [746], [9432], [-3452], [-18078], [792], [-14976], [17114], [1170], [26866], [-29324], [53442], [-1728], [-46406], [-8640], [52258], [17308], [-10782], [-15032], [29090], [-27584], [70604], [-57262], [26642], [-14568], [-11310], [26074], [-46340], [-22086], [69360], [45746], [-66780], [67012], [13338], [700], [-13998], [27154], [-40790], [24170], [48872], [-1270], [40608], [56602], [-78062], [-57276], [-65334], [80240], [-40404], [-70406], [29732], [50514], [-19086], [68152], [6612], [60424], [-37302], [2832], [-58982], [3360], [34330], [-10446], [51064], [57250], [-10368], [31852], [10786], [51474], [-70616], [-45560], [-35388], [-67750], [33100], [-82304], [9626], [-41452], [27984], [21170], [100338], [9028], [-12840], [25772], [90772], [-82504], [56810], [47706], [69128], [49264], [24812], [-33060], [-122648], [-77894], [-28646], [18560], [73770], [-1190], [-25620], [-29630], [-11564], [-81390], [104922], [-6784], [69180], [-62166], [-7918], [115242], [-31892], [79210], [27458], [-39108], [49410], [46226], [62228], [-123142], [-20976], [11010], [-36232], [-30844], [-21190], [-75814], [-119748], [-71712], [-110584], [792], [99450], [-61532], [-81720], [109362], [-96590], [-114840], [19530], [75882], [69676], [-131366], [-127532], [-34262], [-73190], [-62496], [43682], [97140], [-69140], [-46678], [18570], [20064], [-160164], [82188], [-48286], [119652], [108434], [68864], [93922], [-177488], [-102862], [41522], [-167356], [-46736], [-45110], [7516], [70424], [-2606], [92994], [132940], [-54742], [166794], [161056], [-75878], [37874], [-175852], [-3292], [88824], [7650], [39882], [-30822], [9280], [138172], [127084], [-166780], [-7990], [55562], [-72502], [-154640], [-176526], [115578], [63474], [76472], [-73414], [51084], [-204262], [14924], [-45712], [44066], [37852], [74266], [-93366], [200544], [-144366], [5538], [-27216], [130532], [161682], [-53472], [23458], [-101310], [-137304], [153396], [-25380], [-14470], [102234], [91512], [-8630], [-92980], [44836], [-45576], [-170414], [-31496], [144474], [229516], [-98904], [24962], [28474], [-70934], [37978], [11962], [15784], [-184446], [198220], [122808], [77360], [50554], [-212996], [209120], [108002], [-57470], [-159132], [-177108], [220832], [52298], [-72752], [-236350], [-77716], [68754], [-28974], [-125630], [-123072], [-231486], [-25390], [-6712], [170794], [146738], [-190596], [924], [273618], [53490], [42548], [53204], [-228006], [38010], [-28360], [169528], [152826], [5048], [-60774], [133690], [161016], [-159324], [-103254], [298938], [99724], [240666], [-193628], [159080]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1344_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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