
// Make newform 210.6.i.b in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_210_i();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_210_i_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_210_6_i_b();".
// 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_210_6_i_b();".
// 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 := [22801, 0, 151, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
    Rf_basisdens := [1, 1, 151, 151];
    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_210_i();"
function MakeCharacter_210_i()
    N := 210;
    order := 3;
    char_gens := [71, 127, 31];
    v := [3, 3, 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;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_210_i_Hecke();"
function MakeCharacter_210_i_Hecke(Kf)
    N := 210;
    order := 3;
    char_gens := [71, 127, 31];
    char_values := [[1, 0, 0, 0], [1, 0, 0, 0], [-1, 0, -1, 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 := 6;
    raw_aps := [[-4, 0, -4, 0], [0, 0, -9, 0], [25, 0, 25, 0], [-56, 7, 56, 0], [0, 11, -241, 11], [-14, 0, 0, -35], [0, 109, 469, 109], [-1099, -68, -1099, 0], [-309, -369, -309, 0], [-5043, 0, 0, -183], [0, -540, 2069, -540], [1036, -141, 1036, 0], [1273, 0, 0, 767], [-13350, 0, 0, -205], [1742, 236, 1742, 0], [0, -2614, 158, -2614], [0, -277, 33101, -277], [22236, -1564, 22236, 0], [0, 1673, -9482, 1673], [-17219, 0, 0, 4463], [0, 4041, 17258, 4041], [60795, -316, 60795, 0], [-55397, 0, 0, -4057], [-47123, -5657, -47123, 0], [35876, 0, 0, 108], [0, -4317, 111555, -4317], [-97284, -991, -97284, 0], [-134937, -6825, -134937, 0], [0, 6044, 100123, 6044], [30658, 0, 0, 632], [72282, 0, 0, -20467], [-72772, 13274, -72772, 0], [0, -9891, -242043, -9891], [-53163, 0, 0, 10730], [-215556, 3612, -215556, 0], [0, -3948, -342094, -3948], [0, 23266, -103668, 23266], [-113576, 9648, -113576, 0], [-190149, 0, 0, -34905], [-281290, 7778, -281290, 0], [0, -32784, 267138, -32784], [54333, 0, 0, 16790], [-320082, -45732, -320082, 0], [0, -27237, 530834, -27237], [-150413, 0, 0, 17069], [0, -33732, 493718, -33732], [-214686, 0, 0, -14260], [481266, 0, 0, -3970], [0, -36647, 314071, -36647], [-84921, -64540, -84921, 0], [-124308, 93378, -124308, 0], [-396202, 0, 0, 7828], [0, -11030, -192126, -11030], [1244787, 0, 0, 34035], [33197, -76657, 33197, 0], [0, 121030, 411274, 121030], [0, -23406, 1188540, -23406], [421598, 142264, 421598, 0], [0, 38507, 1963720, 38507], [-439580, 0, 0, -46384], [0, 64011, -207580, 64011], [1312352, 0, 0, 31336], [2836620, 0, 0, 9473], [0, 172425, -2631, 172425], [-104882, 22797, -104882, 0], [-183293, 67291, -183293, 0], [-664365, 236150, -664365, 0], [-1179618, 0, 0, 1061], [0, -129124, 599528, -129124], [-188874, 0, 0, 55160], [0, -150837, -928623, -150837], [-1974421, -135091, -1974421, 0], [0, -19499, -3216138, -19499], [-467462, 250311, -467462, 0], [-757829, 0, 0, -157148], [-1233222, 274806, -1233222, 0], [0, 67201, 3665065, 67201], [1966488, 184259, 1966488, 0], [4289614, -23402, 4289614, 0], [0, -220, -3684275, -220], [2072964, 0, 0, -290814], [-1942261, 0, 0, -85116], [0, 173658, 5164320, 173658], [4231340, 0, 0, -228939], [-3768420, -3910, -3768420, 0], [-476438, -103946, -476438, 0], [1263618, 0, 0, 214044], [1190142, -165739, 1190142, 0], [1335719, 0, 0, 225631], [753284, 0, 0, -181971], [784946, -122368, 784946, 0], [0, -398052, -4386720, -398052], [0, -89001, -2572720, -89001], [1216518, 0, 0, 512694], [194903, 213640, 194903, 0], [-1897644, 0, 0, -272538], [-2598608, 202114, -2598608, 0], [0, 221314, 5059246, 221314], [-7264854, -54193, -7264854, 0], [-1388845, -793904, -1388845, 0], [2102602, 0, 0, -253874], [0, -34756, 8696402, -34756], [0, 603808, 1037242, 603808], [10028877, 80841, 10028877, 0], [0, -278092, 10858159, -278092], [0, -10547, -8027814, -10547], [-5301401, 0, 0, 392357], [-2113215, -991761, -2113215, 0], [0, 261930, 261342, 261930], [-2248607, 0, 0, 24208], [5515362, 285395, 5515362, 0], [0, -422740, 8577664, -422740], [-972848, 0, 0, 547262], [0, -529758, -3242047, -529758], [-6509152, 0, 0, 202920], [0, 690991, 5242681, 690991], [-5767698, 0, 0, 71669], [0, -668809, -7208827, -668809], [-1996219, -585121, -1996219, 0], [-12835660, 0, 0, -636104], [0, 788758, 10131627, 788758], [-2440170, 0, 0, 665399], [-3082695, -214443, -3082695, 0], [0, -1387001, 112507, -1387001], [5292351, -1169806, 5292351, 0], [-3355201, 0, 0, -849269], [17964912, -456688, 17964912, 0], [-10147920, 539202, -10147920, 0], [10306690, 0, 0, -834023], [7166868, 257603, 7166868, 0], [0, 543106, -3809319, 543106], [-9793287, 0, 0, -175671], [-19675211, 649482, -19675211, 0], [2906526, 0, 0, -1364068], [-4798137, 634905, -4798137, 0], [13969071, 0, 0, 1228610], [0, -1624989, -3906243, -1624989], [0, -115466, -5090046, -115466], [-10399659, 0, 0, -1220469], [0, -18792, -10110462, -18792], [22573004, 0, 0, -931962], [-26409429, -43137, -26409429, 0], [0, -1330934, 13093056, -1330934], [-6797876, 0, 0, -1577494], [0, 3030198, 1339049, 3030198], [19805029, 0, 0, -581563], [-12559852, 0, 0, 1147407], [0, 405873, -7396119, 405873], [29459612, -322418, 29459612, 0], [-32635688, 163858, -32635688, 0], [1392430, -2880828, 1392430, 0], [-1435712, 0, 0, -1001344], [-6385610, 0, 0, 9997], [41891363, -214291, 41891363, 0], [0, 209163, -25230574, 209163], [6661935, 0, 0, 817251], [-13484837, -2859894, -13484837, 0], [-11965481, 904243, -11965481, 0], [8489228, 0, 0, 1406787], [0, -1060133, 17652073, -1060133], [-2741851, -2541001, -2741851, 0], [260430, 0, 0, -1650726], [2903430, 0, 0, 1181609], [-19872300, -2532864, -19872300, 0], [0, -187695, 42220887, -187695], [0, 954871, -8152493, 954871], [0, 533896, 11486343, 533896], [0, 799593, -2099188, 799593]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_210_i_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_210_6_i_b();".
// 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_210_6_i_b(:prec:=4)
    chi := MakeCharacter_210_i();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 6));
    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_210_6_i_b();".
// 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_210_6_i_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_210_i();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,6,sign)));
    Vf := Kernel([<11,R![1584836100, -19188420, 192514, -482, 1]>],Snew);
    return Vf;
end function;