
// Make newform 675.4.a.b in Magma, downloaded from the LMFDB on 17 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_675_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_675_4_a_b();".
// 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_675_4_a_b();".
// 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_675_a();"
function MakeCharacter_675_a()
    N := 675;
    order := 1;
    char_gens := [326, 352];
    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_675_a_Hecke(Kf)
    return MakeCharacter_675_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], [0], [-10], [80], [7], [-113], [-81], [220], [-189], [-170], [130], [-10], [160], [631], [560], [229], [-750], [-890], [890], [-27], [429], [750], [1480], [1500], [460], [-420], [-607], [2170], [1610], [-2370], [1797], [-124], [70], [2248], [-1010], [-590], [2403], [801], [2360], [1241], [4990], [2260], [-2247], [4564], [4949], [-3890], [2453], [-6213], [-3450], [-6490], [-3401], [4980], [3357], [-4540], [-8410], [259], [4170], [1740], [5070], [-159], [-6490], [8220], [4660], [-6817], [192], [-4840], [-860], [5377], [-8010], [-12930], [6000], [140], [6217], [4551], [2310], [2900], [-2250], [-11263], [6910], [-5249], [11880], [4280], [6463], [11721], [2180], [17840], [2250], [-1230], [5813], [6750], [6610], [4990], [1483], [-11641], [-2620], [13690], [10220], [-2778], [12830], [-4950], [6540], [15240], [-5281], [10510], [4107], [26129], [4360], [-16639], [-490], [-18400], [7827], [-19756], [9829], [6000], [-8280], [-16637], [19751], [-14260], [22318], [-20040], [-2310], [-26739], [5101], [-26030], [-3854], [870], [-35780], [3400], [-683], [-13400], [-23219], [-19630], [-2940], [-13987], [19839], [38390], [-28027], [-8630], [-1932], [18090], [-12890], [14887], [12666], [-43820], [-19320], [-3653], [24373], [-17629], [21210], [-39340], [4240], [-15933], [6780], [24740], [-48344], [29650], [-10260], [16270], [-23103], [-32090], [42010], [-17490], [-22130], [40959], [61169], [-26190], [46103], [31709], [-49500], [19639], [-20640], [-15660], [17377], [-36960], [-52149], [-15060], [47410], [-43406], [28090], [-7940], [-16810], [-27850], [-3039], [28100], [-18180], [59060], [-32803], [40340], [70850], [-35669], [-30279], [-23080], [-40323], [36449], [-66791], [-52740], [-48510], [-56680], [58410], [31008], [-13470], [-46013], [11460], [89610], [-41416], [70009], [45060], [16628], [33040], [-27110], [15120], [-63380], [-43620], [-35839], [-90550], [-82440], [53867], [-27141], [21442], [85307], [10140], [7550], [-4567], [-4597], [51489], [-16010], [44090], [-76500], [-105690], [3163], [-4288], [-25090], [-61940], [-100863], [-20907], [50681], [-3330], [19530], [-12180], [-52929], [40490], [86193], [31110], [-20830], [62260], [95480], [-54916], [61081], [-56230], [-17890], [47493], [45333], [86699], [-20640], [-56219], [67480], [11523], [112600], [-98410], [107843], [-107353], [121140], [-99507], [110164], [-18040], [2350], [-39050], [-17030], [-40669], [-90550], [-4970], [-1293], [-9630], [-99080], [14787], [94737], [-10071], [80850], [-44800], [-139769], [2927], [-8409], [25860], [91260], [-115150], [157410], [16193], [124440], [56680], [3203], [134730], [-17370], [148450], [-16080], [-39061], [-79410], [-97680], [-44660], [-42450], [-66677], [-464], [-65091], [46669], [-18830], [146100], [-91717], [-171030], [-72630], [95061], [47520], [16260], [27880], [-92947], [-107753], [-1920], [106350], [55020], [-110250], [1769], [-62900], [-1240], [108020], [5091], [-141818], [151013], [26300], [-133440], [76549], [-118062], [10930], [-60424], [56000], [-91348], [86180], [40967], [-187969], [1658], [-119250], [-43900], [112583], [113640], [146709], [179530], [-146130], [178139], [-5920], [141480], [87617], [-162612], [102870], [173860], [-83020], [192726], [-8601], [65920], [6120], [-9390], [4879], [26900], [-161410], [51540], [233450], [-166880], [118640], [127107], [119010], [100538], [88230], [-199593], [223009], [-87210], [168171], [15260], [217550], [140070], [-175490], [170670], [-85690], [-137720], [-108759], [25580], [12107], [209904], [55240], [-227551], [-184400], [97710], [23400], [-54726], [153091], [-143530], [34990], [-53170], [-167630], [66293], [123660], [81649], [45360], [-230414], [-118710], [90200], [205430], [-137600], [-99041], [-251390], [-28610], [-231000], [-157860], [13050], [-257367], [100519], [218979], [137050], [154400], [69490], [-236800], [-197367], [-44971], [-14240], [-41830], [239037], [-253330], [77710], [-26663], [-220261], [35730], [127841], [192290]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_675_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_675_4_a_b();".
// 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_675_4_a_b(:prec:=1)
    chi := MakeCharacter_675_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_675_4_a_b();".
// 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_675_4_a_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_675_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![2, 1]>,<7,R![0, 1]>],Snew);
    return Vf;
end function;