
// Make newform 90.6.c.c in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_90_c();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_90_c_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_90_6_c_c();".
// 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_90_6_c_c();".
// 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 := [97344, 0, 625, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [0, -313, 0, -1], [97656, 1249, 312, 1], [292656, 1, 936, 1]];
    Rf_basisdens := [1, 78, 312, 312];
    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_90_c();"
function MakeCharacter_90_c()
    N := 90;
    order := 2;
    char_gens := [11, 37];
    v := [2, 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_90_c_Hecke();"
function MakeCharacter_90_c_Hecke(Kf)
    N := 90;
    order := 2;
    char_gens := [11, 37];
    char_values := [[1, 0, 0, 0], [-1, 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 := 6;
    raw_aps := [[0, 1, 0, 0], [0, 0, 0, 0], [-1, 0, -1, 0], [-1, -15, 3, -1], [-89, 1, 1, 3], [-3, 78, 9, -3], [-3, 187, 9, -3], [36, 12, 12, 36], [-12, -553, 36, -12], [-1269, 27, 27, 81], [5830, 6, 6, 18], [-19, 2184, 57, -19], [-12560, 34, 34, 102], [-56, -3063, 168, -56], [-6, -1669, 18, -6], [-111, 1629, 333, -111], [-11495, -185, -185, -555], [28754, -96, -96, -288], [-86, 4725, 258, -86], [6126, -294, -294, -882], [-98, -11142, 294, -98], [-7506, 198, 198, 594], [432, -6025, -1296, 432], [-30610, 200, 200, 600], [16, 21414, -48, 16], [50171, 371, 371, 1113], [629, -21723, -1887, 629], [-468, -12333, 1404, -468], [35360, 90, 90, 270], [-447, -15153, 1341, -447], [407, 32241, -1221, 407], [86373, 1275, 1275, 3825], [1107, 16137, -3321, 1107], [159818, -834, -834, -2502], [178699, -977, -977, -2931], [-105926, 1194, 1194, 3582], [607, 60096, -1821, 607], [1958, -70335, -5874, 1958], [48, 36579, -144, 48], [-741, -10721, 2223, -741], [598609, -17, -17, -51], [297848, -858, -858, -2574], [-744078, -402, -402, -1206], [-2606, -53088, 7818, -2606], [387, 66437, -1161, 387], [-50130, 390, 390, 1170], [129342, -4470, -4470, -13410], [-575, 235449, 1725, -575], [-2760, 93283, 8280, -2760], [-48548, -8286, -8286, -24858], [-117, 95617, 351, -117], [-289966, 1838, 1838, 5514], [-481214, 5868, 5868, 17604], [-291951, 1527, 1527, 4581], [-4341, -24999, 13023, -4341], [924, 148679, -2772, 924], [-895131, 3573, 3573, 10719], [-384722, 5502, 5502, 16506], [-1303, 162846, 3909, -1303], [1110798, -900, -900, -2700], [4070, 354309, -12210, 4070], [-1395, 354471, 4185, -1395], [-3252, -5907, 9756, -3252], [-122862, -8370, -8370, -25110], [-6254, -125664, 18762, -6254], [-7503, -262013, 22509, -7503], [-747860, 6876, 6876, 20628], [3494, 93630, -10482, 3494], [876, 441075, -2628, 876], [-299398, -5196, -5196, -15588], [-9309, 541213, 27927, -9309], [1587132, -3156, -3156, -9468], [21383, -165327, -64149, 21383], [13713, 328020, -41139, 13713], [-2620622, -10434, -10434, -31302], [-9930, -701429, 29790, -9930], [812159, 10763, 10763, 32289], [-4075, -210408, 12225, -4075], [-2924128, -8602, -8602, -25806], [-384284, 15402, 15402, 46206], [4398851, 7637, 7637, 22911], [2038012, 6870, 6870, 20610], [-208292, 32620, 32620, 97860], [-3782, -632400, 11346, -3782], [5085342, 13014, 13014, 39042], [-14268, -37545, 42804, -14268], [-220956, 1638, 1638, 4914], [6836, 581814, -20508, 6836], [-1712487, -9195, -9195, -27585], [-5973, -608787, 17919, -5973], [-12852, -30621, 38556, -12852], [420902, -3406, -3406, -10218], [-11427, -7527, 34281, -11427], [-734859, -28389, -28389, -85167], [3107880, -20640, -20640, -61920], [13602, -730125, -40806, 13602], [-742293, -10581, -10581, -31743], [4928108, 10370, 10370, 31110], [-30706, 943797, 92118, -30706], [8670328, -7698, -7698, -23094], [-16312, -581487, 48936, -16312], [32259, -854949, -96777, 32259], [-58692, -276293, 176076, -58692], [-5654884, -25258, -25258, -75774], [-6999212, 37572, 37572, 112716], [44984, 331800, -134952, 44984], [-25500, 1570743, 76500, -25500], [-40455, -1517349, 121365, -40455], [-6956460, -1020, -1020, -3060], [-400168, -38490, -38490, -115470], [-8783, 264741, 26349, -8783], [14479, -2932128, -43437, 14479], [24237, 1081567, -72711, 24237], [-7783730, 330, 330, 990], [7082762, 44370, 44370, 133110], [-2153420, 60214, 60214, 180642], [-73518, -1737267, 220554, -73518], [23070, -1137177, -69210, 23070], [13347, 1740965, -40041, 13347], [13966747, 22549, 22549, 67647], [-270706, 45084, 45084, 135252], [41646, 1579956, -124938, 41646], [7113, 3341299, -21339, 7113], [48912, 303635, -146736, 48912], [18206392, -28920, -28920, -86760], [3332749, -44723, -44723, -134169], [-9726816, -54162, -54162, -162486], [9525272, 13904, 13904, 41712], [43389, 990585, -130167, 43389], [22247, 4145718, -66741, 22247], [7424420, -42780, -42780, -128340], [68538, 3309507, -205614, 68538], [-6353614, 31818, 31818, 95454], [5489, 3823890, -16467, 5489], [8004672, 35598, 35598, 106794], [-4307460, -83730, -83730, -251190], [87723, 2207817, -263169, 87723], [-75802, 4232373, 227406, -75802], [52365, -4550087, -157095, 52365], [10799808, 6846, 6846, 20538], [6245494, -65766, -65766, -197298], [6837197, -113227, -113227, -339681], [78963, 96045, -236889, 78963], [55680, -5641937, -167040, 55680], [-8292012, 48486, 48486, 145458], [7015840, 49000, 49000, 147000], [-77461, 2514972, 232383, -77461], [-85455, 4868463, 256365, -85455], [12929962, 15894, 15894, 47682], [15600, 7477971, -46800, 15600], [-27305, 215412, 81915, -27305], [28524978, -41040, -41040, -123120], [13626, -527439, -40878, 13626], [-19800, -1699257, 59400, -19800], [-36492, -1681587, 109476, -36492], [-12160464, 122976, 122976, 368928], [-4683834, 11022, 11022, 33066], [-25190700, 116790, 116790, 350370], [-52868, -3138624, 158604, -52868], [-6266171, 156937, 156937, 470811], [155676, 5571075, -467028, 155676], [-144555, -2153669, 433665, -144555], [217987, -2533659, -653961, 217987], [-13057695, 110439, 110439, 331317], [49137, 8739807, -147411, 49137], [125550, -2346869, -376650, 125550], [35142202, 135450, 135450, 406350], [-224493, 3637536, 673479, -224493]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_90_c_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_90_6_c_c();".
// 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_90_6_c_c(:prec:=4)
    chi := MakeCharacter_90_c();
    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_90_6_c_c();".
// 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_90_6_c_c( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_90_c();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,6,sign)));
    Vf := Kernel([<7,R![782656576, 0, 68948, 0, 1]>],Snew);
    return Vf;
end function;