
// Make newform 18.23.b.a in Magma, downloaded from the LMFDB on 20 February 2026.
// To make the character of type GrpDrchElt, type "MakeCharacter_18_b();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_18_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_18_23_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_18_23_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
        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_18_b();"
function MakeCharacter_18_b()
    N := 18;
    order := 2;
    char_gens := [11];
    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_18_b_Hecke();"
function MakeCharacter_18_b_Hecke( : Kf := false)
    N := 18;
    order := 2;
    char_gens := [11];
    char_values := [[-1, 0]];
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    values := ConvertToHeckeField(char_values : pass_field := ISA(Type(Kf), Fld), 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]];
    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 := 23;
    raw_aps := [[0, 1024], [0, 0], [0, 19826925], [-1666948276, 0], [0, -130862199588], [399915433112, 0], [0, -3621515694201], [-142603811032336, 0], [0, 102452165990052], [0, -13395230660362317], [5818906190320124, 0], [99489731621460014, 0], [0, -35342963445366687], [846050138097114680, 0], [0, 1667654247291032820], [0, 2862388151293990203], [0, 31055427451064918904], [64862304214149354050, 0], [203569144366409204072, 0], [0, 51271853098342781484], [555984492003263138096, 0], [-76399175592178414876, 0], [0, 1537459924599341476356], [0, -2536415336230224554151], [-5299032201716862372016, 0], [0, -6151529458696154813259], [6761941995012102807188, 0], [0, -19601994035962402606080], [-37386810156520691309464, 0], [0, -35084887582280119613679], [173160604308506865207788, 0], [0, -92919413813984454137880], [0, -171614939589244542945201], [662327828775620154518072, 0], [0, -528957901494312537178605], [-447802516379717809545988, 0], [600775189359543585754142, 0], [-2244246053627795619723496, 0], [0, -1668858672122279705140104], [0, -1481834814105583533825627], [0, -4718128773868904760157584], [5944305178924438202688008, 0], [0, 7408191408744687868628616], [-12371939432210430690194866, 0], [0, 16255778351233162018185333], [17768683098911022695057540, 0], [25695301333711388195937416, 0], [-69365605801656405855510244, 0], [0, 2233470069886740258117468], [-23093438397268888207804072, 0], [0, -115446228615079469049940281], [0, -18272306693436852269505504], [-54382559856018719786054848, 0], [0, -50630947374614884331083884], [0, 197549600873499475487333439], [0, -179282575985504550465363864], [0, -411889825917054066878723043], [1154160977129060751486971660, 0], [1349961351571547088666518888, 0], [0, 583592111105921583650273721], [440376141437814787476824048, 0], [0, -648246632670607629150087861], [362509314240162059272034840, 0], [0, 311228574990903326090362776], [-3810025364223216999237523966, 0], [0, -2681115608337261980093321667], [-4773805610883008372708211784, 0], [-729301740238556850135074512, 0], [0, 2740616147547592867946072796], [-4738687650458798139785497438, 0], [0, 11568432271236452760655143489], [0, 4804039074185014831177578084], [4851225728087180280059215916, 0], [27126017297589157480739381810, 0], [-14450872497796738029001187680, 0], [0, -45554278491379852723210368], [0, -23388651665780903355855727725], [26968566774251563586431522274, 0], [0, -38072319898620372070734095529], [-16851763965317162233670930992, 0], [0, -29621842160665494735436533564], [-4376127597587113559681046520, 0], [0, 110056313808052658830197667332], [38185170632109087028812888158, 0], [161684955421658285020071594956, 0], [0, 104447689416592603201208945172], [0, -119044838482639740682534963287], [300517597206351166682371694480, 0], [0, 224795181776127512911948002027], [146321872593168832806948657044, 0], [0, 7958483745006497801783698188], [0, 411752113799663047290800572452], [-476891544978903886478628605116, 0], [0, 190708521053245679530486439808], [-404277688087676845850332847776, 0], [0, 92668728134936947002823771668], [0, -603068281683089570261630109021], [0, -587994673792383439322155272369], [-780573276135707535067152760864, 0], [1563158586980520818498369276552, 0], [103479439556170176246876884984, 0], [0, -1216046601760943846775161988693], [0, 388206864430955010556244108268], [0, 935600822656943456616749894991], [-31496131914102201296758652752, 0], [2296127724209883021143855182322, 0], [0, 2673929964624615135947296163496], [0, -3117411947188720089764683761393], [0, -3006160439051978663894546872476], [-5312182695366772032340349810242, 0], [-6612109004965181994644944922212, 0], [4935901404539208202184800980722, 0], [0, -4828260408586827743016289731351], [-3762571942021588089119544254464, 0], [-10943031208525905233484742962940, 0], [0, 7428983245456479746119031738343], [-800476793148167153727056726728, 0], [0, 7818224055206308870209319568844], [0, -7348014827734501985265879581163], [0, 12584714423427123195614346164856], [6370691706541028904343902744782, 0], [-1291123455423182195840789850910, 0], [0, -97569222236930392289300465475], [0, -20747996614490482000896024525084], [10311505332077510267646546852920, 0], [0, 1799585919252877930488972781875], [-17699998492961277156026451629992, 0], [0, -33994484305681709620654355705652], [-11182312614202624826855584855372, 0], [-20256011495174526124649951774056, 0], [-2020794878169895867897124140144, 0], [0, -25741757460268894953075523281480], [35596016190247797081612088573388, 0], [-30862506665133145602089187613000, 0], [0, -12203755998408076366725419914671], [11674936372847206979417016577010, 0], [0, 33327048096621675724132480701771], [24186184396644442367405522842160, 0], [0, 100787435171343467139471095178645], [0, 108607590695341322651826750243537], [-143413835082507627174181035103840, 0], [0, 100466124390905379810267069016149], [152617659380137362532146469983068, 0], [0, -55165084463633948698695802603992], [-128731492934339362908014875052248, 0], [0, -173011301630107481251338080642124], [-48627506839431604497812944532146, 0], [0, -32135590582490494287176804237967], [-102265387691124523409457004992712, 0], [0, -42949432928446619230205755486632], [13713038048357515046708686947650, 0], [0, 239779536379525733136333956925903], [378932785044830836513063461841736, 0], [0, 230601589951671360010033676417544], [-93594357803325184434138488426632, 0], [0, -156575932507379001753873394146888], [487000519725826490671231544057420, 0], [0, -184633081039243372695352322381529], [506712032004736342606793683146158, 0], [0, 102609874627434910691847413596491], [0, -612222285702954566902772617818792], [0, -104106693185497283130384461475777], [-331656163368788033281015008555820, 0], [0, 467589392285741030662422611776884], [0, 537317913872571688526830598654313], [0, -612129438261817177488764762788296], [-893498659038092312545629158061172, 0], [121911062734731121832734229614706, 0]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_18_b_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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