
// Make newform 2160.4.a.y in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_2160_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_2160_4_a_y();".
// 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_2160_4_a_y();".
// 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 := [-60, -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_2160_a();"
function MakeCharacter_2160_a()
    N := 2160;
    order := 1;
    char_gens := [271, 1621, 2081, 1297];
    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_2160_a_Hecke(Kf)
    return MakeCharacter_2160_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], [0, 0], [-5, 0], [3, -1], [-2, -1], [-9, -6], [24, -7], [-29, -11], [-42, -17], [58, -13], [44, 19], [-131, 5], [-54, -10], [48, 25], [4, 7], [258, 50], [252, 24], [-85, -5], [137, -73], [10, -46], [-501, 79], [203, -30], [558, 36], [-8, -132], [-637, -69], [36, 59], [879, 11], [-374, 0], [-690, -154], [-114, -33], [440, 110], [944, -157], [866, 40], [1769, 121], [824, 301], [1223, -266], [-1434, 61], [1247, 26], [368, 380], [980, -410], [990, -34], [-775, -57], [1008, 218], [-2939, -163], [2444, 36], [201, -378], [2757, 93], [1384, 272], [550, -526], [-2026, 214], [-1312, 350], [2694, 24], [913, -356], [2354, 503], [3412, -175], [2220, -264], [-1440, -81], [-1905, 157], [3106, 636], [824, -46], [1708, -956], [4642, -176], [-1028, 121], [3700, -420], [4513, 315], [6164, -220], [-6071, 61], [-3241, 53], [-6, -666], [3455, -805], [-424, 967], [1530, -598], [-8077, 87], [-2543, -950], [-4441, 93], [6516, 497], [-1800, -447], [3578, 303], [4018, -286], [-4999, 734], [9000, 203], [9845, 43], [-3086, -162], [7722, -8], [-12352, -120], [3724, 728], [-6840, 34], [6110, -1162], [10304, 1106], [2983, 31], [-15536, 300], [8702, -98], [-5077, -1259], [11526, 350], [-520, 500], [-1382, -565], [3166, -469], [-11442, -1018], [1273, -358], [9957, 617], [-9753, 842], [8184, 284], [9308, 262], [-13428, 932], [-1689, 503], [9497, -1645], [-5486, 1784], [-14238, -1105], [16798, -824], [9146, -777], [11639, -953], [7429, 676], [11078, 9], [-14201, 735], [655, 1285], [-5040, -1794], [14408, 1681], [-26238, 714], [3308, -752], [4760, -3336], [-8133, -1637], [14305, 1501], [7952, -1892], [-9610, -2150], [1916, -2778], [-9174, 2171], [-16267, 515], [2286, 2544], [1832, -748], [2746, 4168], [-956, -536], [7168, -169], [7351, -3838], [-5105, -520], [-2746, 5000], [-12165, -228], [-13674, 896], [7925, -1592], [39856, 124], [-38808, 312], [2116, 1310], [17180, -454], [23925, 1627], [-35712, -158], [-24935, 1327], [15260, 3918], [-3775, -4072], [-3982, 3080], [-22435, -1235], [-22100, 3075], [-8795, -3138], [-50302, -148], [35291, -1299], [-26292, -813], [1649, 2952], [-29208, -2384], [-7244, 1897], [-41574, 1290], [1449, 4301], [6238, -3677], [-16596, -338], [-36320, -109], [16941, 2653], [-2580, -5195], [-7286, -5885], [19438, -1417], [6833, -4246], [-6894, 4209], [-27011, 772], [5892, 5166], [22490, 1397], [14746, 2800], [1452, 1046], [1211, 1661], [-14283, 694], [-5350, 4894], [22388, 2128], [-28310, -4468], [5797, -6049], [-31910, -3224], [15745, -4829], [-25412, 3796], [26878, -195], [-19356, 2073], [-7900, -2468], [-22110, -2696], [-26201, -5426], [57655, 738], [-27499, -2155], [11092, 5138], [2251, -6273], [-9528, 582], [20013, 2147], [51220, 395], [-51084, 2696], [-27986, -6132], [37907, 3863], [26267, 2378], [-32866, 4096], [-3738, 7474], [24940, 5583], [21307, 2325], [20035, 5799], [-36963, 101], [-34866, -3475], [52850, 1186], [-24865, 2456], [16890, -5708], [-29970, -5016], [-6397, 7293], [12745, 2851], [41424, 1459], [42289, -3857], [5726, -7080], [14766, 584], [6603, -2252], [-44636, 4966], [6530, 2244], [-49386, 3517], [24078, -8280], [63317, -3117], [-72424, 1115], [-3764, -7600], [31928, 5684], [7042, 2772], [14307, 2443], [-20364, -1515], [-14430, -3204], [-2113, 6909], [-55644, -207], [39395, -8505], [-35972, -1638], [-16076, -3447], [-26942, 1480], [30271, -3463], [82920, -1020], [11549, -9442], [43208, 4456], [24346, 4974], [36380, -3268], [-22442, 3290], [13547, -7987], [-30383, 665], [-11809, 8331], [6248, 9906], [62790, -3606], [-18703, -4503], [45036, -7809], [-72196, 5050], [-28094, -11585], [93438, -2591], [-59772, 2136], [13584, 2728], [-2147, 1417], [21278, 6276], [-19548, 13761], [42461, -85], [-5540, 2899], [26578, -4984], [13858, 1996], [9647, 6393], [49602, 9632], [-57107, 5649], [30417, 7352], [27780, 11119], [-22804, 14532], [76854, -4892], [64566, -7294], [-14528, -10127], [66444, 3976], [58047, 1385], [30491, 7060], [35098, -2760], [-92797, 3852], [56518, 4916], [59827, 1025], [38382, -9966], [-86710, -4406], [-29414, -14473], [-79350, -483], [-68214, 9441], [-29336, -3017], [123510, -4025], [53795, -5911], [15311, -882], [57236, -7946], [24627, 3609], [-7920, -7538], [6549, -6178], [52526, 7228], [91322, 5193], [-24730, -8546], [41550, -2247], [57852, 8008], [30590, -424], [51216, -10250], [73133, 7911], [50796, -10182], [-4638, 7767], [7265, -8689], [-45239, 5427], [51234, -2258], [-65688, -10909], [-17064, 1662], [88217, 10741], [4342, 5812], [149596, 1294], [-35635, 13309], [-83520, -7778], [23225, 5802], [30444, 13001], [111388, 7442], [113050, 5772], [18119, 12582], [93766, 7207], [-38370, 10357], [-8820, -9521], [-59450, 6362], [-14522, -10810], [11158, 12164], [23835, -11795], [41301, -18417], [-20354, -1105], [97888, 5348], [17142, 3983], [6925, 17420], [16600, 4468], [25724, -13816], [110998, -3745], [34218, -13958], [-30715, 18269], [-76422, 8620], [6847, 5098], [-43302, -5380], [1652, 2136], [57978, 1700], [-47989, -17015], [-27858, -4488], [-109626, -4271], [56544, 12414], [81605, -8002], [-128726, -2245], [59406, -2284], [15147, 23368], [15288, 3668], [-112844, -7773], [-62350, 12], [-26484, 9800], [-56940, 14608], [43726, 13388], [75951, -15743], [49187, -16279], [-58712, 22961], [77056, -4062], [-206033, -3071], [80618, 5949], [-116946, 13854], [152802, 9293], [-107590, -11451], [-21046, -19777], [-99791, -9119], [125544, 6756], [-44166, 2874], [-53332, 19779], [5419, -2138], [44937, 6491], [-137012, 13256], [-10333, -13573], [23799, 3236], [-170692, 955], [-77915, -6711], [-162632, 99], [-60406, -12384], [68609, -3445], [-102049, 9836], [-69990, -10503], [90444, -15792], [65033, 1075], [131166, -11628], [147179, 891], [92116, -20791], [-16310, 11869], [-61943, 6275], [-180566, 8909], [-45509, 4011], [5408, 17991], [-150824, -4968], [-43309, 17971], [-49673, 26134], [-181696, -8949], [122366, -10373], [-74168, 5278], [-47534, -23934], [-87775, 1176], [-93278, -13038], [-107309, -6367], [136331, -6567], [6408, 4276], [-25284, 4930], [-109038, 9785], [-206294, -6798], [62162, -6863], [141944, -4388], [-38766, -21395], [74004, -6330], [-99644, -14204], [-21797, -1584], [60390, 8700], [93607, 9337], [-247478, 3443], [149950, -772], [-184508, 1538], [74776, 15330], [-82147, 10665], [82875, 10823], [-192238, -1104], [-75876, 26586], [-181783, 9107], [100570, -3220], [-103090, -1925], [-26642, 10287], [35394, 18280], [64064, 20953], [24396, -2635], [113170, -5892], [-149340, -8934], [-106786, 27482], [20866, 8174], [-20744, 4198], [113062, 5912]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2160_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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