
// Make newform 600.4.a.w in Magma, downloaded from the LMFDB on 01 May 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_600_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_600_4_a_w();".
// 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_600_4_a_w();".
// 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 := [-45, -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_600_a();"
function MakeCharacter_600_a()
    N := 600;
    order := 1;
    char_gens := [151, 301, 401, 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_600_a_Hecke(Kf)
    return MakeCharacter_600_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], [0, 0], [3, 1], [4, 1], [7, -2], [0, -1], [43, 3], [64, 3], [172, -5], [-79, -7], [18, -6], [-122, -7], [195, -7], [378, 4], [134, 7], [2, 8], [-517, 8], [811, -9], [-138, 33], [322, -10], [-472, -20], [-242, -32], [1112, 4], [255, 32], [-422, -31], [272, 54], [1610, 1], [617, -12], [564, 24], [404, 10], [-422, -67], [542, -94], [-624, 30], [2126, 2], [-2129, 25], [-2743, 0], [225, -49], [-682, 67], [1564, -101], [-578, -30], [-967, 6], [2596, 27], [2065, -86], [-986, 138], [-2801, -17], [-3557, 7], [-1189, -151], [-1302, -177], [-2203, 104], [-638, 107], [-5790, 45], [473, -216], [2968, -10], [2664, 198], [-4602, -99], [-208, -217], [-2900, -82], [-7701, -14], [4500, 149], [2649, 157], [-1430, -132], [17, 261], [6150, -146], [-4359, -38], [-524, -214], [-2416, 154], [-3325, 162], [-1526, 400], [-4246, -164], [-4052, 55], [-346, 85], [-2319, -11], [2205, 2], [3865, -267], [2680, 86], [-54, -261], [-5031, -154], [-1266, -369], [-23, -414], [5234, 145], [-10278, -126], [8040, -83], [-543, 214], [9865, 57], [660, -246], [10304, 58], [9578, 144], [-15514, 139], [1924, 50], [-11412, -37], [4210, -344], [4045, 151], [-1120, 532], [14015, 105], [5910, -219], [-8510, 46], [68, 177], [-155, -581], [-9675, -350], [6636, -2], [13470, 32], [-9508, 65], [-1236, -479], [4027, -597], [20613, -212], [-12270, -99], [7622, -155], [-1648, 34], [13503, 214], [15048, -24], [-4762, 88], [15602, -239], [4799, 567], [3241, 3], [3768, 90], [-288, 210], [-12636, 0], [9910, 16], [-3322, -71], [-6286, 256], [-14866, 622], [-5992, 299], [-1608, -504], [23604, 218], [-18264, 427], [-1083, -796], [-6680, -155], [14203, 489], [9218, -308], [-4348, -464], [15156, -492], [4188, 990], [-17629, -160], [-1108, 352], [5903, -214], [11294, -275], [-11899, 491], [-16192, -866], [20634, 441], [22447, 325], [-13650, 140], [-11409, 209], [-23662, 265], [4098, 772], [-23252, 501], [-24519, -212], [-6392, 698], [-36356, 46], [13124, -170], [-9367, 1308], [34340, -434], [-6549, -515], [-2938, -676], [18580, -892], [-16006, -1152], [-5685, -37], [-3272, -1349], [381, -586], [-15082, 996], [-2264, 447], [-5088, 708], [-3184, -776], [-7134, 1078], [15066, -430], [3612, -1308], [-1111, -717], [-13146, -60], [5357, 756], [-2246, 70], [-18480, 1675], [18315, -86], [9118, 1794], [3063, -1850], [-21373, 1017], [19476, -1002], [-32497, -547], [-4348, -559], [-40313, 175], [2823, 268], [-2577, 337], [-17176, -752], [16743, 490], [-25018, 392], [1090, -764], [13438, 744], [22903, 918], [13993, 231], [41913, 602], [-27260, -59], [46659, 502], [-35382, -1053], [-15399, -1177], [24932, -1867], [-1776, -1631], [-19294, 96], [-7582, -974], [31498, 1796], [13810, -62], [60252, 617], [-13426, 25], [6360, 1390], [9318, -308], [51022, -874], [65660, -116], [-7172, 865], [16167, 2083], [-29060, -2013], [-32400, 1638], [-18975, 371], [2013, 680], [2722, 2256], [44535, 781], [65308, 764], [-14130, -1312], [-49966, -134], [9527, 399], [-21108, 991], [-15190, 1903], [-38824, -1363], [-10027, 2346], [44043, -797], [-76646, 580], [-34060, 286], [51494, -1055], [10075, -462], [-24992, 2611], [-33454, -1294], [-43863, 373], [-85744, -697], [14907, -478], [8440, 1958], [-40753, 609], [42206, 396], [22440, 354], [34752, -2172], [-96490, 478], [-41778, -1401], [13430, 2592], [77902, 59], [2708, 1979], [2733, -2231], [-5351, -1679], [-765, 112], [-102654, 668], [-14398, -724], [-54619, -39], [-7744, -229], [-29071, 1067], [50438, 1740], [-43286, 404], [20728, 2341], [35072, 1654], [-12847, 1866], [-63804, -295], [118236, 264], [56097, -1756], [-26024, -1474], [-25254, 2613], [-25342, 3256], [29015, -1635], [-69112, 339], [-2842, 4060], [-64979, -102], [-21874, 1476], [22852, 330], [43734, -1666], [47452, 1646], [-3044, -712], [-43590, 2914], [29315, 3906], [-87692, -350], [-13082, 2816], [-55419, -955], [-72169, -184], [-3205, 3251], [13790, 212], [-47429, 1930], [-82037, -314], [-25164, 3246], [-61338, -675], [65552, -2084], [24624, -2587], [-42725, -3096], [37889, 381], [68230, -1100], [126863, -1216], [-32294, 395], [115988, -254], [-14298, 3693], [41054, -858], [-131784, 534], [33456, 3954], [-15428, -2770], [-69811, 876], [-19450, -2867], [-95079, -1171], [-55302, 975], [125584, 523], [-27268, 1948], [18466, 980], [-4892, -2332], [12705, 5027], [-33098, 2518], [-16404, -2856], [71391, 2606], [43360, 734], [66545, 2432], [-75998, 2873], [60034, -1176], [81648, -3227], [28824, 90], [-41020, 4612], [49259, 1767], [-7492, 333], [-38027, -402], [132440, -1329], [-64188, 4584], [-87353, -2288], [12184, 4387], [85868, -294], [35405, -1708], [32010, 3669], [-151757, -827], [50770, -2658], [-59178, -2838], [95671, 1509], [118957, -1623], [93040, -167], [53626, 1607], [31113, -4168], [193506, -308], [-64679, 27], [-31824, 3499], [-9233, -1143], [-15980, -4120], [55807, -2114], [110154, 369], [29005, -5712], [118680, -3108], [-48531, 4516], [-60090, 1089], [24260, 3507], [-34237, 417], [24616, -2835], [127838, -1986], [69909, -4202], [110993, 867], [-77882, 1631], [-153912, -234], [154071, 1813], [58894, 356], [-8516, 3841], [-63059, 237], [22391, 3420], [103918, 942], [-180582, -969], [-112620, -3439], [90460, 2253], [94704, -553], [80161, -612], [-46454, 838], [99940, -917], [-157396, 802], [-5024, -2266], [45465, -2086], [-66672, 1764], [99904, 3558], [133571, 3474], [65292, -4452], [-107839, 3747], [-14796, 6011], [68272, 2606], [-56408, 6392], [7095, 898], [19122, 5511], [-56194, -2164], [-151147, 2054], [276, -4824], [37555, -2160], [3266, 686], [-64112, -6627], [-72216, 3768], [62802, -4629], [-22748, 2216], [81366, 958], [186393, 1465], [-91614, 5208], [-138296, -2026], [-31116, -713], [-12115, 344], [113786, -2573], [-75974, -4231], [146903, 705], [38118, -3164], [137003, 2918], [-102831, 701], [-34342, -1739], [-24439, -6141], [114280, -1078], [-71218, 3010], [19938, -2259], [95473, 1345], [-118970, -4513], [41958, 5163], [43328, -2444], [-159385, -2178], [-101490, -6171], [96521, 387], [38160, 3426], [-85043, -482], [126348, 2652], [-38694, 4964], [114523, -6813], [-15273, -4438], [-61988, -1672], [-99482, -2744], [-190851, 1967], [-74754, 3117], [82914, -3231], [-112108, 6970], [132005, 4188], [41678, 5408], [-181398, -3334], [52906, -7036], [106890, -6981], [-16402, -7991], [109962, 825], [-112431, 3599], [53000, -3133]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_600_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_600_4_a_w();".
// 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_600_4_a_w(:prec:=2)
    chi := MakeCharacter_600_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_600_4_a_w();".
// 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_600_4_a_w( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_600_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<7,R![-715, -6, 1]>,<11,R![-708, -8, 1]>],Snew);
    return Vf;
end function;