
// Make newform 1344.4.a.bp in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1344_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_1344_4_a_bp();".
// 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_1344_4_a_bp();".
// 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 := [-9, -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_1344_a();"
function MakeCharacter_1344_a()
    N := 1344;
    order := 1;
    char_gens := [127, 1093, 449, 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_1344_a_Hecke(Kf)
    return MakeCharacter_1344_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], [2, 1], [-7, 0], [-24, 1], [26, -4], [-6, 7], [-80, 2], [24, 5], [190, -6], [92, -18], [-42, 20], [26, -3], [192, -16], [32, 38], [326, 36], [-212, 22], [530, -6], [656, -30], [336, 51], [-542, 2], [-368, -38], [140, -40], [474, -87], [402, -26], [970, -37], [-60, 86], [656, 41], [986, -96], [-134, 92], [-1600, -18], [-268, -56], [26, -10], [52, -156], [1734, 60], [-904, -180], [530, 10], [8, 150], [1600, -158], [3162, 63], [-544, 79], [-358, 220], [240, -33], [2406, -40], [1878, -120], [496, 156], [880, -336], [-1216, -80], [-1956, 322], [3298, -56], [1210, 50], [2184, -243], [3034, 82], [-6900, -26], [706, -47], [-4400, -11], [-2590, -239], [-4668, -310], [-946, 80], [4146, 402], [2200, 382], [-670, 95], [3752, 234], [2120, 334], [7906, -24], [-1322, 192], [4600, 368], [-1438, -620], [-1976, -481], [-2902, -454], [-3198, -249], [2584, -5], [6856, 160], [-70, -464], [2120, 840], [-3688, -696], [2662, -742], [1938, 370], [-7230, -254], [-2478, -38], [-12276, 210], [7838, -104], [-11384, 271], [-9190, -268], [-8528, 620], [-2224, -233], [3282, 180], [-982, -136], [1746, 1007], [5864, -14], [-2604, 1146], [11112, -66], [-5128, -344], [-7504, -1], [2568, -1396], [2056, -1160], [3002, -259], [-9534, 947], [2804, 864], [-1418, -1792], [992, -114], [-2610, 600], [-10188, 146], [498, -42], [4752, 730], [-1470, -260], [-5964, 366], [-7446, -1605], [-15984, -777], [-15510, -124], [-2864, -340], [1498, 684], [1346, 422], [11820, -1520], [13384, 742], [-19206, -934], [-20616, -566], [1712, -1370], [-8098, 1770], [7144, 1517], [16914, 378], [-16562, -160], [6210, -513], [26720, 307], [-15340, -700], [-14082, -1194], [-25022, -72], [-28792, -788], [12324, 1510], [-4830, -644], [29208, -226], [8584, 2091], [7376, -464], [5570, -1008], [10674, -87], [-4166, -1348], [5322, -177], [-32660, -168], [-32422, 47], [19314, -1760], [-21852, 44], [3926, -672], [-12112, 462], [-8224, -935], [-19862, -172], [4872, 2042], [26802, -846], [6258, -1839], [-6344, -3242], [-6224, -2119], [-25902, -1468], [266, 2303], [-4248, 1324], [13264, 186], [13832, 2096], [10232, 1127], [4688, -840], [35362, 329], [16194, -1000], [-1006, -475], [28728, -1823], [5626, -920], [47472, 190], [-1300, -2564], [9186, -2218], [-16944, -264], [38000, 552], [-13470, 538], [-8418, 3352], [-20422, -49], [8544, 4221], [-23262, 258], [-13904, -1393], [38798, -884], [14880, 3028], [17282, 1011], [12216, -1634], [49830, -42], [-33276, 1990], [16234, -902], [-8664, 3454], [-3252, 2676], [13638, -3064], [18162, 1351], [21832, -2215], [-20694, 3195], [-30486, 104], [-6700, 472], [40334, 2060], [-21392, -1348], [-43054, -2430], [44544, 1497], [-13520, -2636], [-13598, -3881], [36208, -3435], [-33838, 427], [15470, 112], [39918, -392], [60058, 305], [-45192, 1330], [15750, -1548], [-47384, 2416], [35618, 1992], [47706, 2654], [-3036, -252], [3610, 1411], [12568, -3816], [-7416, -447], [48162, -2052], [19336, 2158], [706, -2664], [25786, -1911], [10584, 2000], [-29244, 2928], [77776, -54], [-59718, 856], [28656, 1864], [-30398, -4345], [42320, 781], [59102, 1986], [49346, -1912], [-23172, -4250], [-8526, 720], [7984, 5096], [14716, 12], [-37402, -36], [-65006, 1693], [24632, 1325], [-26908, -3662], [-23416, 6755], [-18598, -176], [36688, -2206], [-53792, -2072], [-22262, 3916], [45000, -5510], [-22384, 4184], [-62494, 742], [-24154, -1820], [16816, -6269], [32760, 16], [57976, -3565], [-9564, -5844], [-36912, -5544], [-20634, -6488], [-23582, -179], [50248, -914], [-10684, -3154], [-14020, 5146], [-20128, -950], [15264, -3351], [91706, -1680], [12346, 2187], [88352, -369], [1794, 74], [10834, -4697], [46816, -5099], [-40282, -1824], [108840, 1438], [14578, -6557], [-39622, -992], [-12200, -1822], [92696, 539], [-81526, -1104], [-23166, 3194], [-21934, 1679], [-13388, -3048], [-27426, -4292], [-4230, 315], [59368, -4594], [15334, 5990], [75058, -3322], [58216, -5108], [-59966, 3522], [-55696, -1332], [-36990, 2566], [15596, 7950], [-79944, 1533], [-110314, -1512], [7646, 10808], [56364, -2198], [54472, 1672], [29848, -8178], [-69008, -432], [-24462, 5354], [-60284, 552], [-12248, -4513], [11730, -7072], [-76450, -5848], [-10020, 338], [129778, 977], [84646, -5492], [73380, 7440], [-115454, -2722], [-50020, -4870], [-8062, 7080], [-82614, -5161], [7768, 1156], [13834, 269], [-135212, 642], [54868, -3860], [-145926, 1636], [-20826, -6186], [142872, -158], [17080, 613], [26112, -5078], [67906, 6924], [-14504, -3125], [-28238, -6344], [66424, -5253], [-109298, -4936], [41160, -1680], [-107106, 3318], [-1702, 5738], [-49712, 6348], [38768, 5013], [9250, -8318], [53908, 7984], [21488, 7741], [-6854, -6566], [87930, 490], [-23808, -450], [115174, -3304], [118570, -33], [35680, 5008], [-58038, 240], [-110438, -3354], [39272, 3810], [-14688, 1010], [-17720, -4397], [-7170, 874], [73146, 8984], [67678, 3866], [-48340, 2194], [39916, -4790], [-68240, 11778], [51236, 9762], [34018, 12420], [4242, 12897], [-39646, 8654], [55756, 3210], [-78790, -5368], [-18654, 7506], [28058, 5045], [-76424, 1292], [106982, 4286], [24888, -531], [81482, 10032], [-59920, -2360], [-138256, -3644], [-11302, 13475], [-90680, -1322], [-108186, 2648], [106262, -6980], [12024, -4296], [-79782, 9088], [-104894, -9925], [161544, -564], [63196, -8548], [-16230, 1932], [7432, -3601], [-21654, 11840], [-16094, -10807], [135928, -7081], [336, -17403], [-105548, 7612], [32390, -11560], [20242, 9309], [74680, 6282], [-37698, -11960], [1168, 6091], [98336, 1650], [126608, 7595], [90358, -2796], [11380, 6818], [43830, -4888], [77092, -4344], [-83512, 1109], [77650, -3156], [152386, -1533], [-122646, -1422], [54778, 1467], [-48654, 15296], [117176, -4684], [96770, -7252], [-109140, -7240], [28488, 8748], [142032, 7460], [36202, -7212], [14072, -2946], [42392, -1210], [-20186, 15892], [2738, -10671], [-51600, -11847], [-137056, -3102], [-124392, 2355], [-178086, -884], [23584, -10508], [133482, 3795], [-19096, 9246], [102950, 6782], [60794, 5926], [-132390, -8988], [-14248, 17326], [-5510, -4691], [-236310, -271], [103600, -14000], [-96842, 10296], [176986, -1636], [-58268, -12876], [81484, 1002], [-179830, -6620], [-68106, 4594], [16072, 14355], [-37800, -1784], [-12738, -12556], [54978, 11733], [-67776, -4167], [96868, 8234], [38066, 6511], [-90480, -8142], [81910, -6330], [252842, 206], [-255120, 3135], [-44484, 9552], [23354, 9436], [-119798, 6627], [91656, 563], [93770, -5650], [120780, 144], [17600, -17510]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1344_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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