
// Make newform 2304.4.a.t in Magma, downloaded from the LMFDB on 14 November 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_2304_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_2304_4_a_t();".
// 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_2304_4_a_t();".
// 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 := [-3, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-4, 8]];
    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_2304_a();"
function MakeCharacter_2304_a()
    N := 2304;
    order := 1;
    char_gens := [1279, 2053, 1793];
    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_2304_a_Hecke(Kf)
    return MakeCharacter_2304_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], [0, 0], [-4, -1], [8, 1], [4, -4], [-36, 2], [18, -4], [68, 4], [-128, 2], [76, 9], [-40, 13], [-68, -4], [218, 20], [-356, -4], [112, 14], [172, -15], [324, 0], [-324, 0], [228, -48], [-1024, -2], [330, 48], [248, -59], [-388, 28], [-266, -8], [-610, 88], [-612, 77], [856, -73], [244, 8], [-1364, -42], [-114, 56], [2152, 35], [1308, -48], [1594, -68], [284, 112], [-212, -53], [-312, 69], [-1508, 140], [-1676, -52], [528, -60], [-2980, 23], [1292, 112], [-308, -234], [-1568, 20], [-914, -272], [-980, -131], [-1064, 119], [-76, -32], [-1720, -161], [1628, 100], [-516, 50], [102, -8], [864, -360], [-4162, 184], [-3660, -84], [-642, 160], [-1168, -416], [-2180, -227], [-4248, -81], [-1476, 286], [-3434, -224], [1708, 272], [-2452, 233], [3876, -240], [2480, -284], [-5018, -240], [-8116, 93], [-10100, 56], [5410, 80], [-4044, 12], [-244, -224], [6270, -136], [1152, 486], [-3144, 525], [-6548, -328], [4540, -364], [6368, -356], [-3412, -237], [8636, 184], [-3694, 468], [-2026, 424], [3340, 836], [-7236, 430], [-1200, 426], [2414, -144], [-2472, 483], [-4188, 588], [8610, -308], [-506, 56], [4492, 355], [-2968, -713], [1836, 180], [-8240, -58], [-3416, 5], [-2076, 312], [-2188, 208], [-5472, -882], [-484, 425], [-16550, 292], [-12052, 100], [3372, 46], [-4188, 804], [3804, 395], [588, -228], [-502, -1068], [21580, -232], [12946, -560], [7732, -424], [-2002, -424], [-7200, -162], [-4710, -800], [22952, 331], [-7380, 576], [17574, 80], [4364, -80], [-5176, -467], [-1022, -1124], [1956, -1020], [-6240, -222], [-1940, 495], [-11700, 360], [10108, 1052], [11550, -1184], [-4884, 775], [6772, -76], [-10252, 460], [13116, -359], [-2068, -1638], [-13872, -1590], [17704, 737], [3164, -966], [5428, -1576], [-29072, 344], [-2152, 2233], [27532, -134], [810, 1948], [-3218, -384], [-12036, -1127], [8148, -228], [-15732, -113], [2842, 1500], [17164, 188], [3052, -1715], [22952, -1127], [4660, -88], [-19412, -1434], [-5856, 834], [-8180, 548], [-10454, 468], [1244, 1780], [35104, -796], [10748, 232], [-15506, -240], [12868, 1388], [3024, 1728], [-2372, -220], [3552, -1608], [9192, 897], [4034, -1500], [9210, -608], [1356, -469], [21084, 912], [-25622, 292], [-23112, -2133], [-24268, -1292], [-51310, -508], [16528, 608], [10360, 17], [19036, -1720], [-20178, 1224], [42572, -457], [2740, 3560], [-21108, -1356], [44400, 168], [22874, 1984], [14648, 1813], [29910, -1024], [2396, -560], [5484, -1933], [-2120, -2173], [-53876, -196], [9944, 685], [48380, 652], [15868, -854], [-4730, -512], [3648, -1668], [26508, 1135], [8236, 154], [21460, -1984], [26038, -2728], [-8832, -672], [-4286, 272], [15332, -4208], [-3484, -2672], [-22724, 787], [-20436, 528], [8294, -2224], [-17182, -3408], [29580, 1850], [18910, 112], [-9200, 2828], [-17380, 3335], [-30520, 379], [29596, 1038], [-20526, -912], [-45756, -540], [50668, 925], [29608, 3251], [-70724, 236], [28102, 2088], [19244, -3692], [-14850, -3008], [62636, -433], [64920, 1491], [6420, -2928], [-2592, 306], [-41498, -368], [47192, -1391], [-51598, 284], [-72336, 156], [-6564, 1087], [-21924, -938], [36600, -2985], [1602, -5980], [-57592, -845], [-53204, -3460], [-39892, 1084], [7094, 2504], [-45616, 2830], [45016, -2473], [-51964, -1064], [13452, -3914], [-7676, 1700], [-27832, -5441], [73286, 176], [-83588, -364], [-69584, -130], [-33266, -4120], [-51828, 947], [64996, -700], [20256, 1218], [13084, 4700], [40524, 2856], [53064, 3105], [17324, 1972], [-36306, -2624], [-38208, -3318], [15256, -4987], [3708, 2088], [91772, 424], [34816, 284], [50492, 2750], [117790, -264], [-45024, -318], [9306, -5904], [25372, -1787], [-14516, 6776], [-40948, -2218], [22940, -2456], [-62500, 1889], [-25546, 3408], [68296, 1103], [27372, -1344], [-3412, 4814], [42412, 2228], [-4318, 1748], [24100, -1384], [-48724, -5137], [-9610, -664], [-36068, 4460], [12236, -2853], [70700, 1624], [-61660, 4600], [-92470, 1984], [-6888, -339], [-1262, 2432], [-1800, 3159], [16452, -3276], [-90980, 80], [-16278, 1088], [-5604, -5160], [6288, 8238], [-85576, -2309], [-22944, -3138], [-86196, 552], [25596, 8892], [45248, 5908], [-15842, -7288], [-87236, 1651], [-107736, 1833], [81214, 2968], [-15092, 3351], [94556, -992], [-59050, -2712], [2580, -4416], [-40452, -7716], [-95284, 2715], [31432, -2065], [-50756, -4067], [-38076, 1140], [-47068, 1708], [-92490, -3232], [59644, 1723], [79288, -3355], [-23220, 1584], [2444, 796], [1774, 2744], [-41596, 1132], [-118116, 3602], [-60480, 2466], [67964, -1472], [24768, 5148], [-40644, 5261], [78626, -5524], [70564, 1940], [19472, 5116], [83450, 3184], [-32052, 2280], [60784, -5758], [18674, -4400], [-43314, -1880], [-53388, 0], [-17338, 96], [-7252, -4975], [-67304, 2189], [11930, 6804], [42286, -7528], [35316, 2772], [-660, 3756], [62336, -7184], [-94276, -3217], [-109732, 1046], [-86404, -865], [-115256, -241], [45724, -2056], [-138372, 4128], [-6828, 4308], [27532, -9244], [-13282, -4408], [-38678, -6592], [31976, -2825], [-98596, -3932], [-122326, -2860], [128924, 4389], [-107560, -5777], [-70180, -6703], [-67908, 3756], [91804, 8818], [-7508, 5672], [160400, 2122], [15196, 9153], [-78700, 4972], [60998, -4712], [-40980, -8947], [-86520, 4035], [102492, -6588], [-3466, -6736], [-121216, -2192], [49092, 2424], [-111406, 2988], [36144, 3636], [-130820, 500], [-19930, -4968], [-87552, -3564], [110004, -3660], [21748, 14216], [-50550, -6688], [-44308, 8897], [29864, 3445], [54358, 8064], [86508, 6516], [-35444, -14956], [-20896, -344], [-19444, -7759], [-144664, 5353], [68028, -11830], [-49540, 5692], [117216, -9396], [133474, 7680], [-53998, -9852], [13446, 11016], [-42116, -81], [17242, 6396], [134536, -2515], [47966, -11584], [-86956, 3796], [114768, -7596], [103704, -2607], [28764, 3454], [19516, -10768], [11760, 16410], [-28414, 7696], [-5684, 14247], [-47148, -5808], [-18700, -14636], [-74928, -1824], [94614, 8472], [157384, -5113], [-42758, -9996], [11996, -5372], [-21284, -4785], [-29588, -17464], [-87550, -3436], [157672, 1223], [176042, 4772], [23244, -14159], [-32824, -7559], [-14180, 13134], [42546, 6356], [-197004, 4836], [159148, -3700], [26946, -13552], [62812, -8069], [37300, 13820], [130644, 4716], [-118166, 320], [-30356, 57], [-58656, -11508], [61864, -9691], [-21742, 2468], [-10496, 8354], [76556, -13461], [-53668, -5444], [-92608, -3044], [-46316, 7220], [82358, -8160], [132524, -10327], [-10580, -2236], [67382, 6440], [98380, 1844], [-84608, 4418]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2304_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_2304_4_a_t();".
// 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_2304_4_a_t(:prec:=2)
    chi := MakeCharacter_2304_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_2304_4_a_t();".
// 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_2304_4_a_t( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2304_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<5,R![-192, 8, 1]>,<7,R![-144, -16, 1]>,<11,R![-3312, -8, 1]>,<13,R![464, 72, 1]>,<17,R![-3004, -36, 1]>,<19,R![1296, -136, 1]>],Snew);
    return Vf;
end function;