
// Make newform 840.4.a.o in Magma, downloaded from the LMFDB on 03 January 2026.
// To make the character of type GrpDrchElt, type "MakeCharacter_840_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_840_4_a_o();".
// 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_840_4_a_o();".
// 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 := [-720, -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_840_a();"
function MakeCharacter_840_a()
    N := 840;
    order := 1;
    char_gens := [631, 421, 281, 337, 241];
    v := [1, 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_840_a_Hecke( : Kf := Kf)
    return MakeCharacter_840_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], [5, 0], [-7, 0], [-11, -1], [-11, 1], [-14, 0], [107, 1], [-70, -2], [294, 0], [67, -3], [88, 6], [120, 2], [-4, 8], [96, 0], [339, -5], [266, -6], [114, -12], [100, 8], [403, 5], [-313, -13], [-236, -4], [176, 12], [-890, 4], [509, 5], [528, -18], [968, 0], [-528, -12], [1000, 14], [-113, 35], [-816, -32], [-960, -4], [981, -27], [703, 21], [-1184, -18], [-122, 2], [1007, -9], [624, -4], [1320, -32], [4048, 6], [165, 39], [1396, 26], [-399, 15], [946, -48], [1225, -11], [-1013, 77], [2968, 20], [-4178, 2], [-2656, -20], [2034, -20], [283, -1], [-2989, 29], [3992, -6], [-2626, -90], [-1864, 74], [-3904, 72], [-1224, 126], [-2423, -57], [3944, 6], [-3072, -54], [-2176, -108], [-908, 10], [-4842, 102], [-584, 80], [-4831, -23], [-6473, 47], [-2192, -92], [4354, -144], [-7674, 46], [1102, 56], [-2110, -96], [1765, 115], [-7746, 2], [-6374, 116], [-3926, 154], [9920, -16], [-3492, -62], [5353, -179], [-982, -56], [-9562, -28], [-3316, -80], [2342, 56], [675, -83], [6493, -107], [11859, 85], [-9218, -138], [-3802, 220], [-5528, -142], [-6926, 68], [-3988, 212], [2116, -40], [3756, -140], [-9900, -172], [3389, 151], [-726, 194], [-740, -132], [-16852, 26], [1164, 270], [-6090, -82], [4506, -20], [-11496, -76], [-3165, 147], [-2856, 132], [-8854, -320], [15538, 114], [-8623, 273], [-3628, 176], [-978, -252], [581, 163], [11984, 58], [-122, 394], [12508, -126], [3015, -45], [-5133, -191], [24024, -112], [-16344, -38], [-15298, -114], [6408, -32], [10725, -15], [6735, -35], [20898, -180], [23092, 46], [15268, -38], [6078, 198], [20149, 119], [19254, -240], [-16226, -32], [17390, -190], [-4998, -386], [5337, 77], [-21614, 234], [1992, -480], [-5380, 20], [11754, 228], [10042, -272], [8740, 30], [-27824, -242], [-10710, 498], [4172, 282], [-5312, -390], [16475, -263], [-13362, 480], [-13088, 216], [-4840, 316], [4988, 234], [28766, 250], [-36115, 33], [-17484, -426], [11789, -329], [17602, -178], [25972, 322], [19178, -216], [6232, -700], [7700, -604], [-22056, 44], [-19891, -541], [-24864, 456], [23138, 384], [9871, -693], [-7218, 648], [-22546, 78], [7443, 503], [42124, 60], [17346, 338], [-5461, -217], [19216, 424], [-1312, 384], [3577, 69], [-37472, -270], [18660, 266], [-10375, 491], [-17684, 186], [49003, -19], [-30186, 4], [18973, -557], [8712, 258], [-10420, 824], [13652, 362], [-12874, 466], [-38144, 118], [-31192, -56], [-12914, -274], [21354, -108], [11902, -740], [4316, -1084], [-26840, -666], [7188, 50], [-16762, -602], [-6564, -34], [12982, 874], [-4291, -539], [-1068, 144], [-14210, 238], [-25234, 120], [13922, -22], [-20318, -488], [8608, -206], [-72122, -96], [8656, -142], [7656, 352], [-54202, 560], [-6665, -295], [7015, -345], [2824, -678], [54626, -398], [-3580, 386], [7861, 331], [-6224, -868], [-64436, -434], [-31139, 663], [30820, -434], [5724, -462], [-26388, 172], [45620, 64], [48326, 562], [-22420, -498], [9324, 1172], [-26630, -520], [47068, 380], [13505, -1147], [19934, 576], [-9609, -1103], [-8272, 338], [-2016, 1568], [-54320, -244], [10400, -626], [9596, 206], [-43703, 503], [-3852, -268], [-4911, 387], [-48274, -696], [24007, -251], [4366, -206], [23644, -898], [-44762, -66], [-25924, -508], [-10486, 104], [36241, -1379], [-88031, -349], [-80886, 270], [25364, -568], [1255, -483], [42004, -1068], [-29588, 1386], [47120, 418], [59938, 1126], [21326, -318], [-3800, 1588], [24728, -516], [-28262, 806], [29616, -394], [42242, 1280], [15498, -1506], [31126, -380], [-7616, 438], [34117, 1063], [72768, -338], [7176, 748], [-12444, 90], [108141, -163], [-24496, 448], [-59562, -938], [60778, 468], [-71173, 619], [-58926, 720], [-53447, 483], [8962, 148], [13404, -242], [23432, 620], [41853, -191], [-23640, -530], [25912, 1316], [15861, 181], [106488, -504], [7901, -875], [-83486, 598], [-3944, -260], [25238, -1072], [-68942, -216], [-11606, -382], [51492, -1428], [-5928, 544], [22292, -92], [-48408, 534], [71070, -26], [-61095, 663], [-8648, 442], [-26273, 1423], [78627, -283], [8522, 2200], [-11846, 2396], [-79744, -1220], [33715, -617], [-27588, 1368], [-90526, -396], [-17502, 2244], [-16539, 1627], [-1002, 216], [-74926, -462], [-170, 2774], [25959, 403], [37021, -1223], [-7638, 422], [-88918, 1298], [22170, -2710], [-18446, -16], [-6836, 152], [36314, 156], [-64017, -1575], [-7534, -1108], [-53156, -636], [67238, -1688], [19618, -1408], [120912, -676], [-61862, -338], [30088, 1522], [30560, -756], [-126195, 627], [-145243, 573], [-79826, 1604], [141833, -189], [51056, 1818], [-10698, -3024], [-147568, 288], [-21951, 2073], [-18352, 1218], [76654, -1810], [-49416, 1052], [167530, -506], [48919, 455], [-68424, -1794], [24641, -1947], [-10007, -3433], [8536, 244], [-54864, -732], [-65232, 772], [-51606, 92], [-29992, -310], [83468, -1618], [72762, -2234], [-72226, 48], [-103977, -525], [50840, -250], [-61546, -1662], [-38447, 1845], [-69745, -2483], [-96230, 1092], [57164, -1128], [-20166, 438], [-26804, 2210], [23915, -1423], [94716, -1442], [-57258, -1248], [-121080, 632], [-77796, -1006], [91734, -396], [-23382, -1034], [-104276, 1096], [-142689, 915], [-95252, -340], [25622, -664], [14616, 1218], [105508, -100], [126563, 1185], [108794, -1134], [-53728, -2662], [-18602, 64], [-69604, 76], [140794, -1840], [-49631, 1179], [-36487, 187], [-8812, 3756], [-137404, 1898], [143353, 463], [-74328, 830], [126384, -228], [-146731, -1141], [95621, -131], [-133852, 1582], [-139441, -1413], [219712, -250], [89179, -1313], [-39748, -1412], [7125, 2413], [71547, -287], [53088, -120], [980, -900], [-4435, -2879], [182200, 1468], [-106640, -32], [84404, 2574], [-103882, 104], [36227, -239], [-150494, 1402], [-119265, 2217], [16778, 0], [136557, 691], [81170, -2264], [30286, 3494], [117250, -1940], [-104172, -2542], [-64541, -1729], [56248, 296], [13616, -3238], [139494, 408], [-45883, 3283], [233936, 998], [11598, 1988], [-40120, -2092], [-7706, 3766], [-88601, 299], [184623, 63], [-25358, 1890], [57144, 2980], [93778, -2008], [-63216, -1722], [86779, -1883], [-137366, -994], [-20450, 916], [-136380, -780], [-19172, -2934], [-35383, -523], [65692, 1540], [-94122, -2514], [-13799, -3231], [14936, 4318], [74964, 2216], [-236530, -644], [-216523, 879], [96606, 906]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_840_a_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_840_4_a_o();".
// 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_840_4_a_o(:prec:=2)
    chi := MakeCharacter_840_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_840_4_a_o();".
// 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_840_4_a_o( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_840_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<11,R![-2760, 22, 1]>],Snew);
    return Vf;
end function;