
// Make newform 784.4.a.v in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_784_a();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_784_4_a_v();".
// 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_784_4_a_v();".
// 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 := [-2, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rfbasis := [Kf.1^i : i in [0..Degree(Kf)-1]];
    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_784_a();"
function MakeCharacter_784_a()
    N := 784;
    order := 1;
    char_gens := [687, 197, 689];
    v := [1, 1, 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;

function MakeCharacter_784_a_Hecke(Kf)
    return MakeCharacter_784_a();
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 := 4;
    raw_aps := [[0, 0], [0, 1], [0, 10], [0, 0], [-54, 0], [0, 16], [0, 23], [0, 45], [-28, 0], [282, 0], [0, 194], [146, 0], [0, 241], [-10, 0], [0, 358], [598, 0], [0, -407], [0, 330], [-916, 0], [-420, 0], [0, -497], [292, 0], [0, -815], [0, 315], [0, -417], [0, -130], [0, 1334], [1340, 0], [-538, 0], [2068, 0], [944, 0], [0, -321], [-1300, 0], [0, 1977], [-2190, 0], [-1184, 0], [0, 600], [1822, 0], [0, -1082], [0, 1236], [3580, 0], [0, -2064], [484, 0], [-800, 0], [-1686, 0], [0, -78], [-3804, 0], [0, 944], [0, -473], [0, 708], [680, 0], [-1028, 0], [0, -1991], [0, 2761], [0, -4935], [-7580, 0], [0, -632], [0, -3920], [3446, 0], [-5216, 0], [0, -519], [0, 586], [0, 6047], [0, 6040], [0, 1809], [3170, 0], [-6610, 0], [8866, 0], [1046, 0], [0, 7200], [0, 2719], [1904, 0], [0, 8188], [50, 0], [-8830, 0], [0, 2770], [-1278, 0], [0, -1328], [-114, 0], [0, -11565], [0, 4727], [1014, 0], [-3036, 0], [0, -10525], [0, -4452], [10380, 0], [-4898, 0], [1464, 0], [0, 1900], [-13760, 0], [0, -10383], [0, 4862], [-3276, 0], [15956, 0], [10108, 0], [0, -2764], [0, 2512], [0, 10775], [0, -12145], [13666, 0], [5650, 0], [-11430, 0], [0, -9087], [3770, 0], [3370, 0], [0, -1503], [0, 7845], [0, -13781], [23952, 0], [0, -7915], [0, 8908], [-10230, 0], [9046, 0], [0, -6837], [20036, 0], [9690, 0], [0, 3049], [0, -9150], [21910, 0], [23322, 0], [0, -21250], [6820, 0], [0, 11748], [-11140, 0], [0, -7265], [12326, 0], [-7982, 0], [0, -10778], [0, -19146], [0, -12426], [10758, 0], [-27648, 0], [-4236, 0], [7850, 0], [0, -6701], [0, -4275], [0, 10106], [0, -11687], [0, 2192], [-21488, 0], [0, -451], [6534, 0], [-38632, 0], [10564, 0], [0, -23838], [0, -18502], [0, 31680], [0, -27835], [0, -10525], [-8252, 0], [-19190, 0], [0, 8085], [-40580, 0], [0, -19966], [15236, 0], [38568, 0], [24032, 0], [0, 5327], [0, 36423], [0, 33490], [10986, 0], [-36938, 0], [32460, 0], [0, -11711], [14460, 0], [0, 17654], [8480, 0], [0, 8562], [-42208, 0], [0, -6112], [38460, 0], [0, -19740], [-42676, 0], [-47528, 0], [0, 3150], [0, -10855], [-33276, 0], [-12246, 0], [0, 29088], [0, 14270], [-13220, 0], [0, 8515], [-64650, 0], [0, -27205], [57240, 0], [0, -29528], [-21954, 0], [0, -40531], [-75012, 0], [0, -42410], [0, -29495], [21300, 0], [13196, 0], [0, -33124], [-39300, 0], [0, 55471], [-7806, 0], [9602, 0], [0, -12843], [0, -40216], [69630, 0], [0, 48210], [0, 24590], [0, 3965], [0, -35905], [0, 58342], [0, -7002], [-33690, 0], [79420, 0], [0, -395], [68074, 0], [0, 37986], [59488, 0], [0, -5887], [0, 57080], [0, -15885], [22336, 0], [0, 31371], [-32600, 0], [56838, 0], [-68642, 0], [0, -1760], [9902, 0], [-67340, 0], [0, -12187], [-21634, 0], [0, 50891], [10268, 0], [0, 49568], [18010, 0], [36110, 0], [0, 36325], [16000, 0], [39474, 0], [0, -66059], [0, 23568], [0, 14487], [72570, 0], [-37508, 0], [0, 17404], [-19710, 0], [0, 48255], [0, -55276], [7830, 0], [0, -55581], [0, -54970], [0, -34580], [0, 725], [28798, 0], [-56360, 0], [-59110, 0], [0, -84225], [101644, 0], [0, 28595], [0, 33770], [74868, 0], [105110, 0], [0, 20621], [0, -32922], [0, -24523], [-22020, 0], [-62674, 0], [0, -78162], [0, -55974], [0, 20425], [0, 42087], [52482, 0], [0, 75], [-49172, 0], [-650, 0], [0, -35644], [45114, 0], [0, -45769], [53120, 0], [0, 17695], [0, 65364], [-57290, 0], [-106670, 0], [-114004, 0], [0, 28715], [0, 7564], [76504, 0], [0, 101030], [0, 32034], [0, -47107], [-32376, 0], [-12770, 0], [39210, 0], [0, -78098], [0, -74647], [36934, 0], [0, -53053], [125238, 0], [0, 103751], [-20170, 0], [0, 76168], [0, -77504], [0, -66956], [0, 9235], [0, 54003], [0, 38059], [89526, 0], [166872, 0], [-52450, 0], [-103514, 0], [60356, 0], [25110, 0], [0, -14390], [-129860, 0], [-169458, 0], [0, 7440], [-152662, 0], [23020, 0], [-60010, 0], [-21540, 0], [0, -112595], [0, -20095], [39464, 0], [0, -70269], [-146808, 0], [0, -24755], [71476, 0], [0, 64154], [-65748, 0], [-92680, 0], [0, -17579], [-93422, 0], [0, -76065], [-65424, 0], [-22962, 0], [162810, 0], [179334, 0], [0, -73158], [0, 45991], [-36620, 0], [0, 29023], [14438, 0], [0, -60847], [0, 121845], [0, -10722], [70882, 0], [-125826, 0], [0, 130952], [-158724, 0], [-79538, 0], [203274, 0], [0, 24156], [34130, 0], [0, 62984], [0, 9222], [0, -93919], [-180490, 0], [91214, 0], [0, 36666], [-79622, 0], [0, 113017], [0, 8050], [0, -142469], [-107550, 0], [-205692, 0], [46690, 0], [0, 7879], [-72664, 0], [173652, 0], [0, 72045], [-122470, 0], [0, 118748], [-84820, 0], [-97576, 0], [41724, 0], [0, -56015], [-253008, 0], [125938, 0], [0, -7820], [114810, 0], [0, -117795], [53564, 0], [0, 77611], [0, -110543], [0, -39453], [0, -47560], [-98832, 0], [-135624, 0], [-111014, 0], [0, -14077], [0, -132876], [104564, 0], [0, -26738], [203380, 0], [0, -26942], [86978, 0], [0, -77994], [125852, 0], [0, -80195], [155664, 0], [-105780, 0], [0, -17890], [0, 69823], [229284, 0], [-21070, 0], [0, 78390], [55278, 0], [74624, 0], [0, 129443], [0, 61200], [0, -129210], [250694, 0], [166496, 0], [0, 66975], [0, -35375], [0, 121221], [-173210, 0], [-83798, 0], [171140, 0], [135104, 0], [0, 99060], [-188228, 0], [0, 15690], [0, -131095], [0, 34836], [-149122, 0], [0, 117930], [133960, 0], [0, 87895], [0, -162809], [0, -69062], [-63798, 0], [81480, 0], [0, -52489], [0, 47730]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_784_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_784_4_a_v();".
// 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_784_4_a_v(:prec:=2)
    chi := MakeCharacter_784_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 4));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(2999) - 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_784_4_a_v();".
// 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_784_4_a_v( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_784_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<3,R![-2, 0, 1]>,<5,R![-200, 0, 1]>],Snew);
    return Vf;
end function;