
// Make newform 1152.4.a.t in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1152_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_1152_4_a_t();".
// 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_1152_4_a_t();".
// 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 := [-3, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [0, 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_1152_a();"
function MakeCharacter_1152_a()
    N := 1152;
    order := 1;
    char_gens := [127, 901, 641];
    v := [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_1152_a_Hecke(Kf)
    return MakeCharacter_1152_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], [0, 0], [2, 2], [4, 2], [-46, -1], [-50, 6], [-46, -12], [2, 7], [4, 18], [42, 10], [192, 16], [86, 14], [150, -8], [150, 5], [-8, 44], [-6, -14], [322, -33], [-146, 70], [-86, 83], [204, -42], [206, -52], [200, 36], [-474, 13], [-286, 116], [1102, 92], [-1062, -14], [1732, -14], [722, -145], [-714, -42], [-98, 96], [1328, -120], [-474, -171], [710, -40], [1094, -179], [882, 386], [-772, 302], [-2082, 6], [386, -401], [364, 246], [-2622, 26], [678, 253], [-1250, -98], [2480, 232], [-242, -132], [-2894, 34], [-380, 162], [-2806, -149], [4416, -144], [-2130, 233], [-1138, -66], [-2286, -428], [936, -428], [622, -756], [3042, -49], [-2322, 192], [-2484, -714], [1882, 202], [1912, -244], [-3642, 366], [1458, 132], [4566, -291], [3442, -478], [-942, 127], [-5596, 722], [-2150, 840], [4074, -534], [-7042, 169], [3154, -304], [3042, 127], [4358, 1046], [-5010, 944], [-8644, -306], [1928, 1268], [7094, 302], [-7058, -1031], [6144, 512], [7786, -206], [-3210, -1418], [-5070, -236], [2266, 1256], [-8954, -683], [1694, 990], [9832, 340], [-10098, 172], [3228, 206], [-1494, -1229], [3346, 4], [-4566, -1304], [-1190, -342], [-2872, 1572], [-7474, 1377], [-11328, 1104], [-10732, -22], [-326, 2147], [2954, 795], [1940, -422], [16066, -230], [7270, 504], [638, -311], [12302, 1478], [-13382, 459], [-8206, 154], [-9810, -1407], [-2090, 1144], [-12682, 413], [2114, -240], [-12686, -1745], [-7986, 1760], [-5580, 1082], [-18114, -180], [6928, -1880], [10526, 478], [-17086, 740], [-2018, -919], [-11860, -250], [17874, 36], [1098, -3773], [11340, -2506], [-3078, -1590], [-10458, -979], [-8002, -1762], [1102, 828], [2570, -398], [13146, 1491], [11610, -765], [2834, -4006], [3382, -2578], [9432, -436], [3276, -3450], [-13866, 1174], [11346, 3607], [-9172, 694], [2488, -2692], [-16370, 1726], [-13594, -2120], [-8338, -964], [8106, 82], [7178, 2379], [37026, -230], [16278, -328], [9438, 1897], [7882, 1938], [4828, 1262], [7898, -3925], [-12610, -2330], [15324, -2130], [-11738, -3314], [-4938, -4680], [-7298, -3215], [10528, 160], [-20474, 86], [25486, 1584], [802, 3943], [35556, 914], [9782, -3227], [9192, 4420], [10332, -194], [-21102, 3012], [-14162, 4588], [-7766, -3286], [39758, 337], [52022, -488], [-10780, -6094], [-3638, -3269], [19506, 1588], [7892, -6486], [17264, 4408], [-3690, 2478], [15950, -3316], [-2174, 6146], [-6102, 83], [9894, -3914], [-39764, 518], [30686, -1604], [13016, 2140], [-25422, 1604], [-12018, -3655], [-6406, 3506], [-19916, 2362], [-14594, -6714], [-3040, -816], [27294, -5711], [-6882, -2114], [33410, -636], [-45720, -2332], [12786, -7742], [36766, 4614], [62594, -625], [14410, 4136], [-8384, -5920], [3250, -5616], [10362, 275], [58930, 2239], [57290, -1462], [52958, 2305], [-15902, 3620], [-2542, 1952], [-17602, -6394], [-8834, 6208], [24012, -3306], [-29134, 7130], [3688, -10604], [33014, -2578], [-56654, -2752], [16434, -1121], [-26022, -630], [-32320, -32], [-32818, 1609], [-3662, -1292], [49198, 641], [-44530, -3444], [-1694, -3166], [43244, 3286], [14042, 8539], [-33780, -2458], [-13574, -9400], [-21288, 652], [-11566, -8236], [25140, 7994], [58410, -470], [-2258, 7102], [-48372, -5994], [-24366, -8988], [29352, -5164], [31550, 3417], [31510, 5422], [-30590, -2700], [25712, 2296], [-15196, 3234], [-37366, 2507], [12070, -2122], [-80254, -1353], [2272, 4848], [-44158, -6140], [-5578, 6597], [-40904, -5732], [-36082, 1004], [-33886, -2110], [-76758, -5245], [21132, 2694], [-8682, 885], [43142, 869], [12116, -5382], [24350, 3686], [-4306, 10992], [-62732, 2426], [79360, -1680], [-47850, -451], [-26138, -1395], [77352, -5196], [56742, -7082], [30158, -12432], [-14036, 2854], [-16658, -7284], [-74006, -406], [12310, -7771], [-21554, -13538], [-64242, -8295], [-53430, -7726], [27066, 2984], [-17600, 4576], [-32258, 3905], [43942, -11986], [18982, -9066], [-53646, 8740], [8538, 15643], [-38774, -7382], [33282, 1044], [-18050, -17727], [16826, 9362], [-80306, 5638], [-88462, -3649], [12046, -6660], [-43760, 1576], [14562, -48], [-92084, -2058], [29050, -5989], [62238, 4102], [94254, 6476], [-57666, 10713], [57056, 5984], [37444, -4014], [-48780, 11914], [43358, 9438], [-23834, 381], [54952, 13380], [42670, -6964], [85818, -4622], [-54148, -5874], [28766, -720], [-36806, 9930], [-12114, -9695], [-14622, -12140], [26898, -6945], [33830, -8682], [77586, 6682], [-40576, 10032], [31762, -1470], [68154, 8667], [91162, -981], [40730, 8584], [-81006, 10138], [84888, 6364], [-71130, 9293], [-61130, 3565], [-11634, 7420], [-34366, 9479], [-11938, -2074], [-136188, 6530], [-25834, 7214], [135496, -1772], [-31614, 18690], [-28014, 5828], [-32438, -3661], [-73780, 70], [-59538, -9364], [71542, -10619], [-320, 8064], [137922, -2176], [105742, 992], [21146, 5331], [-39238, 1928], [-117990, -1718], [142864, -5400], [-97338, 3960], [64814, 3500], [-146334, 175], [89222, 7125], [72416, 11360], [-79406, -15294], [-82354, 8550], [30570, -3382], [-104768, -6272], [64182, -931], [109270, 10965], [4338, -1753], [-6506, -20426], [98734, 4784], [47070, 10716], [17992, -7020], [-115330, -9154], [40102, -23880], [60042, -9454], [37460, -23494], [15666, -3942], [56446, -1839], [141118, 8478], [-25890, 1513], [-60888, -17228], [147826, 5282], [1330, -20073], [80666, 6216], [72594, -5030], [41256, 14644], [90862, 7646], [82450, -1084], [-141264, 12600], [72042, -14181], [-169614, -332], [-25884, -25198], [-18682, 3246], [60018, 17524], [52680, 3668], [69442, 5263], [-3662, 11943], [-69346, 22172], [38930, -1510], [14804, -3942], [-22774, -17912], [23654, 9061], [62014, 8441], [123672, 60], [130698, -1998], [44492, 6454], [-114250, 5046], [-34826, 18997], [9024, 26864], [109618, -6016], [-59694, 26196], [127162, -11736], [-151766, -12182], [36822, 4184], [80188, 12462], [64398, 6272], [60082, 4807], [63132, 4126], [-74104, 26676], [107078, 4750], [25310, 25169], [-58784, -11504], [-6014, 5904], [-39414, 16882], [-213790, -6425], [126490, -12429], [90740, 11194], [33754, -29016], [-50992, 8296], [-2842, -14632], [52902, -22099], [-28662, 9394], [208902, 1590], [31698, -35644], [-166872, -1420], [-133482, 216], [90498, -16670], [-89724, 21138], [-70130, -15738], [-49422, -20972], [30314, 8139], [47974, 9909], [27330, -1584], [-66006, 13714], [64946, 1959], [49394, -31865], [14462, 24028], [100946, 186], [-149792, -1680], [154996, 970], [-106734, 7892], [-57804, 18490], [-22382, -7430], [23238, -39058], [-163912, 17132], [-121134, -11353], [59274, -21304], [124674, 2362], [48590, 13761], [-253374, -396], [146358, 6349], [114276, 2930]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1152_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_1152_4_a_t();".
// 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_1152_4_a_t(:prec:=2)
    chi := MakeCharacter_1152_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_1152_4_a_t();".
// 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_1152_4_a_t( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1152_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![-188, -4, 1]>,<7,R![-176, -8, 1]>,<13,R![772, 100, 1]>],Snew);
    return Vf;
end function;