
// Make newform 14.16.a.a in Magma, downloaded from the LMFDB on 18 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_16_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_16_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 := 16;
    raw_aps := [[-128], [1350], [-81060], [823543], [70121184], [151469552], [-249756546], [-6476856550], [-21129196200], [7794825354], [-95032053412], [-870082295470], [1007666657262], [155007585272], [-2551970135004], [4047645687774], [-12599248786302], [-39925031318044], [-48423780261124], [37693101366144], [141416194574306], [247020521013128], [2788789610034], [-5839634731110], [278027158065374], [159111963073644], [-1709675288043892], [2169142748872284], [-801542702898286], [-1945683805763034], [-942390434243176], [11191696344143274], [-15242830415217102], [-23066982436852186], [-5229220959645306], [-10263059163540592], [26065286507223920], [42811325023893968], [48563868237390900], [97893215843674584], [-72865709518670508], [-45178594259283304], [115945680294838344], [-240107099023410514], [-308576892656259882], [311534546278429316], [-371643196708473316], [-7620065154789352], [715322102751422826], [-385984363564578976], [708259744819252362], [409558922952153264], [-99494578372258690], [1046541904981179750], [-1389195261358323054], [464878977617854464], [-609641147552224584], [1798636611583373600], [-665763972080255746], [3075855432996997386], [-2286865817501592814], [6014782147318027380], [478607845052117594], [-7553261524329592104], [-3060057073716845026], [-3991501425854576706], [-6582703282308050056], [8409741567269991662], [7422587889873623448], [18799318457759244440], [7987867964252468322], [-21939412306284303648], [27426747182916039032], [22934209092411602342], [-30349767244151274208], [-24730843559134683948], [-37855187704995444894], [53493392241291294920], [-49887808127891154114], [8751584572516705430], [51899377282273262286], [16474504871894802590], [2945886225481874400], [51676754425547779046], [83908838199676107368], [72952769338420143540], [-93614639237125459470], [-76170836716094659930], [-123735914631090703440], [13582801350591955472], [5505771576130155570], [-9962892169873707684], [-94834122443958293656], [-9792693714996126828], [22990311646703338412], [-180849767199272553312], [-241837769622639501960], [-408212488445001920418], [104211192407440485098], [-330897719190053465458], [-138512367685411044856], [-19913141361101158146], [-318834160073337806778], [-758166471549388467834], [-232330889487986971792], [-820976235024568032430], [-46337634519805243314], [713658463261945332042], [612329612932319141400], [-754382774336243587558], [380950451713265910176], [51477753144641692898], [1632888588364069486806], [104020711021035876962], [-703288122125485070176], [-1485072249620272759938], [-621927493689016494826], [-1194574388602073977308], [1723438638993200420082], [-2235395786239298391768], [1401175072778532340052], [-624855241833889588342], [59759411940839938296], [1929470626853040247908], [-576170871304587777142], [-273523610040833942478], [3605996711709618536162], [262331650634911426236], [-2799859830282322551700], [3351192764252185084628], [-1577521294308592637488], [5984026177130288154864], [4925296759329570113984], [-3939585822832861510846], [-7545026697558040756122], [-2815688212846012071610], [-220729400465740332924], [3270717780081517814114], [3123478369386863567928], [-3331073713337919468714], [7286121045257143107818], [-1801777212380626619154], [5076860195535947334776], [8674768890399790849068], [-10532633043978389013964], [9808565587833778486236], [15052561329097171659152], [-14434033360211275091178], [-15294213515074647427162], [-6518225043652553453256], [-6555801033246298768342], [11947558301320857790122], [-12690886548759971163676], [-16338623806145375857572], [-6840605974489155244564], [14347375266441477681000], [-7953653920895981635624], [-497477983636289610978], [-15368421882421629346750], [3841081767166939825812], [23078405418481678907928], [-40578435694323786552102], [-14602108519973180274568], [-9788673380951759327934], [-4806773771086407039510], [-5401586838214328383668], [-26683193155688011407760], [23239573398449108642036]];
    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_16_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_16_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, 16));
    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_16_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_16_a_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_14_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,16,sign)));
    Vf := Kernel([<3,R![-1350, 1]>],Snew);
    return Vf;
end function;