
// Make newform 588.4.a.i in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_588_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_588_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_588_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
        poly := [-48, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rfbasis := [Kf.1^i : i in [0..Degree(Kf)-1]];
    inp_vec := Vector(Rfbasis)*ChangeRing(Transpose(Matrix([[elt : elt in row] : row in input])),Kf);
    return Eltseq(inp_vec);
end function;


// To make the character of type GrpDrchElt, type "MakeCharacter_588_a();"
function MakeCharacter_588_a()
    N := 588;
    order := 1;
    char_gens := [295, 197, 493];
    v := [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_588_a_Hecke(Kf)
    return MakeCharacter_588_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, 0], [3, 0], [6, -1], [0, 0], [-6, 7], [5, -5], [48, 4], [35, -3], [48, -20], [132, 11], [191, -20], [-25, 45], [-90, 18], [359, 3], [-90, -36], [252, -9], [60, 53], [-286, 40], [17, 77], [822, -44], [581, 53], [761, -62], [-654, -101], [-1008, 42], [266, 29], [186, -184], [-457, -111], [72, 207], [77, -31], [762, 110], [1127, 106], [6, 335], [276, 2], [-1, -181], [-2268, -78], [752, -301], [650, 402], [1484, -96], [-2370, -4], [312, -490], [630, 246], [2873, -209], [-3402, 18], [-2581, 378], [-1536, 202], [-496, -132], [-1684, -378], [848, 609], [-5850, 57], [1193, 107], [-3066, -434], [-1206, 618], [350, -903], [-216, -327], [-4374, 336], [5724, 54], [-5682, -379], [1712, 55], [-5095, -393], [-2868, -722], [-1129, 971], [-648, -177], [-67, 143], [-8346, 194], [-2425, -526], [-4248, 735], [-307, 543], [-2707, -164], [3312, -372], [842, 200], [-6894, 582], [-6996, 326], [-127, -840], [203, -883], [2753, -169], [6780, 274], [1410, -1516], [-925, 385], [3564, 540], [5357, 450], [1242, 726], [2549, 1225], [-270, -174], [5327, 1359], [-256, 1471], [4836, -791], [-3522, 626], [10157, -598], [-3900, -346], [7817, -1081], [1986, -406], [6636, 490], [7361, 468], [6588, 249], [12767, -397], [-3798, -354], [-8118, -1671], [1836, 2322], [-3067, 3], [-2239, -491], [5492, 760], [-5754, 1007], [13170, -221], [13590, -1446], [767, -797], [-1729, -1744], [-7584, 2359], [-10566, 1194], [4212, -426], [3311, 156], [-16927, -116], [9002, -1790], [-5046, -1856], [-9055, -151], [-15400, 1845], [9264, -1550], [-10153, 1527], [8766, 264], [-342, 2091], [732, 1324], [6683, -1417], [6695, 582], [7020, 1581], [-22500, 303], [-4303, -2001], [-21792, -49], [-19882, -984], [17442, 552], [-19363, -166], [16805, 397], [14771, 2503], [-5130, -4176], [-13813, -1814], [10514, -2744], [3360, -1208], [3407, 1166], [870, -2020], [-16936, -1178], [-15912, 1305], [32766, -262], [15488, 3698], [-15270, 553], [-15664, -3928], [-12618, 1263], [-12451, 491], [21036, 3328], [-20953, 615], [-25920, 2886], [-10648, 2094], [-8058, 2852], [-18094, 686], [22536, 1926], [-22663, -297], [15714, -1518], [16889, -3245], [-24696, -3330], [-21271, 2183], [-6498, -6132], [22439, -5004], [2508, 3221], [6306, 14], [-7044, -2426], [6077, 3606], [-8244, -3129], [32526, 2868], [27468, 1104], [-10537, 3408], [-5257, 3039], [10397, 666], [4464, 1833], [-20640, 3623], [-37738, -700], [-1404, -3012], [33581, 3496], [25259, -4502], [-2640, 5468], [9353, -8147], [-14910, 967], [36728, 576], [27323, -4221], [44219, -2192], [10704, -3233], [50549, 2225], [-6060, -826], [6918, -3928], [7308, -5151], [20630, -92], [18989, -411], [46481, 970], [33750, -2838], [26609, 4736], [50238, -2631], [-21784, -6688], [-53700, 2794], [4572, -5319], [-15576, -1922], [-13357, -5613], [-28426, -1516], [-13662, -7692], [41508, -546], [39510, -4041], [2273, 4015], [40238, -1632], [-8494, 8032], [-56862, 2766], [-26910, 4101], [5048, -4512], [10386, 237], [43452, -1392], [20348, -894], [20423, 6699], [-15816, -4279], [-6244, -137], [-19380, -1693], [-3708, 6012], [1919, -6045], [-9784, 5225], [-29364, -8576], [-32172, -5462], [14970, -5024], [6353, 7967], [-32125, -6379], [1314, -5160], [48032, -5785], [-36666, 4917], [-10846, 3414], [-4776, -866], [24126, -5434], [3809, 8062], [-39762, -2154], [-40039, -4067], [-6292, -1924], [-7159, 698], [-19170, -1068], [-16549, -5973], [-19458, -7062], [-57955, 5678], [-58194, -5181], [30060, 7752], [-17562, 8006], [-19014, 4954], [29123, 6765], [-61885, -786], [-74410, 1276], [-18456, 3040], [36900, -2712], [71789, 6214], [-56922, -2954], [-29176, 6984], [47304, -24], [-9679, -7447], [-79272, 426], [64566, 1140], [-15139, 13445], [-20112, 13195], [-56040, 6265], [-18043, -5367], [-20419, -593], [-13206, -11047], [110702, 2871], [-4819, -661], [51864, -1219], [47825, 3701], [91727, -1723], [-107154, -1188], [30875, 4775], [-54702, -1185], [73338, 4574], [-676, -1000], [-78210, 6483], [-53089, 1249], [130868, -870], [-22435, -3128], [51545, -5844], [-23590, -9997], [30620, -7868], [17310, -5519], [-1141, -10079], [-30397, 4835], [-53208, 13176], [58536, -7614], [-121903, -362], [7038, -4542], [79787, -8223], [25148, -2162], [-5046, 12346], [69737, 1390], [-13650, -7757], [-44341, -6462], [61794, 4194], [-105228, -2166], [-4428, -19077], [-19530, 7758], [-34284, -5464], [-37297, 18297], [-19530, -3885], [-41425, 1305], [-81180, 10794], [-53766, -3366], [36077, 13825], [-111298, -6232], [38898, -6825], [82916, 785], [34884, -6279], [-25441, 3207], [-3835, -20499], [125790, -6025], [-133867, -3711], [30864, -5198], [-67609, -2769], [-5076, 6342], [-45534, 9848], [78810, -6010], [-27856, 20688], [-38280, 4460], [-3727, -12747], [-99954, -8709], [67200, 9500], [-88903, 1596], [29898, -2802], [-73, -4575], [18095, 13019], [31518, -4623], [67577, 2663], [-38874, -11830], [-90223, 6402], [-46171, 1269], [-697, 6371], [68340, 7978], [70374, 14431], [-14227, 6033], [3990, 4843], [-149065, 5641], [55398, -1646], [45833, -4771], [-114546, 12878], [41906, 20014], [44988, -24334], [-22555, 11916], [91139, 9782], [-68749, -4041], [87696, 5544], [21456, -11097], [39035, 7870], [-3834, -13167], [-13662, -14439], [45557, 20361], [62156, 3270], [120978, -4500], [30978, -4203], [-159580, 9564], [125738, 5001], [-119286, 4776], [11264, -12203], [109187, -14545], [13314, -5096], [-25950, 25376], [127692, 9165], [64272, -2276], [-46086, 8704], [96674, -7156], [-20346, 178], [89106, 5828], [147414, 4150], [-84997, 9929], [-100666, -6531], [99720, 11850], [69791, -4919], [-139090, 8843], [-63204, -20069], [102455, -8695], [70470, 10188], [67470, -27127], [-68575, -13873], [-82459, 9119], [-167832, 9024], [-162888, -4496], [-122386, 18893], [88068, 20554], [737, -6915], [-81504, -17130], [33756, 13250], [-44824, 4568], [91980, 16140], [-167404, 11498], [57372, -29794], [-138799, 16719], [-164218, 5150], [22505, 5303], [7338, 9094], [-52615, 23736], [195102, 6648], [-137508, 12841], [159653, 9741], [-37866, -18964], [16634, -33899], [-119668, 15089], [-9438, -12548], [86933, -12785], [-64626, -20117], [-134314, 8298], [-214884, 11256], [-10720, -23644], [100842, 9476], [18378, -639], [122975, -9798], [118742, -808], [-149868, -10698], [-19825, -3561], [105060, -19127], [-43102, 20693], [107436, -13991], [-32352, 18523], [-17188, -22622], [-83815, 26697], [-170862, 7033], [-52818, -10298], [-16465, 23105], [86220, -19944], [181104, -15910], [101064, 7837], [219131, -8805], [-99816, 9946], [14742, 903], [-93562, -300], [-33366, 11768], [93966, 3113], [792, -29052], [109436, -15590], [38280, 10612]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_588_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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