
// Make newform 6.16.a.c in Magma, downloaded from the LMFDB on 17 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_6_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_6_16_a_c();".
// 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_6_16_a_c();".
// 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_6_a();"
function MakeCharacter_6_a()
    N := 6;
    order := 1;
    char_gens := [5];
    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_6_a_Hecke(Kf)
    return MakeCharacter_6_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], [2187], [77646], [762104], [48011172], [285130118], [-3173671566], [-5895116260], [-333010392], [117285392310], [-225821452768], [-477657973906], [1196721561882], [1066802913668], [1324913565264], [-6573181204962], [7973946241140], [14311350203222], [41052380998124], [67253761134072], [-156200366359942], [-138004701018640], [469396029824988], [-422649074576790], [-201862519502686], [-1094946685080978], [2405527122320408], [1471684888736964], [1455271178948390], [-559505040892782], [-7590790870899136], [-4555957396145748], [12241333378476474], [10699471132287140], [10475022665486910], [-30841966323743128], [38438512830845174], [181401913373708], [-20423064846478056], [12386478221466918], [72907359722973180], [-94529789981627938], [102009529805013312], [12858242550762818], [-100965154186411506], [216643262308643000], [267704962022367452], [19624261639471328], [-299891914134808116], [-56725102540595410], [753633907903675098], [1033522846473576720], [1036882973159911442], [1691016344404221492], [-1962702544409024766], [778447046763167928], [1887370101666168390], [-1739140128093137488], [-479935176452749186], [1261515069413573802], [-546931551959713132], [-5611091905889001042], [-2390948297797832836], [-5531202030635632248], [2011933864416227978], [-8894469863828514666], [-3308256250855376668], [-1848095860420465486], [-12350065659111446316], [-16574248146228054730], [-1499466049562843742], [25644815418830114520], [7241427963681055184], [14142929357337354398], [16086927345490968500], [-145127090154959232], [-3866876232305390130], [-43015021485376220026], [23796584387363269362], [-6062344373303732950], [-15845283802695912180], [-2093644123123108498], [-107407480435668902448], [23825331465445075538], [-29155701498650564920], [-19783093518849490572], [-14784989204241123390], [156631808886609443834], [14185090356899440902], [-30126146489267164432], [-64960938999139374756], [-104052947063029788000], [54457461649450976024], [-5964915429839933628], [85981839922100301500], [10611973127820842568], [184850884473278579670], [-288664262452157760198], [-56356567149567672412], [571586407316617135862], [-171597667467339607156], [-614612221992597125466], [-764192608885993334532], [136011631321307701770], [178797732828619236212], [65069587964911084994], [514130768126491167204], [-683728015510421278542], [914108366757026605800], [-408348782246093966998], [-1219226363526747177376], [224058439187563428398], [-794362224926677433766], [-944258717250868994620], [781223609963084617352], [-1077886765508058648318], [619760254058542470188], [530843875763589674424], [-552087493966920209082], [2297699638966444347420], [903573392459598845822], [-814569272815347905182], [-1847974931621441525586], [1380915504868541206788], [1165066181212194358652], [2404580273243904715542], [1726450907258030692430], [3132443260746925245360], [-4720634707226464695256], [-3051378112758256128202], [-3984344665578197532340], [-3003490674008751567912], [-1354387715167589484208], [-666880751070435938146], [-542504911342479437238], [4693212442861875664130], [-87537163725461973042], [5894832621734249015324], [6933875389128947953974], [5436616022247336534810], [2933938054921412733572], [-7799810507241311367138], [-6337593169602446218552], [2368372789135225197684], [-15001043498479679742250], [3298687405833088583160], [-12480406987705802450242], [15548877287914215183594], [4606468143297100136660], [-3600052600018193654112], [-10313715661335016907866], [-10857909178007646661998], [-3747487169257759149892], [12258768615898391634504], [20989589135926409251364], [18957548404398039311472], [-22198642647652316503960], [2326996435760989228770], [-24602472432986845684966], [-7966765934964951312858], [-29691588008994075706116], [-5753341132794787146102], [-44348279761183615293256], [-39759728453244672439068], [15012597961903882943154], [45346008390677127777768], [-1449340979108942873248], [43747495073880473300654]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_6_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_6_16_a_c();".
// 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_6_16_a_c(:prec:=1)
    chi := MakeCharacter_6_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_6_16_a_c();".
// 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_6_16_a_c( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_6_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,16,sign)));
    Vf := Kernel([<5,R![-77646, 1]>],Snew);
    return Vf;
end function;