
// Make newform 2400.4.a.bb in Magma, downloaded from the LMFDB on 15 April 2026.
// To make the character of type GrpDrchElt, type "MakeCharacter_2400_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_2400_4_a_bb();".
// 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_2400_4_a_bb();".
// 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 := [-22, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-2, 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_2400_a();"
function MakeCharacter_2400_a()
    N := 2400;
    order := 1;
    char_gens := [1951, 901, 1601, 577];
    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_2400_a_Hecke( : Kf := Kf)
    return MakeCharacter_2400_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], [6, 1], [-12, 2], [-4, -3], [-28, 3], [-30, -3], [42, -5], [6, 0], [-66, -1], [52, 21], [70, 6], [252, 0], [174, -7], [342, -6], [-444, 14], [-86, 30], [780, 4], [-72, -32], [282, 18], [42, 25], [756, 28], [14, -54], [-74, -12], [-970, -36], [-666, -35], [1680, -26], [1638, 12], [1388, -9], [-90, 97], [-72, 28], [312, -87], [582, -89], [-674, 120], [1110, 3], [-2280, 27], [-924, -164], [138, -161], [1090, 108], [2928, -4], [-82, -84], [3144, 0], [2082, -54], [3582, 54], [2382, -29], [990, -153], [-5118, -45], [1092, 280], [338, -90], [2224, -123], [4068, 106], [-1222, 36], [432, 224], [1708, 255], [-2658, 77], [-5178, -48], [3774, -33], [-1856, -261], [3918, 66], [204, 336], [-154, -6], [3240, -206], [-3780, -110], [-702, 246], [2814, -150], [-2154, 11], [-702, 234], [9144, 162], [3186, -246], [-1440, 57], [-6048, -272], [8898, -177], [-6712, -153], [6858, -71], [-3378, -203], [-882, -408], [-11852, 81], [6130, 0], [-5494, 504], [14112, -116], [-2638, -546], [-1128, -256], [1106, -486], [-10122, 215], [4188, -488], [-3830, 300], [3262, 204], [2574, -12], [-5538, 753], [3552, -530], [-3264, 576], [11034, 163], [-2412, -710], [16182, -81], [-978, 69], [-538, 144], [4610, -900], [10416, -342], [-970, 180], [-9108, 396], [5066, -48], [552, 854], [12098, 12], [-2226, 871], [-2866, -552], [9864, 762], [-13260, -261], [-10656, 8], [-15238, 552], [-9102, -953], [3116, 369], [-4160, -1059], [5670, 911], [4242, -255], [13814, 642], [-1140, -976], [-9918, 67], [3506, 1284], [19500, 570], [-23318, 138], [8602, -186], [11114, 852], [16272, -454], [-4482, -601], [15326, -924], [4490, -222], [-2292, -554], [-13662, 543], [17456, -609], [15246, -1261], [-14862, -1009], [20238, -105], [-11816, 567], [1042, 1452], [-10830, 816], [-618, -1518], [-4248, 642], [4698, -864], [-17730, 618], [-22146, -257], [21574, 84], [-4962, -1335], [-4932, -1540], [16198, -1452], [-25032, 260], [13412, 597], [14172, 1587], [-14478, 789], [-5310, 2103], [-39208, -141], [9486, -618], [29292, -520], [-23358, 467], [16584, 306], [16020, 862], [-23466, 567], [-26702, 480], [-43018, -144], [16942, -1692], [-5424, 1974], [11448, -1647], [-23790, -561], [-15096, -988], [-12684, -1365], [3186, 823], [-5718, 1557], [-2816, -2613], [27242, 1908], [-12798, 2568], [-14436, -494], [-28794, -1068], [-16704, 1732], [-43486, -522], [-42414, -475], [-29610, -450], [11082, -747], [11318, 1044], [18330, -1137], [-21130, 1500], [-11850, 537], [-17028, -2090], [23000, -753], [25092, -1809], [31782, -39], [-20346, 564], [-60316, 585], [-2472, -450], [35674, -696], [-2112, 548], [-14558, -270], [-3480, -2810], [-18402, 1567], [-26634, 1704], [-59148, -128], [39540, -57], [-28126, 2064], [-12436, -1107], [-17852, -1029], [-10542, -465], [-28994, 924], [-10662, 573], [33916, 1545], [-2798, -2232], [-22488, -1048], [34662, 2574], [-25266, 795], [-46464, 1034], [-54498, -1878], [46842, 1301], [-77670, -450], [19134, 312], [-11898, 821], [-34284, 688], [4236, -1522], [28602, 2472], [12714, 3243], [11466, 2364], [-47562, -2059], [-32494, -3348], [-61502, 1542], [28374, 3967], [-13226, 1914], [26094, 705], [21744, -1610], [-13066, 1488], [44148, -1905], [-26196, 254], [-51762, -2835], [70800, -1584], [12836, 3969], [-21978, 271], [28014, -1145], [-27546, -1818], [-3792, 2354], [62922, 407], [-13046, -3828], [-58734, -1344], [20952, -4584], [-40632, -2272], [26784, -846], [58374, -885], [27030, 3773], [56762, -2586], [66480, -903], [69828, -590], [84618, -901], [2988, 3470], [-29142, -2343], [35082, -2285], [19352, -4605], [-16038, -2340], [-2898, 2297], [45874, -2340], [22958, -2022], [-41292, -3482], [-54570, 3312], [21528, 2058], [-14322, -3330], [9938, -2850], [46098, -3821], [-1176, 4626], [-57134, -1962], [-53684, -2619], [-40616, 1557], [13110, 3375], [74222, -2268], [39522, -300], [-52272, -2478], [10530, -2496], [-81826, -1464], [82296, -1790], [40378, -1110], [24810, -3871], [78962, 66], [-26178, 1593], [43440, 3174], [-22358, 1638], [68098, -2028], [-105552, 1432], [52902, 4385], [-74694, -539], [22050, 1099], [-16522, -5664], [110856, 2162], [18528, 1892], [-54746, 996], [-36582, 1044], [75162, -1863], [13250, 3288], [-16810, 2640], [108564, 1200], [-1408, -2571], [-24792, 3700], [53940, -207], [54934, 888], [52338, -1583], [-92786, -1722], [-46224, -3948], [43260, -3924], [-36014, -186], [66306, -3252], [65526, 959], [4632, 4174], [101130, -2667], [43262, 4248], [133716, -1432], [-18174, 2130], [146484, 298], [-7512, 735], [-31470, 4023], [29710, -4080], [74826, -3036], [-102168, -410], [-73458, 17], [19466, -3744], [-54912, -5220], [43548, -790], [46074, -3906], [-18454, -8316], [-142902, 213], [131122, 2862], [19086, 3756], [-60798, -2517], [-46612, 3315], [30866, -7296], [85926, 1263], [-66516, -5152], [46578, 35], [-8550, 4572], [138698, 2334], [65058, -2556], [38310, -6657], [-109008, -1486], [70386, 5425], [68892, 4548], [32598, 852], [-84344, -1059], [-41102, -3156], [25806, 813], [-83320, -3081], [-155524, 2979], [107646, -3144], [-52086, 661], [-11994, 5022], [119652, -522], [131938, -3546], [17076, 3000], [8940, 1970], [6918, -990], [78210, 657], [-111154, -5580], [-15330, -7188], [64650, -6625], [-155262, -2274], [4728, 2385], [73704, -3364], [50016, -504], [-15280, -8343], [-29562, 4889], [-49016, -2385], [123082, 2928], [150546, -3845], [81672, 7288], [-87444, 2684], [-98274, 4068], [58686, 4386], [52290, 4987], [482, 8868], [6792, -9108], [-63774, -2715], [31878, -2831], [-24290, 4368], [-153378, 4551], [-12240, -2241], [-88188, 6198], [130476, -1286], [-33354, 1932], [-142638, -3336], [91686, 1560], [-119826, -1668], [217736, -2319], [-68442, 4113], [-107088, 2769], [-17634, -7077], [79974, 7489], [10110, 3991], [7504, -573], [-60960, -2190], [154554, 3951], [-44358, -7836], [108466, -5592], [-74868, 5298], [-26520, 3986], [-138840, 1920], [27470, 8892], [-191718, 249], [-63018, 2982], [29562, 10893], [-221442, 888], [6278, -852], [89776, 5841], [-2346, -1055], [-152448, -3531], [-4194, 5016], [-47838, 10233], [70784, -2241], [-60830, -1752], [-16044, -6612], [-30864, -8972], [96758, 756], [192474, 804], [62784, -3662], [67206, 10771], [32634, -4014], [15582, 7764], [-149760, -1664], [77478, -9367], [172528, 2361], [33834, -3981], [-125818, -6288], [552, 639], [2730, 4559], [-123684, -5982], [-20486, -10998], [194030, -5526], [22788, 4092], [10482, -4668], [91074, -9335], [-102768, -11048]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2400_a_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_2400_4_a_bb();".
// 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_2400_4_a_bb(:prec:=2)
    chi := MakeCharacter_2400_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_2400_4_a_bb();".
// 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_2400_4_a_bb( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2400_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<7,R![-320, -12, 1]>,<11,R![-1280, 24, 1]>],Snew);
    return Vf;
end function;