
// Make newform 21.26.g.a in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_21_g();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_21_g_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_21_26_g_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_21_26_g_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, -1, 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_21_g();"
function MakeCharacter_21_g()
    N := 21;
    order := 6;
    char_gens := [8, 10];
    v := [3, 5];
    // 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_21_g_Hecke();"
function MakeCharacter_21_g_Hecke(Kf)
    N := 21;
    order := 6;
    char_gens := [8, 10];
    char_values := [[-1, 0], [0, 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 := 26;
    raw_aps := [[0, 0], [-531441, -531441], [0, 0], [-35728842238, -1722717363], [0, 0], [21081468058559, -42162936117118], [0, 0], [5642266816761114, -2821133408380557], [0, 0], [0, 0], [-1420701470158304875, -1420701470158304875], [0, -70792710091786388161], [0, 0], [181583383500563924875, 0], [0, 0], [0, 0], [0, 0], [-42178864788282994349752, 21089432394141497174876], [55745137266360974031589, -55745137266360974031589], [0, 0], [97052129772454456891191, 97052129772454456891191], [0, 1046591204768194897309693], [0, 0], [0, 0], [-4816266586824017544972488, 9632533173648035089944976], [0, 0], [-27150574699324246767236618, 13575287349662123383618309], [0, 0], [-57317800607531645109888943, 57317800607531645109888943], [0, 0], [24729607227690573547837661, 0], [0, 0], [0, 0], [221936697794068591092529693, -443873395588137182185059386], [0, 0], [2800012593680542205383934876, -2800012593680542205383934876], [-2045703779260868369545811988, -2045703779260868369545811988], [0, -8924980757007963779007589448], [0, 0], [0, 0], [0, 0], [-18369518844975294488576535375, 36739037689950588977153070750], [0, 0], [-21456605903815431372230625625, 21456605903815431372230625625], [0, 0], [-4035724742094009550001095682, -4035724742094009550001095682], [204282520774446056006974815376, 0], [134060104223907647407983466566, -268120208447815294815966933132], [0, 0], [-655058499085611519307882462114, 327529249542805759653941231057], [0, 0], [0, 0], [-442807308341754127310354175376, -442807308341754127310354175376], [0, 0], [0, 0], [0, 0], [0, 0], [-5719797972600205871730384420500, 2859898986300102935865192210250], [-6755521948077221963416095261089, 6755521948077221963416095261089], [0, 0], [2579188261471158796451894669059, 2579188261471158796451894669059], [0, 0], [-13394186617651793627133299439601, 26788373235303587254266598879202], [0, 0], [18666820129978855899543671075514, -9333410064989427949771835537757], [0, 0], [0, -39920772908612614532355051210001], [21286586481396259502395779014875, 0], [0, 0], [-69333228060061620137420234999500, 138666456120123240274840469999000], [0, 0], [0, 0], [114587648244647358600325624569351, 114587648244647358600325624569351], [0, 209230663901333618769182211814573], [-21356222234110872055233655758443, 0], [0, 0], [0, 0], [-73096799814586620128744127760298, 36548399907293310064372063880149], [0, 0], [182122281367897807553948630470057, 182122281367897807553948630470057], [0, 0], [645227478800989973958940437359501, 0], [0, 0], [1031219671729190889820246593792493, -2062439343458381779640493187584986], [2106469892108725693491069698169636, -1053234946054362846745534849084818], [0, 0], [0, 0], [0, 2191927850911009265426973328029161], [0, 0], [4172842146226633464325092066514823, 0], [0, 0], [0, 0], [-4777457823734404013073750684675625, 4777457823734404013073750684675625], [0, 0], [0, -8863095682824516664932226571600443], [0, 0], [0, 0], [0, 0], [21649262999835168710830460819423486, -10824631499917584355415230409711743], [0, 26310415859055240096189339086669251], [-16463997005072349906459420979441000, 0], [0, 0], [0, 0], [0, 0], [-53593779427063792722793131203339249, 53593779427063792722793131203339249], [598582108708898549499567031790899, 598582108708898549499567031790899], [0, 0], [0, 0], [0, 0], [-48584708708371423601048272692000001, 97169417416742847202096545384000002], [-68291956549443971659624528079034726, 34145978274721985829812264039517363], [-129908935168543295666106779052329750, 129908935168543295666106779052329750], [0, 0], [-85732615266184539110941261458104875, -85732615266184539110941261458104875], [200101689825212226730202616158146124, 0], [0, 0], [138823466212797107358561536641860691, -277646932425594214717123073283721382], [0, 0], [0, 0], [0, 0], [-204094296201137495177540348482890249, -204094296201137495177540348482890249], [376686025809569860637933704584836677, 0], [0, 0], [0, 0], [110226123973553431696642656507120502, -55113061986776715848321328253560251], [0, 0], [0, 807483837715183477995454307343183818], [0, 0], [-661255238488215928705634028635492387, 1322510476976431857411268057270984774], [1496757951085602333644084686190935618, -748378975542801166822042343095467809], [-1138694733359863582217037947593190693, 1138694733359863582217037947593190693], [0, 0], [0, 1340335482131458476135386330219491001], [507423081454064250667800967081326214, 0], [0, 0], [505567793593854597624096777323264625, -1011135587187709195248193554646529250], [0, 0], [-1828114596817049653915973253956177762, -1828114596817049653915973253956177762], [0, 0], [0, 0], [-2641313574960313595598243450583454874, 5282627149920627191196486901166909748], [0, 0], [-481308832564639056512122097971187948, 481308832564639056512122097971187948], [0, 0], [-3486871293110519592553745002873179807, -3486871293110519592553745002873179807], [0, 0], [-4693504352925577806558538406044391493, 9387008705851155613117076812088782986], [0, 0], [-10243884776865367384052579883660540500, 5121942388432683692026289941830270250], [0, 0], [0, 5020808495074630043969721704463067714], [0, 0], [9700615666039521641142141651690303073, 0], [0, 0], [6480620875326159414421278038681723339, -6480620875326159414421278038681723339], [0, 0], [0, -8817949643663145412511173427369063761], [0, 0], [14256746923921246844343007371650558851, -28513493847842493688686014743301117702], [0, 0], [0, 0], [0, 0], [-7961864993765346488863812067613919661, 0], [0, 0], [0, 0], [0, 0], [29618378018107157826538946521352145377, -29618378018107157826538946521352145377], [34372146154506412761469728106296572137, 34372146154506412761469728106296572137]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_21_g_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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