
// Make newform 1344.4.a.bg 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_bg();".
// 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_bg();".
// 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 := [-14, -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], [-3, -1], [7, 0], [3, -5], [-8, 6], [-3, -1], [-32, 12], [3, -17], [126, -12], [20, 36], [124, 18], [-225, -15], [-188, 24], [-6, 34], [552, -2], [-402, 58], [214, -36], [-74, -54], [477, -15], [536, 6], [-286, -54], [-972, -48], [183, -71], [404, 138], [-573, 13], [-1456, -72], [-525, -85], [250, 144], [-90, 132], [-1126, -78], [-984, 68], [-912, 62], [-764, -120], [600, -178], [-1024, 216], [-2390, -96], [-1190, -162], [522, -150], [-1929, -247], [-555, 445], [-524, -342], [345, -11], [2828, 162], [-432, 438], [-1708, -180], [-1592, 132], [-3508, -36], [1902, -494], [-1460, 306], [-6576, -2], [-477, 39], [1388, 18], [-3762, 186], [2775, 1], [-1029, 407], [1749, -689], [-2248, 648], [-2000, -90], [-612, -54], [-704, 36], [819, 189], [-2420, 744], [978, -574], [-1894, -48], [960, 686], [-7664, 84], [2990, 972], [3189, -683], [7174, -372], [1365, -985], [4557, 673], [-2920, 456], [4018, -960], [-2744, -516], [-7188, -932], [-3858, 124], [1906, -360], [-636, 394], [3116, -774], [-3114, -1350], [-272, 1494], [-5295, -163], [2870, -1932], [-5008, -1272], [7773, 989], [9954, 96], [-3382, 1008], [-4149, 429], [7310, -378], [10122, -754], [654, 278], [-580, -12], [6093, 285], [-4088, -540], [7632, 72], [-8355, 1223], [33, 1547], [-812, 1080], [8032, 1038], [-458, -246], [2388, 322], [8346, -1442], [-9528, -1946], [11002, 102], [13574, -396], [-3654, 1638], [-11067, -569], [18537, 989], [-1810, 2964], [4784, 1968], [1330, -1296], [-1836, -2958], [9376, -972], [10754, 210], [-7248, -394], [-872, 276], [9942, -1690], [-11262, -1288], [-4977, 975], [2866, 624], [17840, -810], [-14313, -2383], [-18879, -1919], [-4664, 756], [5598, 756], [-6806, 2664], [12936, -296], [-17704, 2064], [520, 2790], [-12206, 2934], [5517, -351], [3128, -1848], [15418, -120], [-32721, -47], [-610, 972], [3207, 2785], [7144, 1332], [18999, -1959], [-11190, -1648], [1744, -3996], [-35076, -574], [1262, 1998], [22923, -2541], [41980, 426], [16398, -66], [-40178, 828], [-7113, -3751], [-3548, 1368], [-8169, -2981], [-8246, -4320], [-34983, -1173], [-14456, -3996], [-15414, -3782], [8692, 648], [-33975, 2325], [-23236, -828], [-1005, 589], [24038, -2436], [38829, 775], [36339, 1667], [11970, 5304], [-29134, -2382], [1068, 944], [5172, -70], [22092, 2900], [11108, -1260], [-20414, -144], [39824, -1338], [-3549, 4349], [-38913, -1289], [-17030, -2736], [-21543, 4477], [25376, -3666], [12332, -756], [-21267, -5097], [8182, 5874], [16590, -2948], [-4132, -2508], [-6878, -5112], [-49882, 78], [-25776, -2004], [22744, -4386], [-16431, 5659], [-5745, 899], [26463, -2519], [24550, 4284], [-43916, 1344], [-33496, -3402], [-1596, -3820], [-57028, -750], [-28125, -837], [-52076, 864], [-23277, -3451], [-7521, 1711], [-219, 4991], [-58648, 510], [-33752, -1098], [-1341, 5757], [28110, -1250], [39720, -5018], [-15220, -6036], [-13232, -1386], [30260, -2358], [-74304, -1644], [28263, -7607], [49700, -1836], [38715, 1691], [64170, -624], [-45380, -4320], [-29302, -1224], [-51039, -3453], [15380, 5340], [-2388, -5536], [45474, 3266], [-41722, -4932], [-8644, -2532], [-4503, -10885], [-30885, 1351], [39366, 2268], [-23582, -6048], [-12736, 984], [9462, 12004], [15008, 1968], [10440, 4308], [47548, -5790], [8751, -2927], [-43941, 6383], [-33376, -4440], [-327, -3079], [12442, 6960], [-7124, 10920], [28196, -2508], [23802, 4448], [38692, 5064], [-26760, -9496], [-50260, 7026], [16836, -3766], [-11583, -1263], [30600, 1872], [38433, -1223], [40864, -4956], [17636, -1668], [10024, -2682], [-55917, 6621], [67098, -1238], [-8524, 7716], [92910, 3154], [-35726, -1266], [-24417, 1299], [26182, 8124], [78933, 3079], [20697, 4157], [23120, 5214], [13359, 673], [50703, -5137], [-29936, 6246], [53260, -1440], [23175, 6081], [29102, -300], [34178, -9606], [30825, -8751], [-50636, 378], [50446, -9516], [100185, -2629], [45016, -9036], [20052, 258], [32553, -9405], [68830, -3366], [39414, -5660], [-107690, 2604], [7540, -10080], [46424, 3222], [60572, -8244], [-94840, -7074], [10928, 5256], [-39297, 7511], [-28784, -12258], [-45844, 3402], [61422, 4514], [13308, -1684], [10658, -2718], [77580, 1140], [-30086, 12264], [9556, 11448], [104097, -2099], [22322, 4032], [116028, -1374], [-15856, -4248], [-66609, -6087], [24816, 10990], [43176, -1388], [-44844, 2050], [-29286, -15258], [47890, 13704], [4359, 8809], [-18700, -1692], [20601, 315], [-66882, -6358], [-6308, -12216], [15770, 3168], [92310, -5572], [81302, 3246], [-89073, -3825], [-121142, -3690], [101366, 2244], [-107583, 2785], [-18164, -14454], [127029, 3193], [72760, 9822], [34356, 628], [57522, 8416], [13692, -1742], [103264, 5004], [45171, -12273], [48296, -16074], [-70776, 10452], [-35157, 11135], [-50176, -7098], [-68328, -7794], [-72176, 9372], [-51016, 13686], [-58797, -10203], [96236, 5052], [79782, -1732], [-47248, -378], [-18578, 13698], [7288, -8964], [25077, 15649], [74574, 5052], [-68546, -1116], [-13902, 6712], [28208, 432], [105222, 5386], [37438, -4374], [-59706, 8082], [-103094, -11280], [11991, -3551], [55916, -9366], [-9304, -10440], [5794, -1872], [-46980, -1398], [2745, -1749], [-16180, 24516], [-31602, -2812], [14391, 1863], [125944, 558], [77116, 9264], [-164412, 6948], [38283, 23333], [-39044, -5400], [79688, -5130], [-61488, -9042], [-9580, 8916], [-25022, 21744], [103725, 8343], [-42216, -4040], [90948, 8584], [-98610, -308], [22545, 23397], [-30230, 5640], [40971, 10477], [28473, -18811], [-83073, 17495], [-16904, -25740], [92576, 7758], [-44199, 10275], [-65374, -18270], [97388, -15846], [-2967, -7343], [-83036, -16632], [66981, -16703], [46692, 8586], [-33160, -14160], [104992, -11538], [-672, -27764], [-210861, 3015], [17894, 18036], [-117843, 11599], [-91456, -162], [-163149, -3131], [18594, -26712], [39788, -6540], [56742, 9332], [-73628, 9168], [150252, -10396], [120656, 9504], [-22448, -5706], [118462, -6342], [-176418, 9222], [91592, 7086], [47085, -16081], [-113685, -12893], [-181532, 8352], [36021, -28007], [-101626, -10548], [-211804, -2124], [38421, 13263], [113806, -6438], [-119094, 6520], [-131810, 9732], [152166, -11948], [-16366, 21498], [-1041, 8113], [-19203, 6079], [-159640, -3024], [-27344, 8334], [-105030, -17784], [-176852, 3816], [67038, 28610], [-75838, -6960], [51774, 6140], [-177255, 5097], [-173900, 1008], [-81856, 22638], [-61959, 28931], [-17241, 16843], [-4900, 8052], [-154143, 8019], [154650, 9034], [-57642, 7660], [132082, 4320], [-85815, -7851], [39024, 7188], [271010, -5112], [52599, -9143], [62241, -13927], [-139788, 20034], [-118868, 10560], [76074, 11354]];
    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_bg();".
// 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_bg(: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_bg();".
// 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_bg( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1344_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![-48, 6, 1]>,<11,R![-1416, -6, 1]>],Snew);
    return Vf;
end function;