
// Make newform 2100.4.a.q in Magma, downloaded from the LMFDB on 05 February 2025.
// To make the character of type GrpDrchElt, type "MakeCharacter_2100_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_2100_4_a_q();".
// 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_2100_4_a_q();".
// 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 := [-27, -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_2100_a();"
function MakeCharacter_2100_a()
    N := 2100;
    order := 1;
    char_gens := [1051, 701, 1177, 1501];
    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_2100_a_Hecke(Kf)
    return MakeCharacter_2100_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]];
    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], [0, 0], [7, 0], [27, -2], [37, -5], [49, 5], [21, -9], [29, -16], [124, -5], [108, 10], [121, -18], [-96, 8], [12, 37], [291, -11], [-56, 18], [-373, -27], [26, -14], [342, -3], [-505, 10], [-379, 13], [-710, 15], [308, -102], [195, -11], [412, 66], [-45, 27], [-999, 19], [208, -80], [-261, 90], [-392, 167], [584, 123], [-1065, 71], [2340, 42], [1539, -13], [-300, 21], [-2594, 65], [768, -236], [2106, 50], [933, 135], [-725, 293], [-1168, 128], [-2041, 67], [1914, 102], [891, -334], [2342, -219], [1816, 152], [-3072, -184], [-2441, 311], [623, 189], [-948, 242], [-1068, -135], [586, 530], [535, 285], [3367, -293], [3240, 334], [-1265, 560], [2732, 230], [-545, 457], [3830, -52], [-656, 75], [6156, 146], [1031, -263], [-2865, 127], [-2055, -651], [2279, 481], [4136, 559], [-9834, -73], [-5360, 482], [603, -424], [2309, -677], [3762, -36], [4725, -640], [6944, 468], [5273, 280], [1546, 79], [5251, -659], [8202, -163], [4830, 160], [326, 477], [1117, 391], [5962, 796], [-639, -206], [-3768, 1104], [6546, -82], [-2475, 1295], [-734, 78], [-3364, 557], [-2273, 26], [865, 335], [-3494, 474], [5302, -376], [-4331, 115], [-392, 21], [-8749, 902], [-5812, -1024], [-7848, -258], [435, -119], [18278, 136], [600, -1880], [-9425, 100], [-5612, -401], [-10114, 1237], [-7608, 1366], [-2832, -141], [-9136, 581], [1895, -123], [-6209, 1523], [14510, -1162], [2507, -124], [-6298, 518], [-18861, 397], [6019, -644], [23676, -23], [5687, -1191], [-1986, -437], [14936, -293], [-14064, -44], [-13226, -1044], [-7200, -554], [2392, 668], [7331, 601], [-15082, 756], [-872, 46], [-19485, -764], [-14650, 166], [18988, -190], [-24834, 140], [10982, -1582], [-10183, 1001], [12444, 2176], [2244, 935], [-31654, 74], [2894, 162], [-5673, 1648], [30342, 798], [-16886, 1662], [2886, 612], [-23569, 567], [15003, 483], [7272, -363], [1450, 1088], [15150, -180], [8716, 1427], [-4549, -240], [-24393, -1661], [-203, -2115], [17754, 770], [-5818, 230], [-9360, -1458], [-25145, 2088], [-21806, 2796], [5772, 758], [-8526, -1287], [-22006, -1470], [-37478, -378], [11113, -1694], [-14756, -2755], [26395, 1427], [-16486, -1214], [40322, -716], [13632, -1220], [4838, 1385], [-32464, -1692], [18021, 2175], [-4416, -3495], [9396, -2690], [-7622, -2337], [-9131, -645], [-13155, 2378], [-13699, 349], [23411, 2560], [-513, -1199], [-7663, 3410], [13546, -380], [36287, -633], [-11985, -4397], [-4020, 4685], [35296, -1886], [-52769, 837], [13894, -2364], [34100, 1801], [39638, 326], [-15505, 220], [49730, 1512], [-32613, -2670], [22350, -1428], [-1753, -4446], [19892, 2710], [-44957, 2574], [20247, 1371], [29730, 1344], [-46261, -746], [-594, -3199], [-9876, 1262], [-1697, -524], [26182, 2590], [29667, 4586], [-15619, -1194], [-7577, -2459], [-14724, 1054], [-47988, 946], [-16030, -1896], [-9766, -6268], [6560, -1540], [-15458, 3034], [-3458, 5486], [12690, 1792], [-70436, -284], [-1374, -6717], [-49810, 1530], [34567, 1636], [26101, -4979], [24198, 1135], [-18338, -250], [85823, 227], [23871, -5669], [-7420, 3693], [29043, -1527], [56741, 940], [10316, -2515], [44237, 2148], [29993, -6675], [-26258, -4853], [-37018, 1973], [-1991, -5185], [-56370, -4220], [35049, -4099], [53053, -1602], [45447, -1745], [-14021, -6750], [44907, 436], [26246, 6128], [16690, -2826], [-782, 6343], [-975, -5405], [-17644, 2174], [59118, -106], [-76304, 1103], [-50351, 492], [-14046, 7186], [32081, 4912], [4349, 6831], [-35918, 1984], [-74385, -3748], [-40497, 4665], [57747, 1539], [104754, -556], [-33598, 2120], [20074, -2458], [59272, -1528], [68684, 6], [-38316, -4668], [20712, -2268], [-26359, -1075], [-54501, 2253], [-18864, -1352], [1571, -5790], [-6349, -7221], [84931, 625], [28601, -7201], [-3972, -8520], [48713, -110], [24174, 7316], [47396, 166], [-14233, -6877], [22776, 2632], [62748, 5541], [-27375, 8729], [-12216, -1967], [103196, -943], [-65188, -2872], [-14964, 2808], [37672, -6528], [-39930, -2637], [6695, -797], [8369, -7871], [60997, 6698], [96836, 4326], [-67307, -878], [92125, 3017], [33451, -10761], [-9784, 8988], [54861, 6795], [44093, -5575], [-58415, 7653], [-87723, 1152], [69915, 2386], [111438, -4623], [58824, 1732], [-63158, 724], [-10790, 10603], [-67490, -7288], [24836, -1235], [-2531, -12747], [54331, -6266], [49503, -6849], [40096, -4932], [-33193, -2747], [122538, -4134], [34964, 5602], [102859, 4255], [131158, -2452], [49956, 7445], [76905, -5022], [-43878, -7781], [88970, 4700], [-36819, -11516], [-30077, 10201], [33189, 7926], [-139922, -3612], [22659, 14043], [-92938, -7228], [-81734, -439], [141480, -1780], [-12987, 5376], [116141, 2109], [-79844, -2798], [9720, -12588], [108100, -1160], [16366, 1257], [101675, -4481], [14994, -5984], [-41035, -6161], [-46784, 5959], [-22176, 6651], [-28996, 15522], [-146624, -3571], [-35978, 3820], [75065, 172], [-56100, -1551], [-51800, -5002], [-33520, 4313], [-298, -8324], [54201, -1839], [-34802, 2618], [-125765, -743], [-64307, -10260], [86079, -7839], [39241, -11841], [3783, -4597], [4866, -4328], [90092, 2857], [-53982, -14634], [-45390, 13315], [-93410, 6991], [-72209, 3530], [-23773, 4643], [-13488, 2281], [-93801, 9357], [-24221, 607], [129537, 4213], [26687, -610], [55236, 5922], [122029, -2913], [22119, -7308], [-112419, 627], [71202, 5124], [21685, -1411], [136776, 3342], [34258, 17698], [-38477, -6594], [-159350, -7500], [-84590, -2890], [32151, -2486], [-31949, 19409], [-76180, 186], [-33422, 15420], [27190, -5317], [158831, 7888], [154107, 7254], [-116158, -1004], [-44035, -2156], [-167748, -930], [-37360, -6534], [60159, -4730], [43142, -1250], [-124421, 6046], [-8671, -13547], [46729, -12749], [-75859, 12545], [-173267, 6065], [-68680, 3931], [-81624, 17931], [-210978, -351], [-53443, 7397], [158958, 4530], [36196, 12235], [-122350, 9556], [-84650, -69], [-130412, -12228], [15723, -6986], [118046, 11104], [-220475, -3448], [-155762, -6872], [-155469, -3854], [-76009, 1752], [32938, -10914], [-222935, -5257], [25578, -15726], [-53532, -12153], [-18385, 5741], [-108180, -9069], [252652, -1393], [42309, 17991], [8425, 11363], [40793, -15197], [-31029, -8338], [-98784, -17874], [2784, -24576], [44994, -1596], [-60523, 9847], [-6380, -12983], [-24126, 8730], [-22890, 6911], [-88513, -2828], [-37963, 7143], [-154592, -13796], [-78435, 6405], [-246616, -2092], [6744, -8642], [-58582, 16320], [-70001, 8931], [18492, -15372], [-111352, -10664], [-56960, -7106], [-123767, -3399], [-7279, 342], [-3096, -14562], [133789, 1413], [30194, -18800]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2100_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_2100_4_a_q();".
// 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_2100_4_a_q(:prec:=2)
    chi := MakeCharacter_2100_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_2100_4_a_q();".
// 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_2100_4_a_q( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2100_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<11,R![293, -54, 1]>,<13,R![-1356, -74, 1]>,<17,R![-324, -98, 1]>],Snew);
    return Vf;
end function;