
// Make newform 50.22.b.a in Magma, downloaded from the LMFDB on 17 January 2026.
// To make the character of type GrpDrchElt, type "MakeCharacter_50_b();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_50_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_50_22_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_50_22_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 := [1, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [0, 2]];
    Rf_basisdens := [1, 1];
    Rf_basisnums := ChangeUniverse([[z : z in elt] : elt in Rf_num], Kf);
    Rfbasis := [Rf_basisnums[i]/Rf_basisdens[i] : i in [1..Degree(Kf)]];
    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_50_b();"
function MakeCharacter_50_b()
    N := 50;
    order := 2;
    char_gens := [27];
    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_50_b_Hecke();"
function MakeCharacter_50_b_Hecke( : Kf := false)
    N := 50;
    order := 2;
    char_gens := [27];
    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 := 22;
    raw_aps := [[0, 512], [0, 35802], [0, 0], [0, 426601196], [86731179612, 0], [0, -447661721393], [0, -1628783402409], [-23032467644420, 0], [0, 73247857287612], [734051633521170, 0], [-3146664162057568, 0], [0, 6481906800496181], [45714648841476042, 0], [0, -12036803898523778], [0, 224995952586842376], [0, 1032418608545770227], [3780497099978396340, 0], [-7619813346829729138, 0], [0, 9395579008462655366], [-4526486567453771928, 0], [0, -12785727643455221963], [-99336442530925070480, 0], [0, 1479090108943764642], [-118802976167736540090, 0], [0, 284526506962676827151], [-265047048338677414698, 0], [0, 756467877127005512452], [0, 892837773734456856546], [-3338942741755898173310, 0], [0, -1523559102027889840743], [0, 3523400362885668883136], [9427867190096541370932, 0], [0, 1008766657195700991531], [-33865264915070239467740, 0], [34079959428680529569850, 0], [23885647990935177756152, 0], [0, -63657443007835057741879], [0, -118144476996490256596118], [0, 157731755918789812340316], [0, 204176730476347642120287], [-791545410335895474841380, 0], [-473054721711831778539418, 0], [-427959738699386191929408, 0], [0, -942380196105917237711903], [0, -41620783545421573822299], [881455250662631920447000, 0], [3797550729150071156329412, 0], [0, -1960053563660596268347088], [0, 560867176033418945591286], [-379307217709669305087830, 0], [0, 2015072202673586657278917], [17522048813246623378977360, 0], [9552133818580811872325042, 0], [6296547800140430825898252, 0], [0, 7262382893118252294796671], [0, 20671481477066287130480532], [51878570377323278171314530, 0], [-23553826435387451936606128, 0], [0, -26452052569708877336962339], [21792171284949614354133882, 0], [0, -2696215144490891170639658], [0, 19647338438780633940483147], [0, -61913659290082300126035154], [-158511379146348935490707688, 0], [0, 57940792370930693331366157], [0, 25487889871092885646685241], [-464134020445434542696141668, 0], [0, 119546589818316210333266231], [0, 150962654003198247337932426], [-492020983346494986609531950, 0], [0, -334821316125361319526964623], [-589124263059407340786449160, 0], [0, 809133457914706170287805416], [0, 56289601017481875973498387], [-1616874318052205334583223180, 0], [0, -36506946838255762077139008], [-438997518622505007172239990, 0], [0, 669260545854823532152812401], [-2072923943891327771383530798, 0], [412923669842691251058870790, 0], [3559210567975067847593767980, 0], [-3996632669868149870150739178, 0], [5742956413481608410072178032, 0], [0, -3496067911731642563139270983], [8740474328485645446348678760, 0], [0, 5798354672072428901256338022], [-6440839322514293445293894850, 0], [0, 4138457611402242822155285771], [4933147331864705955692077662, 0], [0, -207569743832416173059378168], [0, -3653577838744831128985716834], [13080548385678253201942415520, 0], [0, 8406557959123144924971504956], [-26738164707817603151549347908, 0], [-19281859530195414626414675300, 0], [0, 1231701491951787853330815852], [-23478179567484233200753496910, 0], [56582032760739513813733466922, 0], [0, -13726883060500214786134800338], [-15430221003738954722123991058, 0], [0, -4332460834502912301801279274], [0, -56326744359312503664952398879], [0, -65172698462738625857911148718], [-164552366743807821178715494170, 0], [-96958900506454165565509839028, 0], [0, -6271125200346298161413289889], [0, 106617826483341889645398566706], [0, 28709099928264828553090337097], [11846072718437094733470160200, 0], [16056689917222854927998019002, 0], [0, -49535030401381831653146251504], [0, 72938567557070182477010374507], [0, 47621922852591051301606714491], [336525912761645691571862525380, 0], [8771080533827159585904243032, 0], [42990281080730811456147725442, 0], [0, 23099950996269450214085290522], [0, 22705906661620181161986812076], [0, -82277970619060262613696991473], [-221389916995486531002096073860, 0], [254394831229743764289147486662, 0], [0, 399697122439032541540678939537], [0, -230973462043023831240265136139], [0, 167928677661047422563426436542], [-441273495252691238145124044508, 0], [123968785607929950674469945102, 0], [-1276074245894460529902579837110, 0], [-1070392289269778886827136744720, 0], [0, 382139349424137344227489582436], [0, -593776762926169872672209966633], [-162225251592843254165173393940, 0], [0, 547494126049477987560113538372], [-1438762669406955031347767380048, 0], [0, -106687214970494468651091034579], [3158544482401209831390188998362, 0], [1202659763824440492519723800830, 0], [0, -1169611498859336551254032497413], [0, 646720049316984901224576174206], [0, 207791201804675855366494814601], [6347072519824556191947068180790, 0], [-1032888644525031562803272323588, 0], [5483613524943472364227348514022, 0], [0, 753753096048084659942663939212], [0, -1624577535425630068612549029414], [3886790247853883603726166355570, 0], [4764998790453395984103328868760, 0], [0, 1048526264172345739804034540227], [0, -2967984392993859135168364052829], [2890455276866999727659977368340, 0], [0, -2786720111012971351725412967568], [0, -1618112529899553209734017323839], [3379995690738990470919052114482, 0], [0, -2379893627113899149565083074958], [0, -2140325679138246743436535264044], [0, -2017488037505998420133005007854], [-10096467239240028058405450371888, 0], [20486929945706841944680941462280, 0], [-11515473132924391938185930832930, 0], [0, -7008607795413229565319163516069], [-9635116267138341102510755131458, 0], [0, -8540875044039728049730404416274], [0, -7161926364225483065173011487923], [0, -7197527723902579029876801517684], [-26710664490288908787947401766628, 0], [0, 18185695783327329661771523224311], [0, -14053891352106116947412311380708], [32003754467851191489652033085792, 0], [0, 21051401957767585594423943718101]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_50_b_Hecke( : Kf := Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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