
// Make newform 3.67.b.a in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_3_b();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_3_b_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_3_67_b_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_3_67_b_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_3_b();"
function MakeCharacter_3_b()
    N := 3;
    order := 2;
    char_gens := [2];
    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;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_3_b_Hecke();"
function MakeCharacter_3_b_Hecke(Kf)
    N := 3;
    order := 2;
    char_gens := [2];
    char_values := [[-1]];
    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 := 67;
    raw_aps := [[0], [-5559060566555523], [0], [-15459460129734036008401737214], [0], [-10993813372461732057454331126658365206], [0], [-832798423753884127074595015476794447985382], [0], [0], [-20829684874384381866590946759750099977154079183918], [-7417939125211054386881016651493135320203925642789094], [0], [-1245239512199512679501766979615043759328112882443972886], [0], [0], [0], [76718687326389894248157038524144813488758607942856930706762], [236443545730387202454481566607273858427413476877399945116026], [0], [56436561604451561325982235028839350532357796943958932674439634], [624527582495370862537524794357610311427789739490612827187896178], [0], [0], [244251200682546708355692627372351299246029736144700040416696428546], [0], [1687091615377156158443164841581990995594040742332508048003533877954], [0], [-34324188825275387046708861035262125996186873376639851991415054557142], [0], [5208182016283627545992303556307835463173086858245983204268969822827666], [0], [0], [-52759023005833074845900200099637117476246027227305336881776666899831062], [0], [328971136614111182805955664057615536531967100568573636501338690455397602], [-854429000776172990562379577279126087795912610905256608316628332112356214], [11546483372374482176186280620207492092171716464479958958063245119689420794], [0], [0], [0], [-58026611243766297230853626857748085473503492654855634731222162568664574918], [0], [-225295414707144736846632178897110088959597757474857939018838352415784341886], [0], [-3885461015970019810493740048332631806785192575747642600809998623600212837502], [-70362726408027320168147775479188306014000738332721992573393743671302834019238], [-65954741052734078770314356944030985787427050009551445692089240211511999611566], [0], [1429796154566215570846338194634351719073473943250741398602393932526406480989978], [0], [0], [-6924143831016571987456839731625950307486803380201645922461861186624197987689758], [0], [0], [0], [0], [163266751513851873106282513548694953448215375674469446207261559792471205769441522], [691183442327953894742209063169488731652168754935098244370919066873574263509478266], [0], [-486375398363523866344505847791385963022032162961668250911275200475800819397577526], [0], [-23624452281185209071895117625163270950731295481916001105555445241090503591596250214], [0], [-43032304113839808524702544593170562729672304944004820669891473020107562598479768206], [0], [68732313804069304589178394547931821969580808791474474382946859357181318453558245482], [473696083296682807984427052050020230321434932880925548107060403399649303279854798306], [0], [-1599705634225303879746992657331370307161490289203322848219721113276730254177282323702], [0], [0], [-7008921804206002816659329003926546491473871865864854665243714181726775464939937376974], [11580336074175193185234778608359212685253479347372538764524518942239778245366440789434], [-11476954429689194637690471709384719697053075064213538362182831085104532278205367556022], [0], [0], [9841478577688906732802106691244198394474466779674475426297044941726924407318482045546], [0], [-143224812244654973520455558695848896469758890607858499599126925925109687034157530873742], [0], [-748801991839821094877180653322301387998298138509855127070874046968375372135464374616678], [0], [2017978887572175976566148744793352655582003970440701058746931420891277010052065500813474], [1232945880604441213607023847484518885745398123253530730408115002929120271885817353887138], [0], [0], [11878426895397880336123536851611787769253773063976872377884558948683103462767589053810386], [0], [-16296463566673098157654198836247640679406504740863485345140908323235349641180231264379406], [0], [0], [44472079947013121032084878584668911687506853779034620846406565599500566724844242848634306], [0], [165142347774785262707818173662570184032770733734044086383974342231089295972007355369225498], [0], [0], [0], [-586691927310391820192645530433601062041142599764413120564067113802441706019638063725284566], [-2836322931638666187073755127607302623079319955928302574588016267803343939275779743947136758], [-717956197945206426002310996090977051463097552486219272889604683705940066156681180397038854], [0], [0], [0], [15971522555223145726810990719162644392501573230105908132026389167570788484936237416398243722], [23549924067827547774688852248917145725249183185889959433194783059150700768339231351213155266], [0], [0], [0], [-69599247311763940598566781283012093342473855137440006651799921904992877052794593557963920398], [108037249312106955863346698393789438620550623102927650639126719814493834165624842336974207186], [-127210037192983649700509263466624438697583952460070841929227048403929816414864147248676124006], [0], [139663210144096134242513361626947419018428745719478968464792170629470038912881375046068850218], [-127979710701495842936704705653439814191384626311251755035240918342808207550635082977038970718], [0], [899501312019663291154887284483537415856213552326034577663605132676990919734321903850883488314], [0], [0], [0], [213909197420600337628797343214929964693251980728688851611146917023289931030212980440091626362], [2256720957812721117250080012314823467811270249225714977974781862436570031876410729325500693634], [0], [0], [7985367260812390144611868437375931550555310537441869829596824881812537631566338329590994810842], [0], [23242349310371717822096563888429075125547464075730802012827801165725095651274740685465611879258], [0], [-53264305389778302175584516465209183906951615797304696391736879293109307706857627298380310267934], [45666395990774870031666806893330392312634791371664385960887006850683643217681445690959320363274], [-60012890230818202082968182974536531306668209358207422106332476187993798152720407380397434885062], [0], [-113007520728907655133937078463912138671705891913101551007182928198044424601839598932451284837198], [-99406971157480239344745243302029505072763016512288420107408654986096759480675913363831352582214], [0], [249116653570160758709530785719891572522411002702524698722435136863061764211154582713253476809218], [0], [-437842577900766816699082007513300756546557581013061205765363156675782025915327083796211193099494], [0], [0], [1786052904815356041777102798867899396571073902389291985719028041845309209987932518387415994979562], [0], [-2796202542938574756096880071953962744724713573986810564241650573426386554417449506185161212403166], [0], [770745326820676086367583586029654240921058549608576313391697840765608058069654198089625220261578], [0], [77314430362860530781328647453729341496030575818915949646832875461078226532091298118212136165754], [0], [7739898135951585212558502235773393164577095860173959193120758653115189134566526925801528378808458], [0], [23264087415564214732206653916964872457932386272515208545686275619553094446615625698517253318033066], [0], [28693696206160025528859202673688030762158007309832467517109307445743930604053964076594553565136474], [0], [55016208672329773581921538769672291326332757012524395558166750305436386322248042731184711645894186], [0], [-57106796737805422572018435330177198660258189624011860166233029036476241435537324185007119357556382], [0], [182407795551441625357688897130327145004790404873834053757812918035323607572199693429730562261511506], [0], [0], [0], [612965818619848448973226779051651314231190306559559853880432967494415440333442468290362135088026626], [0], [0], [0], [-1028817312184565316260895257288292184933008364814489040494529847183201100443334827343981906965619758], [868647318281746693858426448711696863935033949861858423496705160489585461879988485323518075921409946]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_3_b_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_3_67_b_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_3_67_b_a(:prec:=1)
    chi := MakeCharacter_3_b();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 67));
    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_3_67_b_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_3_67_b_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_3_b();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,67,sign)));
    Vf := Kernel([<2,R![0, 1]>],Snew);
    return Vf;
end function;