
// Make newform 450.4.a.j in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_450_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_450_4_a_j();".
// 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_450_4_a_j();".
// 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_450_a();"
function MakeCharacter_450_a()
    N := 450;
    order := 1;
    char_gens := [101, 127];
    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_450_a_Hecke(Kf)
    return MakeCharacter_450_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], [26], [28], [12], [64], [-60], [58], [-90], [-128], [236], [-242], [362], [-226], [108], [20], [542], [-434], [1128], [632], [-720], [478], [490], [1456], [578], [1462], [-966], [370], [528], [-1534], [-12], [1224], [3100], [-250], [2152], [-524], [-3518], [534], [-4252], [-2500], [-2578], [768], [-2608], [-5116], [-3480], [3132], [62], [5314], [-190], [2408], [5680], [-278], [-3252], [-1536], [4858], [-2610], [-5168], [-1924], [-3042], [-1718], [-2292], [5406], [5688], [7352], [3484], [-7868], [656], [5754], [-3110], [7808], [9240], [-3214], [-348], [4940], [-6142], [-3050], [5396], [-14482], [-1090], [7180], [-8138], [208], [12992], [1080], [9078], [-14310], [-2344], [-11382], [16062], [-17166], [-7520], [-11814], [-14052], [7620], [1818], [-17850], [19238], [-6278], [-9818], [-12514], [-10596], [-14002], [7330], [5812], [16736], [7434], [-25872], [3720], [-12958], [-7214], [-4828], [-27656], [-21220], [17672], [-7322], [-8238], [-6426], [5908], [26780], [-24538], [-28848], [26884], [-14282], [-3428], [-26942], [-1950], [-12080], [17226], [-788], [-2060], [3258], [-4528], [18236], [18678], [27390], [-9252], [5726], [-27236], [-10950], [-8828], [16058], [41862], [12154], [-15390], [4280], [14452], [22584], [-26740], [498], [-13244], [-40842], [-12078], [18294], [22566], [6768], [22200], [6330], [-19544], [9898], [-41406], [-25432], [12106], [-7812], [-12576], [-4342], [26272], [44796], [24110], [54348], [-45900], [53382], [-11192], [35032], [51280], [-25590], [-16108], [46338], [-51658], [1010], [16226], [-56332], [-56828], [3864], [-60382], [34830], [-59404], [51442], [-50290], [40448], [-44448], [25798], [13372], [-45342], [-63726], [-24312], [12042], [24252], [-31296], [48458], [54390], [-26448], [396], [11710], [-40220], [-4596], [-46560], [-32882], [37850], [30532], [-16544], [6138], [-78218], [-7686], [-15880], [-20558], [-18734], [-23122], [70694], [-14972], [26262], [-60680], [-44190], [65422], [26274], [-68070], [27928], [15680], [-20054], [29788], [-28148], [-61820], [-26368], [3918], [23882], [-43346], [112950], [-45652], [-34380], [48168], [98718], [-94348], [-3898], [20170], [-5552], [97320], [8226], [-15372], [104540], [48898], [-93084], [-88802], [84614], [13390], [-28252], [-58500], [-13298], [52966], [117524], [64936], [66222], [-106046], [83170], [-63188], [75504], [-83980], [-101610], [82198], [80522], [-28212], [15542], [-59954], [24712], [43840], [119216], [135862], [14954], [-91270], [105842], [-135132], [110418], [48632], [-50746], [-79778], [-22634], [60688], [-18528], [34484], [108920], [128410], [104338], [153954], [132408], [-61572], [83612], [135870], [89952], [7548], [25300], [-22914], [116872], [61884], [19280], [-12162], [2132], [-112624], [-117286], [25130], [-138040], [-124428], [-166542], [120270], [71838], [-163518], [-28106], [-44890], [95900], [-2272], [-34048], [-21270], [-68548], [117736], [152898], [-64498], [-42312], [-39958], [81300], [-84438], [114094], [-72932], [-24338], [52684], [148160], [47438], [-145788], [136554], [-46430], [-161472], [136402], [-81214], [-85308], [-159976], [-203210], [-26248], [41908], [196620], [185142], [127126], [132848], [-57036], [-208468], [-150984], [-92142], [108462], [-199630], [-98952], [96960], [-213732], [-93056], [-54422], [68636], [-194682], [-1266], [-60140], [95886], [178232], [-84756], [111942], [44802], [-25612], [-175300], [135778], [-66810], [52872], [-46044], [-81860], [16928], [-89568], [-195990], [-202904], [94458], [-25192], [-66374], [-16096], [-70860], [263178], [167952], [214876], [67242], [-198866], [63110], [133068], [-100380], [180526], [-105352], [-101608], [133280], [-132550], [-106108], [10458], [-61790], [-154352], [102226], [206424], [-229770], [50552], [262356], [159438], [181762], [30540], [-125648], [152964], [-110922], [193132], [5576], [-17942], [184480], [-25014], [-137216], [222858], [138270], [86716], [266494], [171540], [26152], [248124], [72638], [-172510], [158292], [281320]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_450_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_450_4_a_j();".
// 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_450_4_a_j(:prec:=1)
    chi := MakeCharacter_450_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_450_4_a_j();".
// 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_450_4_a_j( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_450_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<7,R![-26, 1]>,<11,R![-28, 1]>,<17,R![-64, 1]>],Snew);
    return Vf;
end function;