
// Make newform 2352.4.a.by in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_2352_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_2352_4_a_by();".
// 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_2352_4_a_by();".
// 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 := [-28, -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_2352_a();"
function MakeCharacter_2352_a()
    N := 2352;
    order := 1;
    char_gens := [1471, 1765, 785, 2257];
    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_2352_a_Hecke(Kf)
    return MakeCharacter_2352_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], [0, 0], [-1, -3], [0, -4], [-15, -1], [6, -2], [-39, -9], [28, -18], [66, -10], [160, 18], [-9, 25], [-188, 0], [-120, -16], [-36, -30], [276, 32], [246, 14], [270, -42], [-429, -27], [-450, 18], [310, 66], [612, -32], [711, 33], [-558, -58], [-1581, 9], [222, 138], [555, 57], [-154, -156], [-526, 0], [-290, 18], [-288, -188], [838, 96], [2208, -68], [316, -126], [1160, 48], [-2634, 70], [2242, -150], [3132, -20], [2187, -71], [-1343, -21], [-672, -84], [-561, -159], [316, 438], [-1552, 126], [1848, 48], [1168, 180], [4236, 100], [840, -420], [3348, 264], [1906, 372], [-575, 279], [-1770, 322], [5460, 200], [1971, -171], [-2419, 171], [-4071, -85], [3042, -114], [-4336, -210], [-522, -192], [594, 466], [2031, -547], [2778, -486], [-2472, 328], [3720, 384], [1896, -594], [4520, 300], [6062, -384], [-6851, 111], [4086, 150], [2349, 539], [-6441, 585], [-7392, -336], [-9034, -456], [-128, -732], [5052, -68], [-4172, -258], [4926, -450], [5382, 456], [4206, -918], [48, 1084], [5184, -690], [-8193, -807], [13812, -172], [6732, -300], [-431, -573], [-9362, -588], [-10182, 576], [6363, 761], [-3574, 1086], [7716, -96], [-7260, 548], [9732, -396], [4477, -201], [14504, 300], [-7008, -944], [2181, 383], [11937, -241], [3156, -1600], [-13552, 870], [6862, 1086], [180, 498], [-4884, 1152], [7638, -1248], [12146, 306], [16572, 660], [-2832, -708], [-2931, 667], [-3025, 1497], [10380, -716], [4356, 2044], [3426, 384], [-13542, 12], [-9528, -964], [-5522, -654], [2002, -948], [-11466, -570], [-3828, 60], [10472, -366], [-909, 1425], [-8562, -1546], [13668, 906], [7035, 921], [-12571, 2127], [-8988, -2464], [-9304, -510], [-3586, -252], [-1620, -484], [294, 2882], [-4896, -2460], [25050, 114], [-22645, 69], [4152, 1704], [9814, -900], [-14217, 745], [3228, 3324], [-24165, -863], [14568, 1404], [-30801, 1221], [-28638, 504], [-4140, -2416], [20124, 1890], [5002, -666], [-13453, -1167], [-30120, 220], [-9768, 1408], [-33042, 894], [21567, -847], [-7698, 366], [10149, 1947], [-310, 1728], [-15831, -3345], [-808, 2508], [-23820, -956], [5668, -696], [-21073, 1977], [-19900, -2292], [-16137, -2039], [-13008, -2576], [-29739, 2359], [1731, 2433], [-22878, -888], [16182, -2526], [-22152, 3196], [-22662, -972], [34884, 1684], [-13628, 1188], [-19506, 2998], [-3464, -3990], [-4857, -3667], [-33993, -2163], [-45426, 190], [33055, -663], [12248, -2946], [34176, 1288], [-7479, 3487], [3782, -2970], [-42192, 1794], [-4350, -1602], [6366, 5622], [-7118, 4302], [2556, 3296], [-3072, 2610], [-7275, 691], [-30227, 411], [-49761, -619], [34170, 1836], [35508, -1760], [3984, 870], [5256, -1712], [-29130, 1354], [-49305, 45], [-11852, 6144], [3183, 533], [-12969, 5637], [28245, 3827], [44292, -1062], [-6128, -102], [2439, -703], [-888, -2248], [-45348, -2742], [-9108, -84], [20556, -3720], [37002, 1734], [-22212, 1016], [-19017, -5195], [804, 1748], [-6105, 2589], [-15546, 1716], [-1626, 4118], [17510, 2472], [-21087, 1099], [9796, 2292], [-35484, -2672], [15300, -548], [-16032, -808], [-30332, -60], [33813, -2181], [42617, 351], [6132, -2154], [60398, 756], [-34530, -3598], [32494, 4980], [-37832, 1416], [-18756, -1160], [-40424, 2730], [-44493, 4693], [70581, -1197], [16698, 678], [8621, -4977], [69590, 468], [2418, -134], [53188, 4260], [-32658, 6156], [6978, 690], [-44352, 3232], [-59070, -90], [5032, -330], [-30663, -3669], [-27552, -4496], [-45711, -1245], [2604, 648], [-15900, -1076], [33936, -7338], [83463, -3135], [65544, 160], [3618, 4302], [-96, 6004], [27722, 8058], [-36183, -3417], [20290, -4572], [-24279, 3135], [35703, 2337], [83646, -3438], [-5337, -395], [-13721, 5445], [10480, -4590], [-72498, -3282], [-2733, -5079], [17640, 960], [-41274, 1194], [-33327, -1245], [-23892, 7560], [26934, 382], [99681, 63], [90384, 252], [-25776, 5526], [102861, 2827], [-11074, -7554], [-41016, -6390], [15306, -1790], [-4980, -7680], [34878, -2686], [-3724, 8844], [62850, 2574], [64206, -5486], [6343, 1893], [50416, -2106], [75724, 2046], [46656, -5068], [-29532, 8236], [-48170, 2106], [41676, 6124], [24654, 5286], [-65844, -5544], [77991, 177], [91274, 1512], [-33404, 2586], [4146, 3798], [45399, -10559], [101868, 4794], [-65352, -6788], [-43798, 10764], [36084, 9728], [-31754, -4416], [-95553, 1301], [-10440, -6072], [3081, -1061], [61512, -5276], [57936, -7828], [-9348, -2612], [32880, 8106], [-37950, 5382], [22451, 321], [50810, -2118], [-19890, 2832], [-82071, 7395], [20748, -10440], [23879, -903], [-15768, 4710], [84, 14172], [-82660, -666], [-57834, 5448], [-50776, -6396], [20409, 2415], [-82026, -8454], [22920, 5380], [60729, 1527], [77814, 5786], [63978, 1476], [36642, -3702], [6836, -7470], [-15117, -4423], [-74556, -636], [80126, -516], [34722, 1398], [22174, -15138], [-19914, 10062], [57083, -771], [-65252, 6294], [10218, 2220], [17368, 14322], [13002, -7426], [136536, 4468], [26398, 11118], [129024, -5420], [19842, 6840], [18855, 8401], [-18606, -9426], [-137574, -5298], [-14522, 3048], [128254, 4920], [5817, -1717], [-40844, 6732], [-102144, 618], [109967, -5307], [-64164, 6912], [70868, 11424], [112920, -6376], [133911, 3621], [65886, -9794], [-71864, -13662], [115332, 546], [94260, 9764], [61694, 5136], [16737, -4985], [-23364, -16084], [35760, 820], [42474, -4632], [-146657, -111], [6190, 2544], [30531, -3931], [179351, 1041], [-43557, 13593], [22692, -6864], [-104044, -3390], [-50367, 4211], [29990, 2418], [71708, 11262], [-121095, 8019], [29538, 11050], [-28817, -5919], [55880, -10794], [100242, -9346], [-22880, 19926], [147336, 2604], [76589, -9141], [-43572, 9236], [-50091, 2187], [-76122, -750], [18639, -5291], [-36446, 10392], [17988, -3300], [210930, 240], [-37956, 13920], [171936, -7264], [-12144, -13128], [125616, 7540], [111454, 3486], [58140, 15036], [-61048, 4998], [-1623, 16899], [5463, -10419], [-44334, 13018], [80683, 11589], [-116682, 12096], [-43464, 15888], [-78783, 4015], [-2442, 6534], [68340, -6546], [-19374, 4194], [68274, -2544], [150158, -12198], [57087, -1199], [-66435, -17961], [58536, 15088], [-14384, -810], [120102, 2316], [128472, -4332], [147504, -12516], [-74028, -10260], [30508, 23574], [251113, -1533], [171316, -8448], [-45952, -14730], [-65931, 8031], [-62339, -17997], [-18066, 25658], [-92871, 9383], [-22716, -3444], [246032, -1446], [-5382, 2378], [-158885, -795], [-75120, -14356], [-45636, -8980], [181179, 11089], [-82095, -813], [-54622, -14028], [-29220, 2400], [103572, 6452]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2352_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_2352_4_a_by();".
// 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_2352_4_a_by(:prec:=2)
    chi := MakeCharacter_2352_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_2352_4_a_by();".
// 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_2352_4_a_by( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2352_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![-104, 6, 1]>,<11,R![-1016, 2, 1]>],Snew);
    return Vf;
end function;