
// Make newform 14.10.a.a in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_14_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_14_10_a_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_14_10_a_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
        Kf := Rationals();
    end if;
    return [Kf!elt[1] : elt in input];
end function;


// To make the character of type GrpDrchElt, type "MakeCharacter_14_a();"
function MakeCharacter_14_a()
    N := 14;
    order := 1;
    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;

function MakeCharacter_14_a_Hecke(Kf)
    return MakeCharacter_14_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 := 10;
    raw_aps := [[-16], [-6], [560], [-2401], [-54152], [-113172], [6262], [257078], [-266000], [1574714], [-4637484], [-11946238], [21909126], [27520592], [52927836], [16221222], [-140509618], [-202963560], [153734572], [279655936], [-404022830], [-130689816], [420134014], [-469542390], [-872501690], [-1209014800], [690562580], [179499372], [-1603608446], [1427850374], [-2358727632], [601665350], [-5160087406], [-7143563462], [9104242062], [-289431992], [13906779980], [16623248120], [-15801939652], [3231248996], [-24140781132], [-3893317308], [-25898783016], [15936730670], [-3346846514], [-13426079236], [30170192972], [53502952376], [-40270393242], [19024711756], [-36774761126], [6561095208], [-89681767450], [5337028890], [-83557545870], [108634879584], [141400522724], [-90835285488], [-26507506282], [-186967895078], [-5334125954], [76543346856], [-75194370218], [215133949112], [95907461110], [170586441702], [-123991685200], [-72933538482], [-155720400624], [108728480308], [325585100370], [-227549694616], [-421992952168], [383283068014], [-121461549848], [-397720958420], [67546230866], [124655655588], [351195628398], [-38195614450], [215267665362], [1199326384470], [791117369544], [-1154506168306], [-212728243464], [-64829990396], [-1080312092590], [-64672532042], [429253768988], [1618833928912], [327321126494], [284811101908], [-714775787776], [1015055900868], [1334123745772], [-568444757664], [357172977012], [2179724538534], [-1570808102938], [2245436018118], [-386061536160], [-795101893786], [-2136670256582], [2174610946758], [995075151576], [4305882620962], [5057615223346], [-2802999830598], [3209070700824], [749501715818], [-1740970575744], [-4039771442622], [-2933670336122], [-5776913813138], [3999849053072], [4683278788270], [-1548770030710], [-8144929554756], [-2889250483566], [5202547085824], [2889729962440], [9463624101818], [-6522678603900], [5372402067012], [2015629916966], [-10652253635950], [3461869130642], [-9620251283100], [-3134792007356], [6477745976040], [-1125100195080], [1652656488024], [6032986696104], [-8027976887166], [-6519228061394], [-13424998659842], [7859342513192], [-1477202904306], [-6473266304220], [-15363091195834], [-12905612946746], [893771205094], [-22984443440216], [-2756179886244], [-3159246800024], [19240349793604], [-26080432657540], [21917671626510], [-3555880267366], [22208405716232], [3380040244138], [525102522474], [33397192697588], [-9619644405516], [-20834077302996], [-13378939342224], [-13835163343064], [-17407270665258], [1983612512306], [-23353307899336], [35988225603728], [-13766166749942], [-3027178177936], [-25318283125746], [9907290806298], [24052310333748], [31578178461920], [9322411318328]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_14_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_14_10_a_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_14_10_a_a(:prec:=1)
    chi := MakeCharacter_14_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 10));
    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_14_10_a_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_14_10_a_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_14_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,10,sign)));
    Vf := Kernel([<3,R![6, 1]>],Snew);
    return Vf;
end function;