
// Make newform 320.4.a.s in Magma, downloaded from the LMFDB on 18 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_320_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_320_4_a_s();".
// 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_320_4_a_s();".
// 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 := [-6, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [0, 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_320_a();"
function MakeCharacter_320_a()
    N := 320;
    order := 1;
    char_gens := [191, 261, 257];
    v := [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_320_a_Hecke(Kf)
    return MakeCharacter_320_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], [4, 1], [-5, 0], [-4, 5], [32, 6], [-6, -8], [2, -24], [104, -8], [-60, 11], [146, 16], [-88, 6], [178, -16], [50, -40], [-188, 37], [140, 13], [-158, -24], [360, -20], [634, 32], [-372, 47], [24, -218], [-470, -120], [-16, 172], [-796, -47], [-390, 48], [610, -40], [-758, -208], [1204, -89], [1164, 99], [-22, -176], [-1374, 48], [-276, -291], [448, -406], [-1078, -64], [1352, -244], [-1390, 240], [280, -50], [1610, -400], [-1740, -59], [-1748, 313], [-2406, -208], [2520, -100], [1050, -256], [-392, -46], [1778, 264], [-638, 296], [1168, -456], [-512, 354], [772, -73], [300, 407], [1018, -864], [-1222, 984], [1424, 212], [4506, -72], [2560, -250], [1586, -432], [-2876, 131], [234, -1088], [-616, 402], [4882, 816], [1010, -440], [2020, -491], [-3342, -96], [-1876, -1025], [-4216, -798], [-534, 528], [1978, -1256], [9808, 394], [-1934, 48], [5004, 955], [722, 2048], [-1950, -1040], [-688, -24], [4764, 1305], [5810, -240], [-5928, 1056], [-2812, 775], [1378, 384], [5914, 1592], [-6942, 1280], [2258, 2184], [600, 2740], [3650, 240], [4280, -1670], [-5518, 1336], [8368, -1656], [2196, 889], [1594, -808], [10554, -1248], [-7182, 1648], [-1756, 1031], [-3972, 507], [13008, 924], [10540, -87], [-12320, -1130], [7400, -2120], [5300, -641], [-13902, -608], [-2982, 1408], [-7292, -1467], [-3614, 3152], [-1268, -1057], [6346, 1648], [-10044, 2217], [-8526, -1688], [15568, -46], [-2318, 736], [4828, -1409], [9522, 1376], [-288, 4636], [-2798, -24], [2540, -2947], [23458, -136], [12090, -40], [10904, 952], [-15912, -1586], [13866, 1528], [5556, -2603], [300, -4327], [3690, -2520], [12632, 76], [5810, 2720], [20770, 680], [-16286, -328], [-29020, 301], [12624, -258], [-5574, 1168], [11002, -2736], [-560, -2540], [7676, 5885], [12234, 1312], [-21032, -1356], [372, -3673], [-26968, -1554], [-16750, -3520], [-18614, -3328], [1938, -4624], [17282, -984], [-31268, -317], [-3270, -920], [7866, 2560], [14560, 2310], [-17326, 3312], [-14940, -4349], [8492, -2141], [-38534, -992], [-4032, 124], [3410, 360], [-9222, 7664], [15752, 5556], [-15020, 5651], [12890, -1120], [-6358, 136], [-13916, 5681], [-14884, -4235], [-18340, -897], [-2744, 7238], [24832, 3316], [39162, -2344], [4474, -4408], [17362, 2720], [42220, -1137], [-12758, 7456], [-28036, -1675], [-20688, 786], [-20718, -1144], [-14588, -5685], [-12472, -1106], [-27438, 2296], [-18718, 2704], [6706, -8232], [16152, 2096], [-15358, 2272], [-36504, -542], [5834, 4632], [36480, 6200], [-22470, 5392], [9584, -7078], [38474, 3808], [4772, 6027], [11018, 9344], [-16068, -7191], [-7360, 2410], [-28942, 1624], [1962, -8664], [13236, 2019], [9674, 8304], [20730, -5200], [24180, 2709], [-15518, -24], [15048, 5854], [-9422, -3776], [20468, 4105], [23312, 926], [23322, -7264], [38748, -2709], [-40166, -7768], [9962, -11864], [-17446, 152], [450, 7840], [-13900, -5001], [45378, 4016], [-33544, 778], [1346, 2808], [-40990, -6272], [38696, 308], [13130, 8160], [62912, 576], [33652, 5925], [-8758, -5776], [56496, -1422], [5538, 1944], [-32206, -4048], [772, 6795], [-13604, 1255], [-4672, -2436], [24850, -5800], [-26324, 10485], [-5054, 5504], [-17172, 13521], [15114, 1192], [18626, -3232], [-32288, -7524], [54098, 5936], [16884, 6371], [73212, -5957], [-23982, 12864], [-29094, -8712], [-47008, -3864], [38460, -7787], [57552, 3226], [-53638, -2584], [-34392, -696], [-9160, 7170], [58882, 5896], [-12812, 7113], [-15444, -9755], [-10166, 10232], [13026, 2648], [1848, -17816], [66120, 6970], [-6812, -10655], [-51904, -522], [-7052, -10985], [-82686, 6400], [42994, 13232], [656, 16448], [18508, -6699], [-20400, -7610], [11272, 15036], [41412, -625], [-64566, -10088], [-11070, -2496], [-9236, -11575], [18834, 712], [-98118, 1696], [-2744, 17728], [-10054, 1712], [15372, 4539], [-15774, 11728], [40554, -14528], [73748, -5485], [-10196, 5479], [51194, 5984], [-43910, -2400], [-75566, 6232], [19272, -17064], [68514, -6176], [-34118, -12640], [88148, 4905], [45618, 3664], [-32782, 1920], [-12740, 10123], [12202, -13704], [-121920, 80], [-32734, -10912], [98548, -3585], [-24036, -16345], [8306, -18160], [65506, 8808], [3232, -12374], [-3372, 15155], [-45144, -7822], [64060, 16333], [77226, -5408], [95004, -11441], [-73528, 11606], [30210, -24760], [-108462, 1304], [-59360, -14100], [65450, 11800], [69162, -3344], [-133092, 931], [80538, 2744], [-74880, -17410], [-10502, 24224], [37530, -1200], [-82648, 1686], [97154, -7488], [-40872, -20336], [45724, -1365], [130058, -6976], [-46182, 6864], [21136, -21292], [48948, 14973], [39712, -6514], [-26942, 3944], [57180, 8783], [-36926, -880], [83152, -17664], [35474, 4112], [81732, -12593], [45802, -9472], [-79726, 1888], [-41468, -23695], [40812, 24233], [50858, -8688], [-79160, 1680], [-40792, 2774], [-69518, -12464], [-12326, 11992], [70448, 10934], [-7878, 5856], [634, -7008], [-93916, -3329], [40554, 14512], [30394, 26712], [-102040, -12480], [-46540, 15681], [87276, 3261], [-90862, -19496], [12746, -39312], [-109078, 11296], [-3696, -12708], [15492, -22943], [-129056, -11258], [85932, -11437], [40154, 6832], [64946, -1472], [-101854, -12472], [-79524, -6055], [167650, -320], [-159414, 9728], [-1278, 15856], [13592, 10166], [-26182, -25616], [-71992, 4824], [103522, 8736], [-11924, 25771], [93288, 6174], [41426, 11688], [89248, -606], [5818, 25104], [41706, 18368], [-72364, -8693], [-75414, -10720], [4890, -17080], [13808, 2884], [29872, -25854], [18034, -13688], [-46092, 19615], [67346, -22472], [-39638, 8320], [-46020, -10847], [-28632, 11964], [-79940, -25453], [110138, -4536], [-2886, 28232], [122660, 12299], [-71742, 6584], [63840, 20130], [121240, 17480], [-5148, 35975], [-176142, -12176], [-158120, 17230], [-7478, -17704], [55272, -28424], [71880, 910], [-24702, 22464], [121386, 4728], [-27334, 22288], [-119934, -11296], [-136278, -20784], [45724, 29445], [-84222, -14976], [-42680, 2520], [-44988, -1213], [232184, 1722], [48578, 2544], [-59660, 33281], [-1780, -11707], [-78326, -808], [-60606, 19472], [78760, -5740], [-43140, -10757], [12984, 19222], [-18278, -48384], [124656, 468], [-130886, 9664], [-203968, -1394], [104274, -21248], [83418, 31344], [107922, -10504], [73180, -33127], [2458, -9856], [89890, 36640], [115224, -25258], [181898, 21384], [57122, 24160], [-108252, -3055], [-19656, -39908], [-19118, 21136], [-163038, -14384], [-84828, -7195], [-194880, -550], [92906, -23992], [151346, -12048], [-32256, -27248], [-141940, -3823], [-3950, 600], [-181356, 2983], [170938, 224], [170242, -744], [-132948, 19269], [-50360, 9460], [22554, -5088], [-131334, -5392], [-28300, 51949], [203714, -5528], [-30064, -31662], [22512, 37576]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_320_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_320_4_a_s();".
// 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_320_4_a_s(:prec:=2)
    chi := MakeCharacter_320_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_320_4_a_s();".
// 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_320_4_a_s( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_320_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<3,R![-8, -8, 1]>,<7,R![-584, 8, 1]>],Snew);
    return Vf;
end function;