
// Make newform 405.4.e.t in Magma, downloaded from the LMFDB on 20 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_405_e();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_405_e_Hecke();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_405_4_e_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_405_4_e_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 := [16, -68, 85, -35, 20, -3, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0, 0, 0], [24, -13, 14, -2, 1, 0], [12, 7, -8, 2, -1, 0], [-64, 149, -52, 38, -5, 2], [-356, 786, -287, 206, -28, 11], [220, -514, 183, -132, 18, -7]];
    Rf_basisdens := [1, 4, 2, 4, 4, 2];
    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_405_e();"
function MakeCharacter_405_e()
    N := 405;
    order := 3;
    char_gens := [326, 82];
    v := [2, 3];
    // 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;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_405_e_Hecke();"
function MakeCharacter_405_e_Hecke(Kf)
    N := 405;
    order := 3;
    char_gens := [326, 82];
    char_values := [[-1, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0]];
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    values := ConvertToHeckeField(char_values : pass_field := true, Kf := Kf); // the value of chi on the gens as elements in the Hecke field
    F := Universe(values);// the Hecke field
    chi := DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),values);
    return chi;
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, 1, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0], [-5, 0, 0, 5, 0, 0], [0, -2, 0, -14, -2, 0], [0, 2, 0, -12, 2, 4], [-14, 0, 4, 14, -10, 4], [-3, -2, -8, 0, 0, 0], [59, 14, -4, 0, 0, 0], [39, 0, -4, -39, 32, -4], [0, -42, 0, -42, -42, -8], [-83, 0, -8, 83, -30, -8], [50, -64, -8, 0, 0, 0], [132, 0, -16, -132, 42, -16], [0, -78, 0, 16, -78, -8], [0, -28, 0, 168, -28, 4], [165, 14, 12, 0, 0, 0], [-78, 0, 12, 78, -82, 12], [0, -60, 0, -173, -60, 16], [-302, 0, -24, 302, -52, -24], [-192, 34, -60, 0, 0, 0], [404, 22, 60, 0, 0, 0], [0, 22, 0, -221, 22, -12], [0, -120, 0, 489, -120, 60], [756, -66, -48, 0, 0, 0], [0, -64, 0, -440, -64, 8], [0, 208, 0, 180, 208, 64], [-140, 0, 56, 140, 272, 56], [-120, -200, 20, 0, 0, 0], [953, -224, -28, 0, 0, 0], [342, 0, 20, -342, -116, 20], [-322, -108, 16, 0, 0, 0], [-1470, 0, -72, 1470, -144, -72], [0, -2, 0, 1845, -2, -68], [844, 0, -144, -844, -288, -144], [-1380, 0, 80, 1380, -210, 80], [0, 0, 0, 700, 0, 28], [-1112, 0, 140, 1112, -34, 140], [-2350, -176, -112, 0, 0, 0], [-1257, 0, 128, 1257, 56, 128], [0, 34, 0, 909, 34, -80], [-2436, 308, 72, 0, 0, 0], [41, -592, 196, 0, 0, 0], [0, 56, 0, -1182, 56, -24], [262, 0, -332, -262, 430, -332], [-1905, -154, 4, 0, 0, 0], [-880, 276, 136, 0, 0, 0], [3295, 0, 40, -3295, -242, 40], [0, -720, 0, 970, -720, 0], [0, -812, 0, -495, -812, 56], [3049, 0, -20, -3049, -228, -20], [30, -64, -8, 0, 0, 0], [-234, 0, -160, 234, -188, -160], [0, 1108, 0, -1103, 1108, -220], [792, -492, -216, 0, 0, 0], [1689, 0, -252, -1689, -690, -252], [0, 268, 0, 1188, 268, -268], [294, 580, 16, 0, 0, 0], [-85, -46, 152, 0, 0, 0], [0, 498, 0, 340, 498, 524], [0, 290, 0, -1254, 290, -184], [1084, 0, -144, -1084, 770, -144], [-4227, 0, -28, 4227, 698, -28], [-1066, 56, 128, 0, 0, 0], [-1914, 0, -340, 1914, 662, -340], [0, 740, 0, -4256, 740, -256], [0, -90, 0, 7707, -90, -56], [0, 404, 0, 3772, 404, -104], [-5246, 0, 156, 5246, -1370, 156], [4164, 0, 760, -4164, 168, 760], [0, 152, 0, -4301, 152, 312], [0, -116, 0, 1134, -116, 256], [-5358, 1660, 128, 0, 0, 0], [0, 558, 0, 5506, 558, 200], [2488, 0, 400, -2488, -364, 400], [-2491, 822, 232, 0, 0, 0], [-465, 0, -232, 465, -1156, -232], [0, 1886, 0, -264, 1886, -16], [1586, 1254, 412, 0, 0, 0], [-3930, 0, 320, 3930, -1120, 320], [-7037, 0, -644, 7037, -248, -644], [6900, 0, -580, -6900, -2490, -580], [0, 48, 0, 2797, 48, 112], [6774, -986, 44, 0, 0, 0], [7658, -38, 756, 0, 0, 0], [0, 1746, 0, -515, 1746, -1064], [0, -1444, 0, -8823, -1444, 164], [3306, 2138, 240, 0, 0, 0], [0, -2500, 0, -4148, -2500, -768], [0, -1892, 0, 4518, -1892, -368], [4642, 0, -56, -4642, -1668, -56], [-8865, -180, 592, 0, 0, 0], [0, -1958, 0, -3636, -1958, -380], [-3868, 390, -1032, 0, 0, 0], [-5154, 0, 376, 5154, 764, 376], [-6155, 0, 240, 6155, -1754, 240], [-10983, -1112, 540, 0, 0, 0], [-6636, 0, 1072, 6636, -2928, 1072], [708, -902, 48, 0, 0, 0], [5054, -2002, 32, 0, 0, 0], [5210, -464, 604, 0, 0, 0], [0, 1538, 0, 1504, 1538, 888], [-66, 3700, 776, 0, 0, 0], [1440, 0, -44, -1440, 2152, -44], [0, 146, 0, -4746, 146, 392], [4849, 0, 552, -4849, 2550, 552], [11552, -82, -596, 0, 0, 0], [0, 520, 0, -5913, 520, 700], [-741, -3098, 1476, 0, 0, 0], [1878, 0, 1100, -1878, -2334, 1100], [0, -532, 0, 13087, -532, -268], [664, 0, -712, -664, 2334, -712], [-22792, -1072, -232, 0, 0, 0], [531, 0, 364, -531, 166, 364], [0, -4420, 0, 2584, -4420, 248], [1949, 1202, 1484, 0, 0, 0], [0, -2096, 0, -360, -2096, 1432], [1750, 0, 0, -1750, -1690, 0], [-9651, -164, -1760, 0, 0, 0], [11343, 0, 1312, -11343, -442, 1312], [0, 2770, 0, -13698, 2770, -828], [7966, 0, 636, -7966, -1880, 636], [0, -2574, 0, -4430, -2574, 908], [0, -2364, 0, 11406, -2364, -156], [9459, 1632, 1824, 0, 0, 0], [0, -4358, 0, 4711, -4358, -1192], [7542, -1992, -776, 0, 0, 0], [0, -2936, 0, 18130, -2936, -292], [-11034, -1368, -192, 0, 0, 0], [0, -3588, 0, 3904, -3588, -1800], [8080, 0, -1728, -8080, -4176, -1728], [2597, 1634, 1808, 0, 0, 0], [3216, 0, -1464, -3216, 5144, -1464], [3499, 0, 1004, -3499, 498, 1004], [-17422, -3660, -248, 0, 0, 0], [17442, 0, -176, -17442, -698, -176], [1687, 0, 2492, -1687, 584, 2492], [8913, -4834, -1400, 0, 0, 0], [-620, 0, 1416, 620, -3878, 1416], [7809, 0, 404, -7809, -4230, 404], [26412, 730, 648, 0, 0, 0], [12896, -7472, -452, 0, 0, 0], [0, 4160, 0, 19050, 4160, -880], [-6368, 0, 80, 6368, -1786, 80], [-3195, -7212, -256, 0, 0, 0], [-8350, 3540, -2044, 0, 0, 0], [0, -4380, 0, 4224, -4380, 2104], [0, -6572, 0, 7492, -6572, 1776], [0, -2786, 0, -8901, -2786, 864], [-14933, 0, 1088, 14933, -1614, 1088], [-7239, -4820, -2292, 0, 0, 0], [20344, 0, -1404, -20344, 2690, -1404], [6222, 7718, -1896, 0, 0, 0], [-18898, 8442, 1272, 0, 0, 0], [-7689, 0, -396, 7689, -804, -396], [0, 1416, 0, 124, 1416, -2248], [0, -858, 0, -25710, -858, -4], [11864, -2424, 664, 0, 0, 0], [0, 486, 0, -2292, 486, 16], [1832, 5084, -24, 0, 0, 0], [-4602, 0, -880, 4602, 7416, -880], [0, -3976, 0, -10443, -3976, -2428], [14742, -1344, -1600, 0, 0, 0], [1150, 0, -1680, -1150, 9120, -1680], [-12090, -368, 1664, 0, 0, 0], [5598, 0, 440, -5598, 8116, 440], [0, -2652, 0, -26925, -2652, -180], [14153, 3938, 772, 0, 0, 0], [0, 542, 0, 17128, 542, -836]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_405_e_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_405_4_e_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_405_4_e_t(:prec:=6)
    chi := MakeCharacter_405_e();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 4));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(997) - 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_405_4_e_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_405_4_e_t( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_405_e();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![36, -138, 535, 11, 24, -1, 1]>,<7,R![3240000, 993600, 225504, 20688, 1384, 44, 1]>],Snew);
    return Vf;
end function;