
// Make newform 1344.4.a.bj in Magma, downloaded from the LMFDB on 08 May 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_bj();".
// 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_bj();".
// 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 := [-4, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-1, 2]];
    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], [5, -1], [7, 0], [11, 11], [12, -2], [-75, 11], [-4, -32], [-41, -33], [18, 32], [44, -20], [-144, 14], [-193, 61], [172, 76], [-138, 110], [-80, -18], [538, 46], [-78, -148], [686, 6], [-551, -55], [-120, -178], [-206, 106], [232, -164], [-873, -51], [428, 50], [-365, -387], [-1048, -184], [867, -181], [-1582, 88], [-1070, 112], [-1398, 10], [100, 408], [216, -290], [-980, 392], [-144, 254], [-144, 368], [-1698, 496], [1010, 402], [-1814, -126], [-1361, -279], [-2315, 125], [304, -454], [-1843, -467], [2036, 98], [1348, 290], [932, 36], [-600, -768], [4060, 340], [-2730, -182], [-4496, 250], [-124, 1114], [1663, 295], [-1468, 602], [-6122, -270], [-1841, 621], [-1129, 599], [1589, -97], [2088, -1152], [-6404, -542], [-1336, -1362], [1516, 416], [2667, 389], [-2248, 476], [4310, -714], [5042, -1040], [-720, -1130], [-2040, -1448], [-1290, 1684], [-923, 37], [-3758, 692], [-3259, 691], [-3407, 233], [6592, 360], [1602, -2440], [10248, 216], [-5240, 1392], [234, -112], [-9530, 376], [-4252, -1966], [100, 66], [-3326, -1202], [4484, 2010], [-7579, -435], [782, -1980], [-2648, 1008], [3173, 1469], [-9482, 1876], [14034, 104], [3891, -771], [1734, -1330], [-11622, -1538], [-3574, -894], [2804, -1452], [-4523, -1859], [1688, -320], [-16340, 860], [-6603, 1455], [-647, -2745], [2156, 672], [1196, 218], [14358, -1434], [-11340, -1766], [7262, 202], [15964, -1886], [6802, 1202], [-7962, -300], [1170, -258], [7509, -4557], [-7227, -1387], [-12594, 2308], [-17720, 416], [-8446, 4896], [252, -62], [-4376, -404], [-78, 6506], [25456, -402], [13948, -456], [-12802, 1526], [1970, 6768], [6423, 2551], [25318, 1528], [-4224, -5746], [-1753, -2983], [3561, -3247], [10248, 4364], [-1538, -2916], [10770, 400], [5420, -7052], [-14344, -4424], [-9380, -4474], [3962, -5238], [6865, -5927], [-5256, -840], [39178, -440], [6055, 3269], [-13898, -2068], [23215, 2857], [1048, 7260], [5399, 8129], [21422, -4236], [-11136, -2524], [6620, -790], [29542, 1502], [17067, -3245], [-7080, 3746], [5254, 6830], [29738, -1644], [5575, -907], [11280, -6500], [-7941, 1115], [9234, 696], [-24719, -1377], [46552, 352], [10498, 8650], [-4948, 9428], [35965, 4341], [42132, 140], [17579, 2449], [-17370, 4684], [8453, -11497], [-3765, -7989], [9010, 2936], [37842, 2498], [-23668, -80], [-18328, 390], [5252, -8548], [12660, -5604], [12950, -3496], [-10136, 5030], [6467, -7339], [28135, -1169], [-4114, 10528], [-24443, -3003], [19552, 6406], [43932, 1884], [-39355, -1941], [33054, 934], [-13642, 10156], [-1356, -12244], [3574, 13920], [10326, 10806], [-51696, 3484], [-16308, -10582], [31017, -961], [-24325, 9619], [-24161, 769], [-4562, 1004], [388, -5592], [23504, -8426], [10240, 7544], [12076, 4666], [33635, -2693], [180, 12492], [-23205, 1141], [25223, 1375], [893, 9715], [-34704, 6174], [12460, -11822], [40251, -2631], [-49614, 4866], [-8676, -78], [-54460, -620], [-8708, -5794], [4228, -1630], [-35056, 3972], [9327, 4161], [-50588, -5004], [17963, -7365], [25866, -2576], [-16824, -11740], [-62774, -3960], [3217, 10171], [-25724, 10356], [21948, 9728], [-2650, 19430], [31710, -10084], [-19748, -12428], [457, 12927], [-35777, -3905], [27962, -4312], [-11166, -8000], [-48296, 11440], [-73310, -5120], [-21472, 3584], [-20868, -3632], [-42952, 14726], [11015, -5219], [12479, 6583], [-79440, 6808], [40377, -5335], [-7718, 14832], [42712, 11220], [6556, -9564], [-77426, -5180], [17496, -16340], [61184, -7296], [10932, 15258], [23376, 4510], [69321, -8959], [-39468, 6228], [22561, 3809], [69232, -7980], [-3124, -16876], [-4692, -2278], [-13389, 4833], [50266, 1650], [4052, -2484], [83742, 4882], [-77414, 5146], [23091, -12525], [-1410, 12668], [27189, 323], [18749, -24803], [57264, 16854], [36055, 20505], [-62585, 7247], [-9692, -23038], [-53064, -6828], [-11873, 7913], [19926, -18860], [9738, 20170], [48329, 13641], [-89720, -2998], [-13510, 3348], [35353, -14161], [-16328, 20900], [-40256, 6550], [11713, 2743], [33438, 24982], [104070, 5276], [19354, -9588], [-24212, -22916], [51304, 6510], [-16428, 4292], [56936, -2058], [-76648, -4368], [111887, 4255], [69236, -4350], [268, 12002], [-81666, -13086], [53628, -13172], [47994, 3170], [-91444, -1308], [-55938, -9632], [34996, 5240], [47469, 12997], [17818, -12392], [16792, 1238], [100240, -10768], [91167, -627], [21892, 25370], [-27620, -24384], [-22740, -8574], [-37106, 4578], [110114, -9680], [81175, 9857], [-129644, -7524], [-46943, 3315], [-61274, -15806], [44140, -4440], [-30590, -11376], [67090, 17952], [62902, -21874], [-43145, 5751], [-75198, -16110], [78414, 15404], [133281, -95], [-84528, 19418], [96705, 1017], [37492, -8934], [9228, 20492], [-31478, -17008], [158720, -3346], [-14616, 5944], [49231, 18079], [31288, 15902], [-68520, 17140], [-20857, -38169], [105424, 3726], [-116184, 2966], [32044, 20056], [-69776, 20486], [-118141, 3573], [-42452, 12420], [-43286, 7344], [-109480, -2546], [-146866, -7906], [19556, 2200], [-86647, -1119], [-84578, 11044], [-15962, 25220], [48138, -5416], [-89480, -23288], [76490, -5290], [41566, -1786], [5122, -18282], [38218, -6000], [33199, -11683], [-22324, -29022], [-116632, -9112], [98338, -13464], [-30384, -24522], [1961, -30869], [-61148, -30004], [183698, -5360], [-76721, -4113], [-86364, 23614], [-40180, 23340], [-7156, 7228], [-61309, -24915], [40752, -18788], [-114816, 6422], [-112380, -3958], [-65100, -22556], [-94214, -27520], [-117219, 7811], [23100, 47748], [19340, 22336], [-57894, 11528], [-24139, -9363], [5586, -12200], [6115, 26953], [-86267, 25037], [25975, -28641], [101968, -14860], [-133584, -19354], [-188423, -8125], [180314, 11322], [-93412, -23342], [19537, -11655], [134040, -9420], [-93663, 10305], [-153632, 19806], [-180672, 15160], [-64460, 8258], [-66644, 3072], [46023, -30865], [125398, 11508], [-14083, -9725], [-43496, 23702], [-169405, -19667], [-148786, 25204], [45860, -35780], [82558, -9060], [2236, -10552], [-79352, 24344], [-81376, 8312], [27620, 24374], [48270, -12522], [41602, 45642], [146968, 19126], [-155315, -16921], [179699, 19163], [154016, -15044], [-66087, 12241], [-182826, 15516], [153900, 10636], [15053, -47237], [29038, -8378], [-62370, 37060], [9698, -9732], [73418, -29016], [88466, -2214], [-122537, -2299], [86357, -44633], [-18896, 5296], [93220, 39378], [-72582, -19944], [88500, 41440], [-22966, 10198], [-118046, -3184], [-30062, -50232], [-2487, -15047], [124044, -31100], [-145872, 5686], [-119535, 8651], [139627, -16869], [89700, -10652], [-29695, -52377], [-46874, 58742], [-133070, -24016], [-43842, -20960], [-67939, 8605], [-108836, 11880], [67066, 24008], [196663, -2135], [-123703, 16265], [-105584, -14634], [-43732, 22552], [-101430, -17550]];
    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_bj();".
// 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_bj(: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_bj();".
// 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_bj( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1344_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![8, -10, 1]>,<11,R![-1936, -22, 1]>],Snew);
    return Vf;
end function;