
// Make newform 1344.4.a.bl in Magma, downloaded from the LMFDB on 16 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_bl();".
// 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_bl();".
// 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 := [-44, -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], [-7, -1], [-7, 0], [9, -3], [-24, -2], [17, -9], [-8, -4], [-55, -7], [-106, -4], [68, 4], [12, 26], [347, 9], [-292, 8], [158, -2], [-280, 6], [-246, -26], [302, -28], [-510, -10], [855, -25], [-656, 6], [278, -42], [-132, -32], [35, -95], [-68, 10], [375, -51], [-600, 32], [921, 77], [890, 16], [-186, 20], [1582, 30], [2056, 60], [-296, -18], [2220, 8], [-1928, -10], [368, 56], [1218, 24], [910, -222], [174, -202], [-1285, -23], [703, 139], [-284, 274], [3403, 35], [-420, 234], [240, 62], [-1892, 20], [-1576, 204], [-396, -236], [-2390, -50], [-1940, 170], [184, -82], [5129, -63], [-1052, -446], [-1702, -298], [-2685, 265], [-207, -239], [-1743, -465], [880, -448], [1712, -114], [-1212, 394], [5384, 116], [-3945, 365], [-308, 272], [582, -418], [-646, -336], [-4464, 262], [-1072, 764], [3902, -340], [5727, -109], [2974, 340], [-1431, -65], [-2265, 119], [-10520, 152], [-9326, -224], [-2568, 724], [-156, -220], [-5786, -316], [2954, -848], [-9636, -6], [8100, 394], [-4526, 662], [8432, -386], [-9165, 379], [-4730, 436], [2016, -152], [-5705, -85], [10274, -352], [-2294, -400], [-657, -867], [-86, -310], [12270, 290], [-1718, 410], [-5116, -804], [7527, -373], [-11864, 252], [-2336, -312], [9417, 343], [-10299, -29], [-1012, 264], [2528, 470], [2578, -1018], [-11804, 650], [-13426, -254], [-16128, -58], [-13666, 426], [24822, -108], [-6226, -102], [-1527, 911], [7291, 1115], [-19682, -12], [-14656, -64], [-3838, 1344], [3996, 690], [16416, -420], [12454, 862], [1160, -1738], [6592, 852], [-15246, 1082], [2186, -1568], [2509, -247], [-12278, -728], [28768, 46], [-14085, 465], [-5085, 615], [5480, 1612], [4342, 892], [-5878, 1064], [5208, -216], [-7616, 1992], [-11560, 638], [-13898, -1014], [15335, 1143], [5896, 2328], [10010, -888], [-28389, 793], [4942, 140], [-4085, 2081], [7960, 92], [-12261, 89], [26298, 448], [-2688, 1532], [5100, 1002], [7354, 1874], [14913, 1605], [13036, 1362], [12618, -942], [2630, -284], [2787, -1087], [-22172, -1904], [-15355, 1933], [13594, 944], [16301, 1459], [-7064, 956], [-8850, 38], [34412, 1368], [5083, 1475], [-2620, -2996], [15743, -475], [-24378, -660], [441, -1161], [31193, -1771], [-15262, -2056], [-3690, -2338], [31556, -1792], [20556, 170], [17364, -484], [31452, 1340], [48218, 104], [14976, -1250], [-39065, -819], [3101, 961], [10386, -2296], [-42453, -677], [-7424, -554], [26820, -1004], [23857, 415], [-9454, -258], [-11706, 2372], [-6628, 2900], [-28678, -2080], [2882, 4242], [-3872, -2252], [5144, -1818], [10565, 67], [50157, -731], [-28173, 1177], [-3866, -4276], [-9172, 1952], [-33624, 222], [19164, -2660], [50612, -382], [5289, -3779], [-18436, 464], [-26409, -1483], [-2851, -2167], [36873, -249], [-2120, -426], [-21464, -2530], [-33169, 405], [20794, 2274], [30968, 3038], [-11724, -2044], [-26192, -2], [-11492, -2870], [16176, 2732], [36027, 1721], [46876, 2364], [2097, 1277], [31066, 1152], [-25172, -56], [-18198, 312], [-18435, 2515], [-42484, 2548], [20820, 1440], [-15322, 4878], [-35610, 2924], [-3708, 2772], [18973, -3805], [-21039, 4513], [32254, -2716], [-36126, 4768], [-41704, -1504], [8230, -1404], [9600, -80], [-4072, 5020], [-19892, 554], [-44757, -727], [52049, 153], [-19768, 1312], [80907, -1809], [-45766, 976], [20108, 2544], [-43876, 796], [43610, -2240], [15700, -1392], [-27192, 376], [-72844, 2418], [44628, -2830], [27491, -5673], [-16056, 1792], [-43421, 175], [-44176, -260], [-11588, 1044], [-4696, 3054], [-30033, 5733], [-13106, 4774], [22244, 516], [60778, 1742], [7014, -1182], [6941, -4651], [17254, 5484], [-35495, 2447], [-11093, -3045], [840, 5022], [49555, -191], [-91347, -247], [-7376, 942], [22172, -184], [10011, -7023], [-90066, 580], [-93482, 2182], [-3525, -5097], [26580, -5870], [-42298, 348], [6381, -4413], [-34648, 2460], [84484, 234], [-20659, -1925], [-33558, 758], [40782, 3308], [12062, 1060], [-24068, -1360], [-51376, -650], [62004, -3532], [-109200, -242], [22792, 1168], [12925, 7553], [76304, 1190], [18908, -366], [46890, 2430], [-76284, 1988], [52774, 3630], [72468, -3460], [-45390, -736], [8780, -568], [105219, 3179], [-47022, 4320], [46108, 5946], [-8328, -2368], [133467, -831], [-23712, -6426], [-94264, -4500], [44668, -4638], [92654, -1158], [-97838, -1624], [-102197, -2807], [-5796, 2364], [22853, 7131], [-54630, 854], [-46828, 840], [-10198, -5328], [-92610, 5556], [-44574, -1790], [-73107, -1047], [-60210, 1210], [47078, 3748], [71331, 1223], [-104788, -1438], [43615, 2591], [-24104, 1542], [-12148, 5276], [50570, -904], [138404, 2258], [32464, 9908], [118841, 1145], [43360, -5930], [-31336, 412], [-52703, -5079], [9016, 10278], [42672, 10158], [60344, 3292], [-32920, 3406], [-12009, -4331], [-45388, -8172], [-8906, 1500], [-85192, -4938], [-103862, -2978], [32800, 460], [38367, 2199], [155190, -524], [-104514, 4756], [-41766, -5440], [-62056, 7960], [-93598, 5062], [10682, 4054], [-6110, -7202], [131066, -1504], [39491, 4329], [-41356, -9078], [-79072, 7088], [24930, -8656], [19140, -790], [-31611, 267], [124804, 3356], [-23242, 6748], [-64347, -399], [-28168, -6634], [6532, -3600], [4492, -12996], [61247, -7163], [129644, -7328], [71416, -7858], [-45120, 6310], [-51732, -5380], [-27774, -3856], [30897, 5471], [131976, -3448], [-24116, 936], [86958, 5116], [67827, 211], [69802, -10072], [15063, 1381], [-110133, -6285], [114237, 2177], [137016, -1716], [62576, -11930], [105093, -6909], [30870, 11294], [-63332, 2146], [-32549, 8695], [140660, 5040], [-59025, 5367], [27316, 7026], [68240, 984], [-97056, -7306], [-67312, -6188], [93753, 4993], [159638, 2516], [-78671, -5129], [69496, -3938], [155623, 6629], [54898, 9176], [110276, -7412], [31446, -9900], [140444, -912], [-122124, -5044], [84544, 11312], [-6176, 17102], [127562, 726], [115642, 6314], [52808, 3190], [-32567, 13135], [202113, 1557], [29268, -6312], [-138497, -4193], [-8554, 16172], [-52564, -1812], [53945, 5015], [-89414, -6666], [34386, -12320], [-45978, 10972], [-27962, 13028], [-107658, -5386], [112587, 2921], [68921, 10431], [198616, -1392], [-83216, 3606], [-47638, 2712], [99204, -2712], [-105174, -3698], [72306, -3392], [-118218, 4036], [14443, 4479], [-28916, -16464], [-206784, -5450], [97317, 6883], [6613, -1859], [145100, -7548], [-80139, -1669], [20590, -14746], [78270, 1508], [95962, 9576], [234747, 2531], [169248, 5004], [190770, -456], [-81621, -4711], [40451, 6255], [-10740, -4590], [16724, 8448], [-166226, 10022]];
    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_bl();".
// 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_bl(: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_bl();".
// 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_bl( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1344_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![-128, 14, 1]>,<11,R![-1512, -18, 1]>],Snew);
    return Vf;
end function;