
// Make newform 700.6.e.g in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_700_e();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_700_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_700_6_e_g();".
// 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_700_6_e_g();".
// 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 := [44100, 0, 249001, 0, 998, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 499, 0, 1, 0, 0], [0, 0, 499, 0, 1, 0], [69930, 0, 709, 0, 1, 0], [0, 165957, 0, 832, 0, 1]];
    Rf_basisdens := [1, 1, 210, 210, 210, 210];
    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_700_e();"
function MakeCharacter_700_e()
    N := 700;
    order := 2;
    char_gens := [351, 477, 101];
    v := [2, 1, 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_700_e_Hecke();"
function MakeCharacter_700_e_Hecke(Kf)
    N := 700;
    order := 2;
    char_gens := [351, 477, 101];
    char_values := [[1, 0, 0, 0, 0, 0], [-1, 0, 0, 0, 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 := 6;
    raw_aps := [[0, 0, 0, 0, 0, 0], [0, 1, -2, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 49, 0, 0, 0], [-5, 0, 0, 11, 1, 0], [0, 13, 2, 0, 0, -2], [0, -31, 14, 0, 0, 2], [-779, 0, 0, -6, 9, 0], [0, -70, -1225, 0, 0, -1], [-1359, 0, 0, 99, -15, 0], [1957, 0, 0, -248, 17, 0], [0, -64, 3793, 0, 0, -1], [3827, 0, 0, 142, -31, 0], [0, -322, -6171, 0, 0, -31], [0, -113, 7246, 0, 0, 16], [0, 594, -2496, 0, 0, -6], [-4108, 0, 0, 1840, -64, 0], [9037, 0, 0, -110, 71, 0], [0, -2228, -2556, 0, 0, -8], [27392, 0, 0, 136, -184, 0], [0, -1772, -160, 0, 0, 250], [5277, 0, 0, 3919, 95, 0], [0, -960, 28746, 0, 0, -138], [31861, 0, 0, 2870, 127, 0], [0, -931, -58622, 0, 0, -322], [-8187, 0, 0, -6732, 75, 0], [0, -5259, 18070, 0, 0, -300], [0, -1094, -102584, 0, 0, -8], [50093, 0, 0, -331, 193, 0], [0, 4424, 93593, 0, 0, -1], [0, -3476, -97464, 0, 0, 592], [199911, 0, 0, 3522, -693, 0], [0, 6982, -102335, 0, 0, 367], [-6146, 0, 0, -9774, -858, 0], [282840, 0, 0, -2700, 462, 0], [341969, 0, 0, 1521, 495, 0], [0, 16164, -29674, 0, 0, -576], [0, -826, -83358, 0, 0, 2018], [0, 17579, -70210, 0, 0, -976], [0, 4531, 120268, 0, 0, -2204], [-144460, 0, 0, -9992, -88, 0], [336632, 0, 0, -15270, -114, 0], [59111, 0, 0, 1975, 2657, 0], [0, 1714, -278413, 0, 0, -323], [0, 9810, -280443, 0, 0, -2289], [-564038, 0, 0, -8556, 450, 0], [593147, 0, 0, 13869, -435, 0], [0, -37147, 327900, 0, 0, -1222], [0, -44805, -11856, 0, 0, 798], [-144571, 0, 0, -44866, -341, 0], [0, 20774, 725960, 0, 0, 2222], [420211, 0, 0, 64571, 2773, 0], [812025, 0, 0, 21668, 1219, 0], [-523310, 0, 0, 16466, 34, 0], [0, -33976, -250036, 0, 0, -910], [0, -36078, 190158, 0, 0, 3306], [372564, 0, 0, 29820, 258, 0], [1117809, 0, 0, -42736, 397, 0], [0, -5028, -166228, 0, 0, -426], [-185465, 0, 0, 677, 1435, 0], [0, 14715, -850880, 0, 0, 366], [0, -20961, 993732, 0, 0, 636], [0, -79035, -350620, 0, 0, -4722], [738227, 0, 0, 83698, 275, 0], [0, -4523, -2138500, 0, 0, 6796], [0, -2272, -1629220, 0, 0, -3466], [-637436, 0, 0, 94072, -5128, 0], [0, -55200, 1150958, 0, 0, -2580], [0, -109770, 644979, 0, 0, 8991], [-799463, 0, 0, -68328, 5739, 0], [0, -19485, -1746108, 0, 0, -5232], [1009388, 0, 0, -81608, -172, 0], [0, -24745, 1758322, 0, 0, 4628], [0, -121794, 535441, 0, 0, -12513], [-1416700, 0, 0, 122000, 7984, 0], [0, -172428, 281730, 0, 0, 7410], [-1049211, 0, 0, 43569, 11049, 0], [0, 101237, 2716270, 0, 0, 5534], [-183465, 0, 0, -181893, -6129, 0], [-2896912, 0, 0, 181520, -3134, 0], [402084, 0, 0, -185364, -7632, 0], [-489083, 0, 0, 164131, 65, 0], [-1088283, 0, 0, 205923, -13233, 0], [0, -42100, -3963810, 0, 0, 13784], [-2536922, 0, 0, -89670, -4758, 0], [0, -121658, 2022841, 0, 0, 13477], [2301749, 0, 0, 113263, -17695, 0], [0, 191102, 2708347, 0, 0, 7025], [-3504844, 0, 0, 111850, -1246, 0], [0, 215592, -1404959, 0, 0, 3021], [0, 205945, -2525504, 0, 0, 4114], [-1157439, 0, 0, 93762, -13311, 0], [0, -193670, 2737842, 0, 0, -20162], [-4576923, 0, 0, 107793, 1407, 0], [-4183291, 0, 0, -137767, 20815, 0], [0, -51229, 4870508, 0, 0, 6326], [1388290, 0, 0, -297268, 19048, 0], [-2419263, 0, 0, 119544, -10725, 0], [0, -418584, 1900408, 0, 0, -396], [-1307881, 0, 0, -48003, -1353, 0], [0, 339596, 6435877, 0, 0, 14597], [0, 215062, -1329944, 0, 0, 36358], [0, 176256, 3049188, 0, 0, -10008], [-6561858, 0, 0, 159552, -11400, 0], [-2846834, 0, 0, -189584, -5062, 0], [0, -154233, -210076, 0, 0, -11532], [0, -11532, 4844454, 0, 0, -47814], [0, -576471, -985476, 0, 0, -26724], [-4763861, 0, 0, 225293, 17929, 0], [3950150, 0, 0, 134976, -5604, 0], [0, -398651, -93264, 0, 0, 13438], [0, -170148, 2442130, 0, 0, 33456], [0, -173780, 5776168, 0, 0, 10702], [-7580641, 0, 0, 37310, -10709, 0], [6279519, 0, 0, 38627, 7417, 0], [-531366, 0, 0, 329088, 3960, 0], [0, -100679, -608938, 0, 0, -39224], [0, -910184, -3774386, 0, 0, -21410], [0, -493028, -9433151, 0, 0, -8261], [-7907137, 0, 0, 585457, -5359, 0], [-6076546, 0, 0, 613098, 6108, 0], [0, -547638, -1307201, 0, 0, 5385], [0, -239349, -4880160, 0, 0, -16908], [0, 58780, -2435399, 0, 0, 46393], [-5319350, 0, 0, 205216, -12850, 0], [-2076765, 0, 0, -96231, -43125, 0], [3709967, 0, 0, -61501, -32609, 0], [-8063397, 0, 0, 103050, 45075, 0], [0, -398504, 6754494, 0, 0, 9406], [0, -877903, 6127206, 0, 0, 17210], [7299477, 0, 0, -344987, -69049, 0], [0, 65784, 4570614, 0, 0, -88938], [4524895, 0, 0, -260879, -9139, 0], [0, -436626, -12569038, 0, 0, 13392], [5216951, 0, 0, 386620, -12463, 0], [2527946, 0, 0, -454192, 67516, 0], [0, -46891, 5781518, 0, 0, -4990], [0, 653019, -18772834, 0, 0, -14268], [0, -78771, 1035888, 0, 0, -30792], [7860281, 0, 0, -1285835, 73145, 0], [3188244, 0, 0, 1161914, -38756, 0], [12425029, 0, 0, 360167, 64537, 0], [0, 517216, 19990097, 0, 0, -20555], [0, 363150, 6626682, 0, 0, 11370], [21628837, 0, 0, -451410, 24963, 0], [2679177, 0, 0, -322194, -15927, 0], [0, 489028, 3233438, 0, 0, -6644], [0, -189052, -30520366, 0, 0, 9296], [9465532, 0, 0, -784848, 9288, 0], [0, -795684, 2703693, 0, 0, 40401], [0, 436308, -17202073, 0, 0, -68979], [15172488, 0, 0, 833046, 81978, 0], [0, 237280, -1626247, 0, 0, 89497], [0, 10792, -19802576, 0, 0, 21448], [0, 286090, 2066157, 0, 0, -51815], [18254754, 0, 0, 407424, -88662, 0], [-4954897, 0, 0, 2011571, -32711, 0], [-14876794, 0, 0, 1788562, -47236, 0], [0, -1235843, 3146760, 0, 0, 119236], [14679453, 0, 0, -696486, -119241, 0], [0, 797184, -21698109, 0, 0, 24051], [0, -889134, -2065017, 0, 0, 72825], [0, -134878, 18531556, 0, 0, 22232], [3333, 0, 0, -164856, 112965, 0], [0, -681660, 21518847, 0, 0, 63201], [0, -1124045, 3158764, 0, 0, -73802], [-1503200, 0, 0, -214976, 18176, 0], [0, -422847, -33721888, 0, 0, -48168]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_700_e_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_700_6_e_g();".
// 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_700_6_e_g(:prec:=6)
    chi := MakeCharacter_700_e();
    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_700_6_e_g();".
// 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_700_6_e_g( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_700_e();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,6,sign)));
    Vf := Kernel([<3,R![608400, 0, 246529, 0, 1010, 0, 1]>],Snew);
    return Vf;
end function;