
// Make newform 196.8.e.a in Magma, downloaded from the LMFDB on 10 February 2025.
// To make the character of type GrpDrchElt, type "MakeCharacter_196_e();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_196_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_196_8_e_a();".
// 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_196_8_e_a();".
// 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 := [777924, 882, 883, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [777924, -883, 883, -1], [-777924, 1558495, -883, 1], [2647, 0, 0, 2]];
    Rf_basisdens := [1, 778806, 778806, 883];
    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_196_e();"
function MakeCharacter_196_e()
    N := 196;
    order := 3;
    char_gens := [99, 101];
    v := [3, 2];
    // 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_196_e_Hecke();"
function MakeCharacter_196_e_Hecke(Kf)
    N := 196;
    order := 3;
    char_gens := [99, 101];
    char_values := [[1, 0, 0, 0], [-1, 1, 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]];
    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 := 8;
    raw_aps := [[0, 0, 0, 0], [0, -7, -1, 0], [21, -21, 3, 3], [0, 0, 0, 0], [0, -3714, -42, 0], [-5915, 0, 0, -9], [0, 7896, -318, 0], [13307, -13307, 27, 27], [-16320, 16320, 1512, 1512], [-79008, 0, 0, -462], [0, -90370, -2646, 0], [22912, -22912, 7686, 7686], [160860, 0, 0, 8142], [511934, 0, 0, -6174], [832986, -832986, 2994, 2994], [0, 205314, 4032, 0], [0, 851067, 21789, 0], [-273763, 273763, -14589, -14589], [0, 1295308, -50904, 0], [2064636, 0, 0, 8148], [0, -4004434, -5508, 0], [-1235228, 1235228, -123228, -123228], [4950393, 0, 0, -53079], [7711746, -7711746, -36168, -36168], [8688736, 0, 0, 143370], [0, 6686925, -87291, 0], [1021202, -1021202, 253026, 253026], [-17039184, 17039184, 111300, 111300], [0, 5363716, 216846, 0], [16084284, 0, 0, 155442], [-5247220, 0, 0, -582372], [1377579, -1377579, 196731, 196731], [0, -7353654, -67284, 0], [33208987, 0, 0, -396549], [-41648610, 41648610, -244692, -244692], [0, 10072612, -224028, 0], [0, 31642835, 887823, 0], [1240018, -1240018, -1037610, -1037610], [-70175238, 0, 0, 21978], [18285183, -18285183, -803427, -803427], [0, -40213992, 835548, 0], [-41297627, 0, 0, -80721], [61541244, -61541244, -379092, -379092], [0, 41644648, 422478, 0], [-36225486, 0, 0, 251412], [0, 70509278, 802242, 0], [-115452292, 0, 0, -578592], [-212910236, 0, 0, 460116], [0, 196966203, -2030571, 0], [83046215, -83046215, 2563677, 2563677], [189161742, -189161742, 2148552, 2148552], [-91440480, 0, 0, 132720], [0, -129524248, -422190, 0], [94666131, 0, 0, 3029859], [-237601014, 237601014, 3200424, 3200424], [0, 240155940, 3820404, 0], [0, -133070721, 5606787, 0], [-198794680, 198794680, 574200, 574200], [0, -335701598, 4898880, 0], [-334905702, 0, 0, -3299856], [0, 77543795, 4224933, 0], [155462223, 0, 0, -611631], [100274965, 0, 0, 5022549], [0, 39466224, 6081144, 0], [405799604, -405799604, -2113326, -2113326], [-380674026, 380674026, -7145796, -7145796], [-297931502, 297931502, 1120014, 1120014], [1013665136, 0, 0, 1905750], [0, -3029238, 4589802, 0], [121218265, 0, 0, 12859947], [0, -954609726, -714336, 0], [-1124382876, 1124382876, 9038988, 9038988], [0, 711709124, 154044, 0], [559193086, -559193086, 1351980, 1351980], [-338587990, 0, 0, 11683854], [570004554, -570004554, 19584882, 19584882], [0, 226030440, 32441682, 0], [166157159, -166157159, -371835, -371835], [518953992, -518953992, -4026750, -4026750], [0, -803935552, -11836206, 0], [-1394225133, 0, 0, 2024475], [-154883674, 0, 0, 15176952], [0, -1246200024, -21520632, 0], [-1535484860, 0, 0, -18688338], [608238008, -608238008, -7827408, -7827408], [-1396203156, 1396203156, -33252576, -33252576], [532414746, 0, 0, 50095416], [178457872, -178457872, -6649902, -6649902], [-353148411, 0, 0, 1778391], [-1734187744, 0, 0, -23896656], [48658407, -48658407, -15040137, -15040137], [0, 2537995614, 9521802, 0], [0, 2063441056, -2762424, 0], [-3025150356, 0, 0, -21520632], [2689337164, -2689337164, -18823896, -18823896], [-1226922228, 0, 0, -26136348], [-3322871097, 3322871097, 9745557, 9745557], [0, 200138988, -52668858, 0], [-1394753017, 1394753017, 52237359, 52237359], [1057733278, -1057733278, 37630404, 37630404], [917086346, 0, 0, -51044490], [0, -434448786, 78139068, 0], [0, 3956875713, 275175, 0], [-461471400, 461471400, 77412426, 77412426], [0, 1433355790, -31267530, 0], [0, -314927158, -79268328, 0], [4011215271, 0, 0, -76663305], [-7019564034, 7019564034, -20662404, -20662404], [0, 873566784, -44070600, 0], [388427326, 0, 0, -129072888], [2389745120, -2389745120, -38877120, -38877120], [0, 2801207896, -85982526, 0], [-7024795464, 0, 0, 30094134], [0, -3332371021, -36766251, 0], [5172995252, 0, 0, 19634076], [0, 1462161504, -151261194, 0], [2676989119, 0, 0, -137990313], [0, -2130330930, -17557806, 0], [-1410595932, 1410595932, -157546830, -157546830], [749305506, 0, 0, 194784030], [0, 2715028841, 120293001, 0], [6429790262, 0, 0, -142009308], [-6672308013, 6672308013, -16177575, -16177575], [0, -5475986292, -66168144, 0], [14279735939, -14279735939, -34195293, -34195293], [2238333156, 0, 0, -162514842], [-9429070328, 9429070328, 93678606, 93678606], [-5985329322, 5985329322, -174086850, -174086850], [4946173750, 0, 0, 161479062], [874857221, -874857221, 296061867, 296061867], [0, 5979306226, 74716362, 0], [-3642260124, 0, 0, -63703332], [7499966296, -7499966296, 80903592, 80903592], [-1347007408, 0, 0, -14867622], [-11266700424, 11266700424, 99031782, 99031782], [4444330492, 0, 0, 122514678], [0, 11074164969, -65155239, 0], [0, -11843876065, 84558897, 0], [-6139436919, 0, 0, 129914715], [0, -7329829656, 211018710, 0], [-10090767575, 0, 0, -145469727], [-27044161542, 27044161542, -1682856, -1682856], [0, 7740238144, 58297176, 0], [-14776464816, 0, 0, -117655860], [0, 8828641157, -331891083, 0], [-3027431946, 0, 0, -189132570], [-11521615847, 0, 0, -110580525], [0, 21229008864, 211890930, 0], [-20286754915, 20286754915, -232112403, -232112403], [-3604580268, 3604580268, -420926268, -420926268], [26590847800, -26590847800, -25562250, -25562250], [-7919434782, 0, 0, 15314820], [5215013456, 0, 0, -348564636], [-24434792718, 24434792718, -92500782, -92500782], [0, -5890157384, -52689420, 0], [12890969580, 0, 0, -352763124], [33264357568, -33264357568, -30526776, -30526776], [-19928444256, 19928444256, 64123638, 64123638], [5067179026, 0, 0, 127095516], [0, 24849508509, -131210547, 0], [-24541389450, 24541389450, -83987526, -83987526], [-10760807502, 0, 0, -517776504], [7706420216, 0, 0, -268750944], [-43369383981, 43369383981, 195575403, 195575403], [0, -17159523534, 380488332, 0], [0, 2214845178, 579420774, 0], [0, -13601142536, 205909704, 0], [0, 23853254705, -172041327, 0]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_196_e_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_196_8_e_a();".
// 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_196_8_e_a(:prec:=4)
    chi := MakeCharacter_196_e();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 8));
    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_196_8_e_a();".
// 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_196_8_e_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_196_e();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,8,sign)));
    Vf := Kernel([<3,R![12110400, -48720, 3676, 14, 1]>],Snew);
    return Vf;
end function;