
// Make newform 7.9.b.b in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_7_b();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_7_b_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_7_9_b_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_7_9_b_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 := [51570, 0, 1016, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [0, 3506, 0, 4], [0, 15454, 0, 8], [1016, 0, 2, 0]];
    Rf_basisdens := [1, 201, 201, 67];
    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_7_b();"
function MakeCharacter_7_b()
    N := 7;
    order := 2;
    char_gens := [3];
    v := [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_7_b_Hecke();"
function MakeCharacter_7_b_Hecke(Kf)
    N := 7;
    order := 2;
    char_gens := [3];
    char_values := [[-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 := 9;
    raw_aps := [[8, 0, 0, 1], [0, -1, 0, 0], [0, 2, 1, 0], [357, 16, -1, 119], [-5542, 0, 0, -68], [0, -272, 17, 0], [0, -630, -18, 0], [0, 969, 102, 0], [227018, 0, 0, -5984], [-368254, 0, 0, -23324], [0, -2582, -526, 0], [1678818, 0, 0, 29716], [0, 5456, -782, 0], [1437018, 0, 0, 173656], [0, 16966, -3910, 0], [1687394, 0, 0, -379832], [0, 67847, 9826, 0], [0, -67474, 13243, 0], [17506778, 0, 0, -580704], [12475178, 0, 0, -1287818], [0, -49794, -29784, 0], [-20541814, 0, 0, -1054374], [0, 597295, 18428, 0], [0, -801618, 46716, 0], [0, 203798, 13006, 0], [0, 19312, -79849, 0], [0, -639098, -123556, 0], [-10494406, 0, 0, 628048], [-12154014, 0, 0, 17582896], [42991538, 0, 0, -10794014], [19820138, 0, 0, -6984264], [0, 4640675, 8260, 0], [76971554, 0, 0, -26261072], [0, -3834569, 277118, 0], [-486850174, 0, 0, -32774384], [535480458, 0, 0, 31041712], [0, 2619088, -246619, 0], [-559132006, 0, 0, -24735612], [0, -1441414, 176800, 0], [0, -8298500, -514267, 0], [-1064654470, 0, 0, 29583724], [0, 5858334, 382617, 0], [1463686442, 0, 0, 37975330], [-847985262, 0, 0, 42162346], [1173596258, 0, 0, -50103284], [0, 21053598, -1080996, 0], [-923415078, 0, 0, 129514840], [0, 6859568, 1632952, 0], [0, 15246673, -1951174, 0], [0, -14215400, -3252865, 0], [326082338, 0, 0, 39863776], [528279530, 0, 0, -304324496], [0, -57499846, 1492822, 0], [0, -19879443, -74664, 0], [0, -31479988, 2628268, 0], [300111338, 0, 0, 176687086], [0, 45902616, -1187367, 0], [0, -30007992, -8357676, 0], [-1300396606, 0, 0, -461193612], [5301977858, 0, 0, 65713312], [0, 37468597, 5758904, 0], [0, -34478584, -9814049, 0], [0, 48920271, -8144700, 0], [0, -50976436, 10699342, 0], [0, 56282684, 2785570, 0], [5895967778, 0, 0, -800635604], [178484538, 0, 0, 421573972], [3864974514, 0, 0, 179849698], [6791333978, 0, 0, 630294856], [0, -73195846, 1977967, 0], [0, -85202912, -6692968, 0], [-7504256374, 0, 0, 1098364576], [0, -14501392, -5767964, 0], [-24813824062, 0, 0, -434059044], [-8527218054, 0, 0, -537808124], [0, -15508114, -24958754, 0], [-6506131294, 0, 0, -387537764], [0, 349582494, 4493679, 0], [3322112018, 0, 0, 497244322], [0, -114190496, 25627262, 0], [0, -247619125, -39744860, 0], [25395765698, 0, 0, 2529454872], [-7417625878, 0, 0, -1183425080], [0, -195511866, -290190, 0], [0, -5920336, -16586798, 0], [-4464160966, 0, 0, 4214848828], [-413517214, 0, 0, -3133219544], [25077592338, 0, 0, -750070754], [0, -291750566, 40152827, 0], [12220926314, 0, 0, 2356259178], [0, 230258217, 31270038, 0], [0, 386168242, -54740374, 0], [28984976778, 0, 0, -442118864], [-98645183782, 0, 0, 1008536032], [-38403104550, 0, 0, -4823931356], [0, -610091544, 52791546, 0], [0, -330288886, -44156633, 0], [0, 743334264, -3128238, 0], [0, 709854975, 59524038, 0], [81731392898, 0, 0, 2620510152], [-31827726502, 0, 0, 2356566996], [27522917858, 0, 0, -8126615264], [0, 209146529, 134419510, 0], [39615074066, 0, 0, -3617343554], [29022209498, 0, 0, 4542893952], [0, -1386695508, -83053092, 0], [0, -231109781, 119786114, 0], [0, 1080773640, -57822372, 0], [53713956746, 0, 0, 5362915966], [0, 1433482226, 94459648, 0], [0, 610298608, -125468584, 0], [-243431631742, 0, 0, -209054424], [-107854289422, 0, 0, -3453566354], [0, 655204733, 137497324, 0], [-92407251382, 0, 0, 7600556502], [154625076818, 0, 0, 6098641642], [0, 1551277165, -42622162, 0], [0, -1044906258, 67996668, 0], [-151372882366, 0, 0, 10674999448], [-26079787270, 0, 0, 14568629824], [0, 1556414668, 10977359, 0], [147993728514, 0, 0, -10984557752], [0, 460195030, 72290237, 0], [188031665978, 0, 0, 1016997256], [0, -286908865, -326913740, 0], [-62334713278, 0, 0, -8669364200], [-27841944990, 0, 0, 12387616984], [0, -2310128250, 318219090, 0], [0, 869219690, -255683468, 0], [0, 891490234, -222377425, 0], [34678631066, 0, 0, -6556099044], [295521641354, 0, 0, -13790734832], [212837621802, 0, 0, -30656441360], [35113172418, 0, 0, 22017363256], [0, 4742032904, -275857538, 0], [0, 4198999762, 273314066, 0], [0, 1900856802, 216153249, 0], [0, 988097305, -351660778, 0], [0, -3637036780, -42035543, 0], [-423448492654, 0, 0, -24621446834], [0, -1899881751, 43435272, 0], [193183548482, 0, 0, -35407961420], [-369798055702, 0, 0, 31715228526], [339217053338, 0, 0, 32739975436], [0, -942574554, -413171757, 0], [0, -848739146, -8336428, 0], [0, 699406076, 322926031, 0], [0, -1303543916, 349879874, 0], [0, -4718319179, -412586872, 0], [-679145286742, 0, 0, 22586426626], [45970720034, 0, 0, -45682093932], [0, 1947417696, -497395332, 0], [507215441658, 0, 0, -15352876784], [0, -7969727974, 583697500, 0], [39387345594, 0, 0, 7155382348], [276819879338, 0, 0, -24913244048], [189083572266, 0, 0, -8869798874], [0, -8922245726, -17601238, 0], [0, -1240673430, 625584972, 0], [0, 3902309624, -992991743, 0], [818484719354, 0, 0, 18370919848], [648026042498, 0, 0, 35565947536], [-860784189046, 0, 0, 2042109888], [0, 8915310867, -681227094, 0], [321958750178, 0, 0, 54578017216], [0, 4513225282, -467599636, 0], [-1173749051382, 0, 0, 21395963122], [0, -8435447482, -74661059, 0]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_7_b_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_7_9_b_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_7_9_b_b(:prec:=4)
    chi := MakeCharacter_7_b();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 9));
    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_7_9_b_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_7_9_b_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_7_b();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,9,sign)));
    Vf := Kernel([<2,R![-120, -16, 1]>],Snew);
    return Vf;
end function;