
// Make newform 1176.4.a.i in Magma, downloaded from the LMFDB on 10 May 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1176_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_1176_4_a_i();".
// 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_1176_4_a_i();".
// 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_1176_a();"
function MakeCharacter_1176_a()
    N := 1176;
    order := 1;
    char_gens := [295, 589, 785, 1081];
    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_1176_a_Hecke(Kf)
    return MakeCharacter_1176_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], [-7], [0], [7], [52], [-72], [-20], [-48], [-243], [-95], [352], [296], [158], [142], [-375], [-279], [-246], [-730], [338], [542], [-305], [-1123], [426], [369], [-1270], [-1832], [-999], [-1666], [-1832], [-1931], [-979], [-486], [2630], [-1878], [2103], [-1404], [-1536], [3634], [-858], [-2420], [2672], [-1712], [-3395], [510], [-276], [3198], [5091], [3895], [6428], [-3824], [568], [-3535], [-4335], [-3574], [5466], [5815], [3237], [-3176], [-3282], [-2182], [-3021], [1304], [-6208], [-3337], [8637], [1940], [-5527], [9564], [918], [-11480], [3654], [10067], [8800], [1136], [-4290], [-862], [9140], [-14232], [10001], [10256], [-4502], [12356], [-862], [1365], [8931], [11228], [12151], [-18534], [17096], [2140], [13266], [-19183], [-21693], [19658], [-19436], [-3089], [-1950], [-13132], [2930], [19824], [-19169], [-7267], [-4892], [22126], [1097], [-9969], [6424], [17046], [18877], [13783], [18192], [-13054], [-7246], [2817], [15786], [17426], [25834], [27983], [-28296], [-21254], [-28259], [-31779], [-9747], [24512], [14325], [12078], [10658], [-19099], [-1406], [6730], [-1166], [-16967], [11878], [-27324], [11971], [338], [-14114], [-1563], [-31568], [-2626], [361], [-29544], [24163], [39196], [-6528], [-1046], [-32910], [-22682], [-7450], [10080], [32958], [-19784], [11480], [-45352], [-39906], [17528], [-17066], [30821], [-4179], [9776], [14778], [8759], [33579], [42634], [-29148], [-44797], [-10654], [-3505], [-29331], [-20799], [-14542], [14460], [-37363], [-20713], [10452], [8698], [48707], [52704], [-25850], [-58673], [37791], [16766], [-61302], [13210], [4041], [39990], [42662], [-24581], [33212], [-42161], [42329], [-59060], [-30258], [-15717], [3942], [7622], [67086], [64034], [81534], [-3817], [-75320], [22770], [31254], [5888], [3211], [2448], [14953], [32928], [-16494], [-59326], [-27915], [-32137], [70959], [-33876], [-69890], [-363], [6144], [56106], [54566], [2360], [344], [70778], [45099], [46699], [-38112], [-52242], [69004], [45845], [49340], [68138], [-25128], [-7777], [-92410], [-34270], [-41692], [72637], [16243], [-110244], [7784], [9340], [-71456], [-22301], [-6694], [-101004], [660], [-84359], [97444], [56032], [-60288], [-4574], [8814], [14726], [-34370], [-1401], [125103], [-39806], [-31604], [46919], [78123], [73024], [79299], [106610], [-121124], [67102], [-7498], [-66725], [-50068], [-50940], [8107], [-976], [69078], [-49805], [-50159], [-92805], [-146000], [-56951], [6880], [-110618], [-119424], [44958], [595], [-122684], [-94076], [17694], [125536], [-96649], [78251], [63487], [133660], [65298], [-102993], [-61348], [1308], [-130052], [9181], [35216], [-24498], [63404], [93430], [-155766], [58211], [26489], [48315], [65906], [-106766], [115835], [-19678], [-145194], [53918], [31362], [32918], [74092], [-11216], [109128], [-67606], [160057], [-121560], [72107], [26200], [-137792], [-169982], [117115], [3520], [-93544], [110885], [-14170], [-73010], [105258], [-158369], [-100534], [50507], [101984], [47048], [67870], [-7604], [8700], [-172590], [-32593], [5299], [-94978], [97788], [-134949], [105925], [-150259], [-113779], [-11326], [-5934], [-120322], [20419], [166332], [67059], [-116050], [57783], [-134674], [-47690], [-168338], [-6327], [-99684], [29918], [148794], [68888], [105914], [-185252], [-104056], [-50325], [-59790], [123208], [-76815], [-195087], [4144], [-93202], [112789], [-30368], [-145168], [-87336], [-228084], [-18507], [191262], [134306], [95214], [-168618], [138192], [-201060], [-172122], [-36138], [-148496], [-12204], [-109748], [121060], [-69415], [-104146], [-78021], [7402], [-198490], [-77793], [98863], [56278], [-142832], [-28877], [-10780], [105552], [-84132], [230206], [238847], [98939], [-20706], [83514], [161558], [-99243], [170881], [123471], [166245], [-132630], [241130], [32519], [-281116], [224504], [-80976], [242262], [175887], [-121918], [-147630], [-231779], [248166], [163466], [184153], [-75672], [86274], [-184308]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1176_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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