
// Make newform 2166.4.a.u in Magma, downloaded from the LMFDB on 20 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_2166_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_2166_4_a_u();".
// 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_2166_4_a_u();".
// 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, -32, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0], [-1, 2, 0], [-85, -6, 4]];
    Rf_basisdens := [1, 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_2166_a();"
function MakeCharacter_2166_a()
    N := 2166;
    order := 1;
    char_gens := [1445, 1807];
    v := [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_2166_a_Hecke(Kf)
    return MakeCharacter_2166_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 := [[2, 0, 0], [-3, 0, 0], [3, -1, 0], [2, -1, 0], [-15, 0, -1], [-1, 6, 0], [-30, -7, 1], [0, 0, 0], [3, 9, 2], [36, 15, 1], [-28, 24, 1], [77, -17, 3], [-222, 20, 2], [-28, 21, -2], [102, -10, -6], [-435, 18, -1], [81, -9, 0], [-157, -32, -4], [-244, -12, -1], [-18, 19, -11], [-217, -66, -4], [-172, -30, 3], [846, 37, 5], [543, 34, 11], [320, -13, -1], [-324, -9, 11], [-892, 33, -4], [-528, -13, 15], [-478, 1, 7], [-117, 50, -9], [26, 46, -20], [210, 29, -5], [-282, 193, 15], [-1906, -37, -24], [-555, -235, 10], [-1402, -96, 18], [-577, -123, -17], [182, -136, -11], [-1077, -99, 24], [-288, 65, -5], [-2217, -233, 32], [2192, 17, -19], [-1449, 40, 15], [269, -159, -19], [2757, -82, 9], [-694, 222, 9], [-112, -155, 28], [338, -254, -31], [-2307, 248, -19], [-2329, -100, -14], [-972, 211, -13], [1443, -32, -25], [-865, -36, 34], [864, -298, -72], [483, 386, -27], [-738, -307, -89], [315, 232, 65], [-2776, -40, 8], [3056, 143, 95], [-705, 409, -54], [-532, -392, -80], [-6534, -196, -8], [4562, 331, -17], [2775, 133, -48], [-394, -489, -51], [-3219, -223, -20], [-5464, 93, -6], [2501, 663, -107], [-4263, 140, 5], [2885, 310, 120], [885, 321, -60], [2268, 244, -28], [-9622, 228, -11], [6032, 615, 3], [-7558, -673, 30], [165, -736, -37], [-2235, -218, -73], [1949, -230, 80], [-4503, -272, 63], [2570, -505, 101], [7815, -446, -73], [2738, -255, 51], [-7398, -472, 16], [-2137, 511, 77], [-5320, -627, -30], [1260, 177, 127], [-2388, -467, 135], [-7495, 707, -35], [939, 130, 43], [-2572, 215, -112], [-2922, -556, 194], [7626, 491, 65], [11102, -682, -88], [5574, 857, 135], [1460, -76, 233], [-10584, -661, -47], [3786, -754, -62], [-7227, -447, -10], [-3514, 1114, -139], [-835, 977, 43], [-12196, -363, -182], [5190, -1797, -131], [2820, 733, -43], [2262, 540, -182], [-11302, -1252, 115], [3854, -627, -21], [18513, 275, 88], [2121, -1752, 7], [4575, -570, 171], [7595, 1599, -83], [-14422, 652, 107], [-3460, -1129, 167], [-3417, 315, 210], [2942, 1278, 205], [12458, -19, 82], [-12648, -648, 102], [-1816, -562, 35], [18912, -979, -33], [5772, -1511, -223], [3279, 260, -3], [-706, 1508, 296], [14831, 879, 189], [6498, -794, -54], [11355, 250, 69], [260, 16, 64], [-7323, 1173, -64], [797, -1658, 250], [-5457, 1979, -208], [-8584, 254, -493], [5912, 241, -371], [-12184, 1916, -53], [10959, 232, -131], [-14272, -715, 292], [7145, 1230, 202], [13461, 1536, -153], [-6289, -2062, -214], [8724, 484, -94], [2006, -1518, -311], [14736, 331, 407], [7899, -1043, -310], [28790, 640, 202], [-21240, 711, -195], [-5362, -594, -396], [3156, -1893, -463], [20165, -1220, -20], [-8085, 3780, 179], [-20647, -1347, 137], [17442, 92, 76], [8564, -212, -69], [4866, -1172, 344], [-11299, -1877, -117], [-4767, 1151, -62], [-22336, 311, 32], [11043, 2305, -240], [-19852, 2376, 216], [18858, -1320, -114], [-45460, 501, 42], [-8127, -1477, -402], [-9547, 4289, 145], [10416, 666, 190], [1038, -2069, 65], [-4005, -1283, 424], [-18208, -1374, -199], [-7890, -1368, -100], [-2880, 104, -198], [-24243, -602, -55], [-19486, -1860, 277], [4115, 317, 239], [26978, 2102, 50], [9510, -5140, -218], [28623, -129, -270], [-19297, -420, -504], [21948, -2225, 95], [1505, -5143, 7], [27356, -1757, -326], [-55194, -102, 30], [8510, -2087, 368], [27474, 104, 16], [-10618, -253, 56], [-25297, -73, -335], [482, -379, -355], [-5238, -2441, 231], [-457, 1205, -427], [18105, -4000, 53], [-23052, -21, 447], [15234, 146, 586], [4970, -5343, -117], [20876, -4262, -303], [32078, 735, 717], [-8571, -158, -763], [20729, -64, -160], [-19206, -3012, 446], [-490, 3553, 444], [25308, 974, -452], [20331, 2363, 236], [22038, -3676, -482], [4340, -4545, 387], [2741, 2863, -59], [7548, 23, 405], [-14616, 906, 204], [9297, -2333, 56], [-26374, -379, 449], [19757, 4226, -250], [1049, -107, 563], [-753, -687, 602], [-16806, 1476, 542], [-12886, 1374, -444], [1122, -466, -68], [30048, -522, 390], [-11266, 1766, -215], [-30049, -2059, -473], [27840, 1755, -793], [-42994, 3558, -49], [-7737, 4448, 589], [-1647, -985, -686], [-6823, 1386, 188], [-64702, 1684, -134], [27069, 6998, -689], [22464, -7635, -485], [31035, 5462, -245], [-23683, 4978, 490], [-36442, -1983, 228], [12753, -5208, 161], [3530, 4709, -422], [8826, -2666, -80], [24701, -3740, -554], [2958, -2986, -630], [28473, -5215, 214], [5690, 4974, 432], [-25590, -1546, -716], [5591, 2867, 15], [9596, 3122, -695], [14858, -71, -611], [11880, -2359, 191], [-28474, -1422, -324], [3315, -4046, 311], [11525, 2725, 655], [12852, 258, -190], [27258, -5642, -464], [58425, 1860, -111], [54225, 32, 5], [-39622, 3158, -208], [72944, 3276, 121], [2801, -3091, 193], [36933, 5017, -778], [-26070, 3681, 405], [-14224, 500, -1060], [-48291, -1083, -250], [-3622, -980, -157], [-46785, -654, 159], [15275, 6875, 287], [-51693, -423, -1450], [15222, -4421, -185], [-104056, -2187, 165], [41973, 6639, 80], [-11856, -7749, -83], [37565, 8184, -304], [-26350, -2494, 589], [-27528, 1962, 414], [32009, 3535, 819], [-4048, -2293, -298], [38499, -2907, 564], [-38071, -1008, 728], [-37519, -1795, 897], [-51405, 3600, -735], [51440, -4742, 201], [-38202, 5915, 199], [31050, -10106, -448], [7898, 4522, 785], [-28230, -30, 0], [-70441, -2068, -36], [-25402, 4205, -715], [-23482, -542, 970], [-38896, -5004, 780], [57539, -2959, 589], [-25390, -5688, 623], [-21564, -3370, 1348], [-45553, -4022, -210], [8861, -3014, 1296], [-33582, -2252, -604], [56031, 2643, 168], [34358, 1448, 338], [77349, -2776, -239], [45701, -8157, -937], [-44914, -1633, 131], [-528, 349, 251], [8753, -2114, -1010], [31071, 5637, 306], [-712, 5718, 289], [5496, -6305, -881], [53196, -3016, -1250], [17373, -4480, 1465], [44994, 5727, -231], [-39846, -5676, -796], [39563, -12171, -921], [-29499, -518, 961], [-40930, -5610, -948], [18837, 6674, 621], [35175, 2406, 883], [15854, 5926, -293], [-47632, 6443, 755], [29046, 4524, 1976], [-44434, 2703, -890], [-74172, 150, -16], [-17512, 6077, -1296], [-93013, 2906, -668], [49128, 5206, 908], [-32161, -2432, -1966], [-115029, -1628, 443], [13031, 10989, 159], [48300, 2405, 1133], [-96885, -3398, 539], [67308, -6491, -795], [-35086, -3779, -2486], [-69303, 5, 148], [9782, 4531, 1117], [-31635, 795, -36], [-4566, 2674, 30], [3533, -314, 278], [41211, 578, -1597], [10466, -4503, -134], [-48919, 2701, -155], [-73002, -90, -36], [-34582, -5396, 1295], [-80091, 8223, 1242], [119531, -1084, 1194], [45506, -12598, -1495], [133832, 2099, -346], [-99165, -1707, 856], [53352, 11528, -1788], [-47647, -2007, -2033], [56766, -868, -302], [-18430, -414, 1320], [-75387, 16049, 1160], [-54118, 10234, 616], [-37443, 8187, 2], [40049, 11901, -1675], [72108, -556, 382], [63761, 1705, 1487], [-68452, 1937, 548], [-98176, 4151, -1141], [-759, -11139, 624], [-723, 3248, 1603], [-96478, -6180, -354], [-55581, -3448, 393], [131421, 4950, 403], [-44164, -1157, -929], [-46468, 2866, 1102], [4269, -13178, 343], [58779, 2832, 1455], [132926, 4621, -894], [46979, -2100, 1170], [95424, -2365, -1467], [-76312, -6566, -1586], [86654, -1404, -696], [-123864, -898, 968], [-113661, -2742, -241], [39237, 12479, -626], [-61929, 10162, 1647], [-17292, -9851, 251], [-202, 4283, 2525], [-75747, -326, -1025], [80409, -6371, 938], [48831, 3683, -738], [-32614, 4233, 129], [-49930, 7437, -801], [9087, -520, 1633], [-121324, -7193, 622], [-144223, -1312, -1378], [-16491, 5818, -1525], [-136870, -6043, 198], [-81486, -5721, -1729], [-88728, 4786, -804], [217466, 2280, -315], [33839, 3891, 1719], [-56607, -5611, -720], [-96711, -910, 9], [45128, -9651, 57], [104289, -13926, -1173], [-18361, 17127, -685], [-39333, -12544, -833], [87468, -432, -538], [27950, -289, 1691], [-11328, -13205, -2197], [92138, -10919, -1844], [18270, 4165, -941], [15554, 3416, -199], [-10912, 6359, 479], [-70060, -10768, -928], [19236, 11977, -2331], [-14557, 13630, -724], [-148572, -7228, 1266], [-21384, 15558, 792], [75380, 21043, -1554], [315, 13719, 840], [57224, -1377, -669], [-64642, 5032, -441], [-13449, -8491, -2586], [-119920, -9518, -1281], [-21942, 9117, 357], [-7135, -10927, 1981], [-130503, -4144, -1195], [-38710, 13141, -791], [-44712, 1200, 1558], [-112800, 9195, 1371], [133700, 9577, -754], [-101527, 10634, -874], [-77103, -17990, 1687], [-46300, -1144, 1616], [-145083, -5239, -1434], [-39043, -12333, 703], [56061, 12063, 222], [60543, 6735, -824], [67280, 7789, 1850], [-26374, -271, 1487], [-34821, -4713, -18], [19647, -1051, -3314], [115634, -5094, -48], [110847, -6950, 935], [8415, 12379, 2340], [198807, -987, 390], [145211, -236, -28], [74541, -1173, -1468], [20967, 443, -2098], [18221, 14854, 336], [163893, 14023, -316], [-10335, 11888, 195], [4044, -2976, -1046], [53090, -6663, 2346], [-9696, 2886, 380]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2166_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_2166_4_a_u();".
// 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_2166_4_a_u(:prec:=3)
    chi := MakeCharacter_2166_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_2166_4_a_u();".
// 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_2166_4_a_u( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2166_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![504, -96, -10, 1]>,<13,R![-37685, -4629, 9, 1]>],Snew);
    return Vf;
end function;