
// Make newform 1440.4.a.ba in Magma, downloaded from the LMFDB on 30 December 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1440_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_1440_4_a_ba();".
// 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_1440_4_a_ba();".
// 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 := [-50, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-2, 4]];
    Rf_basisdens := [1, 1];
    Rf_basisnums := ChangeUniverse([[z : z in elt] : elt in Rf_num], Kf);
    Rfbasis := [Rf_basisnums[i]/Rf_basisdens[i] : i in [1..Degree(Kf)]];
    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_1440_a();"
function MakeCharacter_1440_a()
    N := 1440;
    order := 1;
    char_gens := [991, 901, 641, 577];
    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_1440_a_Hecke(Kf)
    return MakeCharacter_1440_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]];
    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], [-2, -1], [20, 0], [-12, 1], [-16, 3], [-58, -1], [-6, -1], [-74, 4], [-38, 9], [140, 5], [-286, -2], [-260, -4], [-170, 13], [-262, 6], [-276, 8], [314, -22], [-84, -20], [-624, -8], [454, 18], [526, 7], [20, -16], [-414, -30], [-158, -56], [-946, -28], [38, 7], [336, -30], [910, -20], [-960, 15], [-138, 27], [544, 58], [1868, 1], [-1150, 25], [-1130, 60], [-190, -95], [-1160, 35], [-2484, 8], [-2998, -29], [2598, 56], [168, -74], [1206, -124], [-2488, -76], [-250, 150], [3722, 14], [2810, -15], [-2246, 33], [-1366, 17], [-1500, -32], [2954, 90], [-2644, 117], [-1652, 26], [-2454, -108], [-5888, 34], [2384, -57], [-3106, 17], [-570, -140], [-5798, 69], [-3112, -189], [-1606, -82], [5452, 8], [114, -222], [-352, -166], [-140, -270], [198, -294], [4586, 82], [2626, 137], [-5522, 186], [-2760, -118], [9778, -82], [-7332, -199], [-8, 204], [-1230, 297], [8104, -57], [-1890, 15], [6262, -95], [-4882, -24], [1460, 5], [558, 172], [4730, 240], [11184, -82], [10810, 90], [4624, 268], [734, -22], [8882, 69], [-11796, -88], [-8690, 220], [-8838, 264], [-7146, 64], [-6098, 215], [1296, -366], [1896, -288], [11642, 81], [-10292, 176], [2498, 341], [13414, -23], [1422, 16], [-10410, -76], [14392, 198], [-3442, 260], [5164, 520], [3038, -524], [312, 750], [-8130, -520], [2218, -179], [2362, -436], [7096, 110], [12984, -317], [-10680, 100], [-4262, 336], [6442, -799], [764, -187], [8124, -347], [6338, -199], [-17562, 271], [-2838, 14], [708, 260], [1578, -121], [6510, 60], [23012, -16], [-7526, -442], [-8186, 718], [14582, 524], [5600, -946], [-10566, 453], [6150, 100], [-2062, 54], [-11380, -50], [33058, -91], [-13368, 319], [-11606, -447], [-1062, -373], [-10214, 777], [-7088, 239], [-218, 268], [1698, -296], [6946, 642], [31456, -226], [-34050, -20], [-558, 1406], [-19478, -591], [17206, -768], [17094, 67], [13868, 668], [-11938, 604], [-13392, 616], [30676, 537], [-6360, 835], [-4810, 675], [20882, 275], [1624, -1117], [7442, -706], [-5900, 844], [-5246, -65], [14696, 150], [-15220, 1010], [-718, 649], [2598, -1304], [28954, 448], [-13570, -4], [6064, -690], [5164, -367], [33370, 437], [-50664, 102], [-19728, -1061], [-3622, -1605], [-39266, -257], [36648, -689], [-70, -988], [-250, 60], [20964, 1348], [-5642, -1148], [8688, 1036], [10550, 930], [28950, -565], [-17478, -754], [-33874, -173], [-13154, -464], [-39134, -759], [-52202, 236], [-2562, -1437], [-3940, 200], [-2216, -77], [14952, -2001], [-25266, 1389], [18982, -1668], [-16956, -367], [12120, 1374], [-28646, -1152], [-60672, 136], [20518, -994], [-33688, 518], [-41494, 217], [15870, 620], [-22428, 1452], [-1880, 655], [17810, 1160], [-62588, -271], [-8184, 2507], [-25142, -1005], [39726, 1220], [-10514, 1147], [-18812, 621], [-4462, 2288], [-5704, 1582], [-55214, -1218], [-50582, -699], [9952, -30], [-8110, -1982], [28638, 591], [56670, 690], [-30266, 428], [-18538, -1785], [30436, 1880], [13132, 2394], [-24134, -1808], [26666, 405], [20278, -848], [19230, -1023], [18150, -1280], [-21974, 962], [13538, -2739], [47090, -1118], [-37794, 1343], [-72096, -94], [4854, -1032], [-7224, -2433], [17788, -234], [-1506, 955], [-23448, 1874], [-49988, -1291], [68130, -1215], [19786, 597], [-14078, -526], [-32456, 2502], [3594, 2395], [-6950, 1540], [13854, 1928], [12408, 86], [48768, -2144], [-78320, -1246], [-59998, -111], [57998, 895], [1050, -182], [-11636, -1247], [1876, -178], [-27862, 2469], [15060, 3080], [77134, -117], [-4470, -1801], [-49656, 2023], [49590, 204], [10814, 2141], [5298, -3724], [-22014, -1898], [-100868, 404], [57358, 440], [-38904, 570], [-82830, -1670], [2574, -2962], [60874, -2023], [15400, -2662], [83818, 1538], [52724, 213], [96028, -499], [52434, -2307], [-29346, -1004], [-93146, 592], [-29320, -2394], [36606, -368], [56494, 2664], [9184, 1586], [51118, -354], [21822, -3001], [52406, 142], [-50098, 1083], [86448, -1802], [59866, -646], [-28238, 2844], [44152, -706], [-15882, -1483], [-16866, -97], [20714, 151], [61254, -2768], [-12024, 14], [-22064, -3328], [104106, -428], [46038, 356], [-35170, 2715], [-72874, -1588], [69318, -704], [-3900, 1268], [-54996, 253], [34560, 190], [17516, -223], [-66642, 2316], [121654, -297], [-18974, -1038], [89904, -502], [4732, -3288], [-56506, -62], [-9954, -828], [-71086, -2467], [120072, 1530], [83662, -1481], [-40094, -1088], [3060, 52], [73322, 1622], [65828, 3846], [16744, 5423], [-121278, 1315], [-23410, -1492], [19526, -1792], [-6200, 274], [-47274, -331], [-64726, -3000], [-38504, 582], [-28820, -3970], [-48602, 3686], [-15890, 1400], [61502, 319], [-74106, -2022], [-49258, -4236], [98578, -263], [-122904, 1547], [-6350, -3960], [-66286, -1407], [-86884, 2388], [48138, -2961], [63406, -1448], [-52958, 2034], [-7178, -2216], [-58110, 3105], [33504, -1858], [57094, 4223], [95820, 1288], [23782, 2764], [46340, 5], [-115486, -332], [-74034, -745], [96536, 1207], [112584, 2323], [-6666, -272], [42910, 215], [114922, 274], [47300, 1740], [67178, 3306], [-55796, -544], [-42900, 2790], [-23942, -1074], [-110330, -2265], [-85766, 1128], [59286, 4052], [-48926, -3851], [50034, -5830], [103476, 2257], [25480, -2060], [-72728, 1314], [88228, 1721], [-58794, -3467], [-23792, 691], [-111218, 2948], [110202, -1313], [15144, 3438], [-95012, 4348], [-195142, -984], [88962, -2746], [-8270, 2021], [-45006, -4292], [85224, 378], [-124682, -3029], [6750, -4411], [143022, 3724], [-17878, 4189], [-47776, 5363], [-134844, 1172], [-53100, 2110], [74154, 4188], [-147498, -2136], [187418, -184], [16854, -5608], [19404, 1233], [-118210, 567], [9036, 2457], [50362, 7869], [59670, -2539], [-26390, -1935], [132520, 1515], [-149240, -134], [-19046, -1909], [970, -740], [244854, -772], [-182108, -3116], [-55584, 4310], [15576, 3472], [42730, -6360], [-129810, 435], [-214358, 746], [226142, 479], [-2898, 64], [-13290, -420], [-59100, -4295], [-126346, -4285], [-40748, 3709], [-21106, 4468], [5574, 1343], [36688, -309], [-72274, -964], [52044, -536], [-52848, 2534], [-22958, 344], [-47274, -2588], [-98736, 694], [39570, 8545], [-442, -3374], [81646, -4032], [49392, 4264], [-65666, 311], [-72332, 3321], [-13590, 1711], [80462, -1876], [63728, 531], [-15726, -1749], [-212708, 3284], [91278, -4674], [-166182, 506], [-174604, 1688], [176078, 2396], [148694, 2283], [-3192, -5684]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1440_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_1440_4_a_ba();".
// 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_1440_4_a_ba(:prec:=2)
    chi := MakeCharacter_1440_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_1440_4_a_ba();".
// 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_1440_4_a_ba( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1440_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<7,R![-800, 4, 1]>,<11,R![-20, 1]>,<17,R![-6980, 32, 1]>],Snew);
    return Vf;
end function;