$\newcommand{\setC}{\mathbb{C}}$ $\newcommand{\setQ}{\mathbb{Q}}$ Via jupytext this file can be shown as a jupyter notebook.
)cd ..
)read input/jfricas-test-support.input )quiet
The current FriCAS default directory is /home/hemmecke/backup/git/qeta All user variables and function definitions have been cleared. All )browse facility databases have been cleared. Internally cached functions and constructors have been cleared. )clear completely is finished. The current FriCAS default directory is /home/hemmecke/backup/git/qeta/tmp
)set output algebra on
)set output formatted off
This notebook contains supplement material to the article
Construction of Bases for Modular Functions for $\Gamma_0(121)$ related to $p(11n+6)$¶
by
Ralf Hemmecke, Peter Paule, and Silviu Radu.
@article{HemmeckePauleRadu_IntegralBasis_2021,
author = {Ralf Hemmecke and Peter Paule and Cristian-Silviu
Radu},
title = {Construction of Modular Function Bases for
$Gamma_0(121)$ related to $p(11n+6)$},
journal = {Integral Transforms and Special Functions},
volume = 32,
number = {5--8},
pages = {512--527},
year = 2021,
publisher = {Taylor \& Francis},
issn = {1065-2469},
doi = {10.1080/10652469.2020.1806261},
URL =
{https://www.tandfonline.com/doi/abs/10.1080/10652469.2020.1806261},
sponsor = {FWF (SFB F50-06)},
abstract = {Motivated by arithmetic properties of partition
numbers $p(n)$, our goal is to find algorithmically
a Ramanujan type identity of the form
$\sum_{n=0}^{\infty}p(11n+6)q^n=R$, where $R$ is a
polynomial in products of the form
$e_\alpha:=\prod_{n=1}^{\infty}(1-q^{11^\alpha n})$
with $\alpha=0,1,2$. To this end we multiply the
left side by an appropriate factor such the result
is a modular function for $\Gamma_0(121)$ having
only poles at infinity. It turns out that
polynomials in the $e_\alpha$ do not generate the
full space of such functions, so we were led to
modify our goal. More concretely, we give three
different ways to construct the space of modular
functions for $\Gamma_0(121)$ having only poles at
infinity. This in turn leads to three different
representations of $R$ not solely in terms of the
$e_\alpha$ but, for example, by using as generators
also other functions like the modular invariant
$j$.}
}
Since some output is rather big, consider to search for the string
"In [
" within your browser.
This notebook shows how to compute an (order-complete) integral basis for $M^\infty(121)$ with 3 different methods. |
Preparatory steps¶
-------------------------------------------------------------------
--setup
-------------------------------------------------------------------
First we locate the QEta package and load it together with some useful macros into a FriCAS session.
The following assumes that the
QEta
package has already been compiled via
make compile-spad
, i.e. all further computation
is done inside /home/hemmecke/g/qeta/tmp
.
)set mess type off
)set mess time off
C ==> QQ;
)read convenience.input )quiet
smallerMod5?(x, y) == _
positiveRemainder(qetaGrade x, 5) < positiveRemainder(qetaGrade y, 5)
Monoid basis for $E^\infty(121)$¶
We do expansion at the cusp $\infty$ which corresponds to 1/nn
in
terms of our session variables.
nn: PP := 121;
idxs := etaFunctionIndices nn
trfs := cuspMatricesM0 nn;
Show only a few terms of the $q$-series expansion.
)set stream calculate 2
We use 4ti2 to find the monoid basis of the
eta-quotients of level nn
.
We first compute the respective exponent vectors for the
eta-quotients generators.
The variable mspecss
corresponds to the generators of $R^\infty(121)$.
The generators of the eta-quotients of level 121 having a pole only at infinity $E^\infty(121)$ are given by these exponents for the eta-functions (with arguments being the divisors of 121).
mspecs := mSPECSInfM0(nn, idxs);
rgensExpected: List List ZZ := [[1,0,-1],[-1,12,-11]]
assertEquals([pureExponents x for x in mspecs], rgensExpected)
ys := [specYM0EQn spec for spec in mspecs];
xiord := lcm [minimalRootOfUnity x for x in ys]
assertEquals(xiord, 44)
EXTENDEDCOEFFICIENTRING(C, xiord, CX, xi);
As can be seen in the above expansion, some cusps involves computation in $\mathbb{Q}[\xi]$ where $\xi$ is a primitive 44-th root of unity although the $q$-series expansion itself is eventually with rational coefficients.
The corresponding series are the following.
egens := [specM0A1(C)(spec) for spec in mspecs]
Naming convention¶
Our naming convention for elements of $M^\infty(121)$ corresponding to the article is as follows.
We prefix cf
to the variable name of the article, if we simply
consider its corresponding $q$-series.
We prefix the variable name with x
to denote the corresponding
$q$-series together with an indeterminate (a "polynomial part").
All module operations are then done on both parts of the pair so
that we can easily extract relations among the elements by simply
looking at the "polynomial part".
Note that in FriCAS a semicolon separates two expressions and (if given at the end of a line) inhibits the output of the last computation.
xab
=samba($\{t, u\}$) --- Samba with t and u¶
In this section, we compute a $\mathbb{C}[t]$-module basis of the space of eta-quotients $\mathbb{C}[E^\infty(121)]=\mathbb{C}[t, u]$.
xgens := [toX1(C, egens.1, 'T), toX1(C, egens.2, 'U)]
We take a minimal (in terms the pole order in q) element from the
generators and make it special, here xt
of order -5.
Then we compute an algebra basis for $C[t,u]$.
xt := xgens.1;
xu := xgens.2;
xz := toX1(C, first(1/11 * (xu - xt^10)), 'Z);
The output of the algorithm samba
is a pair
consisting of a
multiplier mul
and
basis elements be
.
The multiplier mul
usually corrsponds to the series $t$.
The basis elements are a table, whose entries are
indexed by integers $1, \ldots, n-1$ where
$n=-\mathrm{ord}_q(t)$.
Thus, if $b_1, \ldots, b_{n-1}$ are given by be
,
then the result of samba
represents the module
$\langle 1, b_1, \ldots, b_{n-1}\rangle_{\mathbb{C}[t]}$.
xab := samba(xgens, 96)$QSAMBA(C,X1,QTOPRED)
assertEquals(# basis xab, 4)
xabbas := sort(smallerMod5?, basis xab);
assertEquals([qetaGrade x for x in xabbas], [196,147,98,49])
-- numOfGaps:=[1200, 96] -- numOfGaps:=[909, 96] -- numOfGaps:=[628, 96] -- numOfGaps:=[357, 96] -- numOfGaps:=[96, 96]
Compiling function smallerMod5? with type (QEtaExtendedAlgebra(Fraction( Integer),ModularFunctionQSeriesInfinity(Fraction(Integer)),QEtaLazyAlgebra( Fraction(Integer),Polynomial(Fraction(Integer)))), QEtaExtendedAlgebra( Fraction(Integer),ModularFunctionQSeriesInfinity(Fraction(Integer)), QEtaLazyAlgebra(Fraction(Integer),Polynomial(Fraction(Integer))))) -> Boolean
Clearly, the element after 4 =
corresponds to the element
$z=\frac{1}{11}(u-t^{10})$ from Section 4 of the article.
The variable xab
represents the $\mathbb{Q}[t]$-module
$\langle 1, z, z^2, z^3, z^4 \rangle_{\mathbb{Q}[t]}$.
nog := numberOfGaps(xab);
assertEquals(nog, 96)
The genus of the Riemann surface $X_0(121)$ is a curve of genus 6. Its genus is equal to the genus of $\Gamma_0(121)$.
gen := genus()$GAMMA0(nn);
assertEquals(gen, 6)
Since 6 < 96, it proves that xab
does not represent
an integral basis for $M^\infty(121)$.
Let's set new variables for each series in the basis.
xabz := samba([xt, xz], 96)$QSAMBA(C,X1,QTOPRED);
-- numOfGaps:=[1176, 96] -- numOfGaps:=[891, 96] -- numOfGaps:=[616, 96] -- numOfGaps:=[351, 96] -- numOfGaps:=[96, 96]
With this number of gaps (96), we have not yet reached the genus of the modular curve $X_0(121)$. Thus we must find another modular function.
The generating function $f$ for $p(11n+6)$¶
Let us first construct $c(q)$ such that $$f := c(q) \sum_{n=0}^\infty p(11n+6) q^n \in M^\infty(121). $$
rspec := eqSPEC(1, [-1])
sspec := cofactInfM0(121, etaFunctionIndices 121, rspec, 11, 6)
assertEquals(pureExponents sspec, [11,1,-11])
alpha := alphaInfinity(sspec, rspec, 11, [6])
assertEquals(alpha, -54)
eulerquo: T1 C := qetaTaylorRep eulerExpansion specEQI(C) eqSPEC [[1, -1]];
pp: T1 C := multisect(11-6, 6, eulerquo); ---- p(11n+6)
cofact: T1 C := qetaTaylorRep eulerExpansion specEQI(C) sspec;
f: A1 C := laurent(alpha, cofact * pp)$A1(C)
assertTrue(zero?(f-specM0A1(C)(sspec,rspec,11,6)))
xf: X1 C := toX1(C, f, 'F)
-- == z:=[zinhom=[], zhom=[], zfree=[]] -- >= z:=[zinhom=[[5, -1]], zhom=[[5, -1], [1, 0]], zfree=[]]
The generating series does not reduce to zero modulo the
algebra basis xab
.
xfr := reduce(xf, xab)$QRED(C,X1)
assertTrue(not zero? xfr)
Load function definitions for Klein $j$ function and for the trace map connected to the Atkin-Lehner involution.
)read modfuns.input )quiet
Function declaration kleinJ : (PositiveInteger, Matrix(Integer), PositiveInteger) -> QEtaLaurentSeries(SimpleAlgebraicExtension(Fraction( Integer),UnivariatePolynomial(ξ,Fraction(Integer)),ξ^20+(-(ξ^18))+ξ^16+(-(ξ^ 14))+ξ^12+(-(ξ^10))+ξ^8+(-(ξ^6))+ξ^4+(-(ξ^2))+1)) has been added to workspace. Function declaration kleinJn : (PositiveInteger, NonNegativeInteger) -> ModularFunctionQSeries(SimpleAlgebraicExtension(Fraction(Integer), UnivariatePolynomial(ξ,Fraction(Integer)),ξ^20+(-(ξ^18))+ξ^16+(-(ξ^14))+ξ^12+ (-(ξ^10))+ξ^8+(-(ξ^6))+ξ^4+(-(ξ^2))+1),[[[0,-1],[1,0]],[[1,0],[11,1]],[[2,-1] ,[11,-5]],[[3,1],[11,4]],[[4,1],[11,3]],[[5,-1],[11,-2]],[[6,1],[11,2]],[[7, -2],[11,-3]],[[8,-3],[11,-4]],[[9,4],[11,5]],[[10,-1],[11,-1]],[[1,0],[0,1]]] ) has been added to workspace.
In order to have a fixed order of the factors of the discriminat, we sort the factors by the size of the second coefficient.
absSecondCoefficient(x: Pol C): C ==_
abs(coefficient(x, 'T, (degree(x, 'T)-1)::NN)$Pol(C));
smallerSecondCoefficient?(x, y) == (_
xfac := x.factor; dx := degree(xfac, 'T);_
yfac := y.factor; dy := degree(yfac, 'T);_
dx=dy =>_
(absSecondCoefficient xfac < absSecondCoefficient yfac)@Boolean;_
(dx < dy)@Boolean);
Function declaration absSecondCoefficient : Polynomial(Fraction(Integer)) -> Fraction(Integer) has been added to workspace.
)read projectdir.input )quiet
basedir := PROJECTDIR "/data/integralbasis"
f1d x ==> first lines(format(format(x::OF)$Formatter(Format1D)))
fdfactorsexpected := [_
T,_
T^2-11,_
T^2-2*T+11,_
T^2-3*T+11,_
T^25+430*T^24-31200*T^23+578905*T^22-6007240*T^21+42281581*T^20_
-218350660*T^19+851271410*T^18-2472691265*T^17+4848984855*T^16_
-3205367440*T^15-18988485230*T^14+93248895025*T^13_
-243431953930*T^12+416601090015*T^11-403942642466*T^10_
-112485265695*T^9+1267233014520*T^8-2655224484605*T^7_
+3433152350925*T^6-3075192506826*T^5+1978532471630*T^4_
-978548291765*T^3+412640845925*T^2-129687123005*T+25937424601,_
T^30-920*T^29-19225*T^28+1258030*T^27-19448535*T^26+75396538*T^25_
+2157132615*T^24-50735009930*T^23+643909614260*T^22_
-5980486211480*T^21+44473273280260*T^20-276140775186430*T^19_
+1465665176339650*T^18-6744922810982730*T^17_
+27144546684208910*T^16-95977332323506700*T^15_
+298590013526298010*T^14-816135660128910330*T^13_
+1950800349708074150*T^12-4042977089504521630*T^11_
+7162465135059153260*T^10-10594796133295720280*T^9_
+12547976761628658460*T^8-10875499956118688330*T^7_
+5086405868720041965*T^6+1955592019551431338*T^5_
-5548894011786504885*T^4+3948237050766319630*T^3_
-663699140967073475*T^2-349369846896581720*T+4177248169415651];
)set mess type on
)set mess time on
-------------------------------------------------------------------
--endsetup
-------------------------------------------------------------------
Denominator polynomial $d(T)$ corresponding to $f$¶
-------------------------------------------------------------------
--test:time130-dc
-------------------------------------------------------------------
We compute a polynomial $d(T)$ such that $d(t)f \in \mathbb{Q}[t, u]$.
We only need the coefficients of the pricipal part of $t^{37} f-h_{37}, \ldots, t^{102}f-h_{102}$ where $h_i \in \langle 1, z^1, z^2, z^3, z^4 \rangle_{C[t]}$ in order to find a relation among these $q$-series.
Note that $t$ corresponds to our variable xt
and $1, z^1,\ldots,z^4$
to our basis xabz
.
Then $t^i f - h_i$ corresponds to reduce(xt^i xf, xt, xabz)
.
We first compute all the reductions. That will give us $q$-series of order 191 each. (Takes about 1.5 min.)
e1:=37; e2:=102;
rs := [reduce(xt^e1*xf, xabz)$QRED(C,X1)];
for i in e1+1..e2 repeat (_
rs := cons(reduce(xt*first(rs), xabz)$QRED(C,X1), rs))
rs := reverse! rs;
[qetaGrade x for x in rs]
Extract the 192 coefficients corresponding to the orders $-191, \ldots, 0$ and compute the kernel of the corresponding matrix.
This takes about 20 sec.
l := [[qetaCoefficient(first x, i) for i in 0..191] for x in rs];
mat := transpose matrix l;
ns := nullSpace mat;
assertEquals(#ns, 1)
Extract the coefficients from the vector in the nullspace.
Check that the resulting vector indeed yields a relation, i.e., we
multiply the series $t^i f - h_i$ from above by the corresponding
coefficient from cs
and sum these products.
The result is the zero series (as expected).
lincomp := [c*rr for c in cs for rr in rs];
lc := reduce(_+, lincomp);
assertTrue(zero? lc)
l := [qetaCoefficient(lc, -i) for i in -5..20];
assertEquals(removeDuplicates l, [0])
Indeed, we have just shown a relation for $t^{37} f-h_{37}, \ldots, t^{102}f-h_{102}$.
df := x1Pol(C,lc);
assertEquals(variables df, ['Z,'T,'F])
l := [degree(df, x) for x in variables df];
assertEquals(l, [4,112,1])
Computation of the corresponding polynomials $c_0,..,c_4$¶
In this section we compute a polynomial $c(T, ZZ) := \sum_{k=0}^4 c_k(T) Z^k \in \mathbb{Q}[T,ZZ]$ such that $d(t)f = c(t, z)$.
cf1:=coefficient(df,'F,1); -- The denominator polynomial d(T).
cf0:=coefficient(df,'F,0); -- The polynomial c(T, ZZ).
assertEquals(variables cf0, ['Z,'T])
cf0s := [coefficient(cf0, 'Z, i) for i in 0..4];
l := cons(degree(cf1, 'T), [degree(x, 'T) for x in cf0s]);
assertEquals(l, [102,112,103,93,83,73])
assertEquals(gcd cons(cf1,cf0s), T^37)
Factors of $d(T)$¶
Apart from the $T^{37}$ factor, we get other factors. Below are the factors $d_1, \ldots, d_5$, unsorted.
dfactored := factor cf1;
ud := unit dfactored -- the constant common factor
Now we sort by degree and the size of the second coefficient.
dfactors := factors dfactored;
dfactorssorted := sort(smallerSecondCoefficient?, dfactors);
assertEquals([x.exponent for x in dfactorssorted], [37,1,2,2,1,1])
Compiling function absSecondCoefficient with type Polynomial(Fraction(Integer )) -> Fraction(Integer) Compiling function smallerSecondCoefficient? with type (Record(factor: Polynomial(Fraction(Integer)),exponent: NonNegativeInteger), Record(factor: Polynomial(Fraction(Integer)),exponent: NonNegativeInteger)) -> Boolean Compiling function G26983 with type Integer -> Boolean
fdfactorssorted := [x.factor for x in dfactorssorted];
assertEquals(fdfactorssorted, fdfactorsexpected)
dend := denom(ud::QQ)
Multiplying by the denominator of the constant factor of cf1
and dividing by the common factor give the polynomial $d(T)$
from the article.
d := (-dend * cf1/T^37)::Pol(ZZ); degree(d)
Here we collect all the coefficient polynomials $c_k(t)$ for $k=0,\ldots,4$ after they have been multiplied by the constant denominator.
cis := [(dend*(x/T^37))::Pol(ZZ) for x in cf0s];
l := [leadingCoefficient degree x for x in cis];
assertEquals(l, [75,66,56,46,36])
assertEquals([unit factor x for x in cis],[11,11,22,22,-22])
Each of the polynomials has a constant factor that is divisible by 11. Together with the "freshman's dream" trick for $z = \frac{1}{11}(u-t^{10})$ that show that the $q$-series expansion of $z$ has integer coefficients, this establishes yet another relation that shows that $p(11n+6)$ is divisible by 11.
C11 ==> IntegerLocalizedAtPrime 11
P11 ==> Polynomial C11
Express $d(t)f$ in terms of $t$, $z^1, \ldots, z^4$¶
Plugging into $d$ the respective series, we get a $q$-series of order $-325$.
xd := eval(d,_
(c:ZZ): X1(C) +-> c*1$X1(C),_
['T],_
[xt])$PolynomialEvaluation(ZZ, X1(C));
first xd
assertEquals(qetaGrade first xd, 325)
When multiplied by $f$, it can be reduced to to zero
modulo our algebra basis xabz
.
)set mess time on
xdf := xd*xf;
xdfredz := reduce(xdf, xabz)$QTOPRED(C,X1);
assertTrue(zero? xdfredz)
Of course, it is not surprising that when we clear denominators and
extract the respective polynomial representation (in particular the
coefficient of the variable F
) that we get back our polynomial d.
xdfredz2 := integerPrimitivePart(x1Pol(C,xdfredz)::Pol(QQ));
df0int := coefficient(xdfredz2, F, 0); -- the representation
df1int := coefficient(xdfredz2, F, 1); -- the poly d
assertTrue(zero?(df1int - d))
Express $d(t)f$ in terms of $t$ and $u$¶
xdfred := reduce(xdf, xab)$QRED(C,X1);
assertTrue(zero? xdfred)
Write out the data to a file.
makedir(basedir)$QETAAUX
fh := open(filename(basedir,"dc", "input"), "output")$TextFile
for x in dfactorssorted for i in 1.. repeat_
writeLine!(fh, "exponent" string(i) ":=" f1d(x.exponent) ";")
for x in dfactorssorted for i in 1.. repeat _
writeLine!(fh, "d" string(i) ":=" f1d(x.factor) ";")
for x in cis for i in 0.. repeat _
writeLine!(fh, "c" string(i) ":=" f1d(x::P11) ";")
close! fh
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
xfab=samba($\{t, u, f\}$)¶
-------------------------------------------------------------------
--test:time93-bf
-------------------------------------------------------------------
We know that $$ F(\tau) = q^{\frac{13}{24}} \frac{\eta(\tau)^{11} \eta(11\tau)}{\eta(121\tau)^{11}} \sum_{k=0}^{\infty}p(11k+6)q^k \in M^\infty(121). $$
Let us try to add $F$ to the basis and check whether we come closer to $M^\infty(N)$. We first do a computation without the "representation" part.
That takes 26 seconds, but gives information whether the input elements span a module with gap number 6.
xfgens := [xt, xu, xf]
We know already (by previous computation) that the number of gaps will be 31, so we can abort the computation when we have reached gap number 31 and avoid the remaining reductions to zero.
The computation with "polynomial part", can be done, but yields (at least for one basis element a "representation polynomial" in $T$, $U$, and $F$ that is quite huge. (Computation of algebra basis takes about a minite.)
xfab := samba(xfgens, 31)$QSAMBA(C,X1,QRED);
-- numOfGaps:=[1296, 31] -- numOfGaps:=[981, 31] -- numOfGaps:=[667, 31] -- numOfGaps:=[362, 31] -- numOfGaps:=[58, 31] -- numOfGaps:=[57, 31] -- numOfGaps:=[57, 31] -- numOfGaps:=[56, 31] -- numOfGaps:=[55, 31] -- numOfGaps:=[54, 31] -- numOfGaps:=[53, 31] -- numOfGaps:=[52, 31] -- numOfGaps:=[51, 31] -- numOfGaps:=[50, 31] -- numOfGaps:=[49, 31] -- numOfGaps:=[48, 31] -- numOfGaps:=[47, 31] -- numOfGaps:=[46, 31] -- numOfGaps:=[45, 31] -- numOfGaps:=[44, 31] -- numOfGaps:=[43, 31] -- numOfGaps:=[42, 31] -- numOfGaps:=[41, 31] -- numOfGaps:=[40, 31] -- numOfGaps:=[39, 31] -- numOfGaps:=[38, 31] -- numOfGaps:=[37, 31] -- numOfGaps:=[36, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[34, 31] -- numOfGaps:=[33, 31] -- numOfGaps:=[33, 31] -- numOfGaps:=[32, 31] -- numOfGaps:=[31, 31]
pols := [x1Pol(C,x) for x in basis xfab];
l := [[degree(x,'T), degree(x, 'U), degree(x, 'F)] for x in pols];
assertEquals(l, [[155,8,8],[77,4,4],[42,2,2],[34,2,2]])
l := [# monomials x for x in pols];
assertEquals(l, [4500,750,174,126])
l := [(z := max [leadingCoefficient(xx) for xx in monomials x];_
[length numer z, length denom z]) for x in pols];
assertEquals(l, [[4033,3870],[2013,1928],[446,417],[516,461]])
xfabtopbas := sort(smallerMod5?, basis xfab);
l := [qetaGrade x for x in xfabtopbas];
assertEquals(l, [66, 42, 33, 24])
Write out the data to a file.
makedir(basedir)$QETAAUX
fh := open(filename(basedir,"bf", "input"), "output")$TextFile
for x in xfabtopbas for i in 1.. repeat _
writeLine!(fh, "bf" string(i) ":=" f1d(x) ";")
close! fh
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
xfab=samba($\{t, u, f\}$)¶
-------------------------------------------------------------------
--test:time190-f2
-------------------------------------------------------------------
xfgens := [xt, xu, xf]
The computation with "polynomial part", can be done, but yields (at least for one basis element a "representation polynomial" in $T$, $U$, and $F$ that is quite huge.
--xfab := samba(xt, xfgens, 31, oneVerboseStep!(1,1,0,1))$QSAMBA(C,X1,QTOPRED);
xfab := samba(xfgens, 31)$QSAMBA(C,X1,QTOPRED);
xfbas := basis xfab;
-- numOfGaps:=[1296, 31] -- numOfGaps:=[981, 31] -- numOfGaps:=[667, 31] -- numOfGaps:=[362, 31] -- numOfGaps:=[58, 31] -- numOfGaps:=[57, 31] -- numOfGaps:=[57, 31] -- numOfGaps:=[56, 31] -- numOfGaps:=[55, 31] -- numOfGaps:=[54, 31] -- numOfGaps:=[53, 31] -- numOfGaps:=[52, 31] -- numOfGaps:=[51, 31] -- numOfGaps:=[50, 31] -- numOfGaps:=[49, 31] -- numOfGaps:=[48, 31] -- numOfGaps:=[47, 31] -- numOfGaps:=[46, 31] -- numOfGaps:=[45, 31] -- numOfGaps:=[44, 31] -- numOfGaps:=[43, 31] -- numOfGaps:=[42, 31] -- numOfGaps:=[41, 31] -- numOfGaps:=[40, 31] -- numOfGaps:=[39, 31] -- numOfGaps:=[38, 31] -- numOfGaps:=[37, 31] -- numOfGaps:=[36, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[34, 31] -- numOfGaps:=[33, 31] -- numOfGaps:=[33, 31] -- numOfGaps:=[32, 31] -- numOfGaps:=[31, 31]
The generating function $f_2$ for $p(121n+116)$¶
Next naive attempt: $$f_2 := q^{-604} \frac{(q;q)_\infty^{122}}{(q^{121};q^{121})_\infty^{121}} \sum_{n=0}^\infty p(121n+116) q^n \in M^\infty(121) $$
rspec := eqSPEC[[1,-1]]
sspec2 := cofactInfM0(121, etaFunctionIndices 121, rspec, 121, 116)
ff2 := specM0A1(C)(sspec2, rspec, 121, 116)
xf2 := toX1(C, ff2, 'F2);
-- == z:=[zinhom=[], zhom=[], zfree=[]] -- >= z:=[zinhom=[[60, -10]], zhom=[[5, -1], [1, 0]], zfree=[]]
red121 := reduce(xf2, xab)$QRED(C,X1);
assertTrue(not zero? red121)
assertEquals(qetaGrade red121,191)
red121f := reduce(red121, xfab)$QTOPRED(C,X1);
assertTrue(zero? red121f)
f2rel := integerPrimitivePart x1Pol(C,red121f);
fn: FileName := filename(basedir, "f2", "input")
writeValueToFile(fn, "f2relation", f1d f2rel)
Clearly, the computation above confirms that xf2
is in the $\mathbb{C}[t]$-module generated by $\{1, f, u\}$.
In other words, it lives in the algebra $\mathbb{C}[t, u, f]$.
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
Method 1: integral basis by using the Klein $j$-function¶
-------------------------------------------------------------------
--test:time250-fj
-------------------------------------------------------------------
First expand $t$, $u$, $j(\tau)$, $j(11\tau)$, and $j(11^2\tau)$ at every cusp of $\Gamma_0(121)$.
The elements of ms
are, in fact, the $q$-expansions
(at all cusps of $\Gamma_0(121)$) of the eta-quotients
corresponding to $t$ and $u$, namely
$$
t=\frac{\eta(\tau)}{\eta(121\tau)}
$$
and
$$
u=\frac{\eta(11\tau)^{12}}{\eta(\tau) \eta(121\tau)^{11}}.
$$
ms := [specM0An(CX) x for x in mspecs];
l := [qetaGrades x for x in ms];
assertEquals(l, [_
[-5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5],_
[ 0,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,50]])
The pole orders (computed by the function qetaGrades
)
of $j(\tau)$, $j(11\tau)$, and $j(11^2\tau)$ is given below.
mj0 := kleinJn(nn, 11^0);
mj1 := kleinJn(nn, 11^1);
mj2 := kleinJn(nn, 11^2);
assertEquals(qetaGrades mj0, [121, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
assertEquals(qetaGrades mj1, [ 11,11,11,11,11,11,11,11,11,11,11, 11])
assertEquals(qetaGrades mj2, [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,121])
Compiling function kleinJ with type (PositiveInteger, Matrix(Integer), PositiveInteger) -> QEtaLaurentSeries(SimpleAlgebraicExtension(Fraction( Integer),UnivariatePolynomial(ξ,Fraction(Integer)),ξ^20+(-(ξ^18))+ξ^16+(-(ξ^ 14))+ξ^12+(-(ξ^10))+ξ^8+(-(ξ^6))+ξ^4+(-(ξ^2))+1)) Compiling function kleinJn with type (PositiveInteger, NonNegativeInteger) -> ModularFunctionQSeries(SimpleAlgebraicExtension(Fraction(Integer), UnivariatePolynomial(ξ,Fraction(Integer)),ξ^20+(-(ξ^18))+ξ^16+(-(ξ^14))+ξ^12+ (-(ξ^10))+ξ^8+(-(ξ^6))+ξ^4+(-(ξ^2))+1),[[[0,-1],[1,0]],[[1,0],[11,1]],[[2,-1] ,[11,-5]],[[3,1],[11,4]],[[4,1],[11,3]],[[5,-1],[11,-2]],[[6,1],[11,2]],[[7, -2],[11,-3]],[[8,-3],[11,-4]],[[9,4],[11,5]],[[10,-1],[11,-1]],[[1,0],[0,1]]] ) Compiling function G38946 with type NonNegativeInteger -> Boolean
We can easily figure out by which powers of $t$ and $u$ we have to multiply in order to arrive at elements in $M^\infty(121)$.
mmj0 := mj0*ms.1^25*ms.2; qetaGrades mmj0
mmj1 := mj1*ms.1^3 *ms.2^3; qetaGrades mmj1
mmj2 := mj2*ms.1 *ms.2; qetaGrades mmj2
toA1C x ==> (map(retract,series(x,12))$QEtaLaurentSeriesFunctions2(CX,C))::A1(C)
Then xj0
and xj2
correspond to
$j^\infty_0$ and $j^\infty_2$ from the article,
however, we attach a representational part in
terms of $j_\alpha(\tau):=j(11^\alpha\tau)$.
xj0 := toX1(C, toA1C mmj0, T^25*U*J0)
xj1 := toX1(C, toA1C mmj1, T^3*U^3*J1)
xj2 := toX1(C, toA1C mmj2, T*U*J2)
cfj01ab=samba($\{t, u, j^\infty_0, j^\infty_1\})$¶
Unfortunately the following basis computation only leads to number of gaps = 31.
We do not compute with the extended basis, since then the computation takes quite some time (1440 seconds) to reduce the representation part.
Since we already know that the computation will end with a basis having gap number 31, we can abort the computation when we have reached a basis with gap number 31.
gens := concat([xj0, xj1], xgens)
agens := [first x for x in cons(xt, gens)]
fj01ab := samba(agens, 31)$QSAMBA(C,A1,QTOPRED);
-- numOfGaps:=[4224, 31] -- numOfGaps:=[4224, 31] -- numOfGaps:=[3177, 31] -- numOfGaps:=[2140, 31] -- numOfGaps:=[1113, 31] -- numOfGaps:=[92, 31] -- numOfGaps:=[91, 31] -- numOfGaps:=[91, 31] -- numOfGaps:=[91, 31] -- numOfGaps:=[90, 31] -- numOfGaps:=[90, 31] -- numOfGaps:=[90, 31] -- numOfGaps:=[89, 31] -- numOfGaps:=[89, 31] -- numOfGaps:=[89, 31] -- numOfGaps:=[88, 31] -- numOfGaps:=[88, 31] -- numOfGaps:=[88, 31] -- numOfGaps:=[87, 31] -- numOfGaps:=[87, 31] -- numOfGaps:=[87, 31] -- numOfGaps:=[86, 31] -- numOfGaps:=[86, 31] -- numOfGaps:=[86, 31] -- numOfGaps:=[85, 31] -- numOfGaps:=[85, 31] -- numOfGaps:=[84, 31] -- numOfGaps:=[84, 31] -- numOfGaps:=[83, 31] -- numOfGaps:=[83, 31] -- numOfGaps:=[82, 31] -- numOfGaps:=[82, 31] -- numOfGaps:=[81, 31] -- numOfGaps:=[81, 31] -- numOfGaps:=[80, 31] -- numOfGaps:=[80, 31] -- numOfGaps:=[79, 31] -- numOfGaps:=[79, 31] -- numOfGaps:=[78, 31] -- numOfGaps:=[78, 31] -- numOfGaps:=[77, 31] -- numOfGaps:=[77, 31] -- numOfGaps:=[76, 31] -- numOfGaps:=[76, 31] -- numOfGaps:=[75, 31] -- numOfGaps:=[75, 31] -- numOfGaps:=[74, 31] -- numOfGaps:=[74, 31] -- numOfGaps:=[73, 31] -- numOfGaps:=[73, 31] -- numOfGaps:=[72, 31] -- numOfGaps:=[72, 31] -- numOfGaps:=[71, 31] -- numOfGaps:=[71, 31] -- numOfGaps:=[70, 31] -- numOfGaps:=[70, 31] -- numOfGaps:=[69, 31] -- numOfGaps:=[69, 31] -- numOfGaps:=[68, 31] -- numOfGaps:=[68, 31] -- numOfGaps:=[67, 31] -- numOfGaps:=[67, 31] -- numOfGaps:=[66, 31] -- numOfGaps:=[66, 31] -- numOfGaps:=[65, 31] -- numOfGaps:=[64, 31] -- numOfGaps:=[63, 31] -- numOfGaps:=[62, 31] -- numOfGaps:=[61, 31] -- numOfGaps:=[60, 31] -- numOfGaps:=[59, 31] -- numOfGaps:=[58, 31] -- numOfGaps:=[57, 31] -- numOfGaps:=[56, 31] -- numOfGaps:=[55, 31] -- numOfGaps:=[54, 31] -- numOfGaps:=[53, 31] -- numOfGaps:=[52, 31] -- numOfGaps:=[51, 31] -- numOfGaps:=[50, 31] -- numOfGaps:=[49, 31] -- numOfGaps:=[48, 31] -- numOfGaps:=[47, 31] -- numOfGaps:=[46, 31] -- numOfGaps:=[45, 31] -- numOfGaps:=[44, 31] -- numOfGaps:=[43, 31] -- numOfGaps:=[42, 31] -- numOfGaps:=[41, 31] -- numOfGaps:=[40, 31] -- numOfGaps:=[39, 31] -- numOfGaps:=[38, 31] -- numOfGaps:=[37, 31] -- numOfGaps:=[36, 31] -- numOfGaps:=[35, 31] -- numOfGaps:=[34, 31] -- numOfGaps:=[33, 31] -- numOfGaps:=[32, 31] -- numOfGaps:=[31, 31]
grades := [(qetaGrade x)::PP for x in basis fj01ab]
numberOfGaps(fj01ab)
xjab=samba($\{t, u, j^\infty_0, j^\infty_2\})$¶
Computing with $j^\infty_0$ and $j^\infty_2$ leads to an integral basis, gap number 6 of the respective module, i.e., an (order-complete) integral basis for $\mathbb{C}[t,u,j^\infty_0,j^\infty_2]=M^\infty(121)$.
gens := concat([xj0, xj2], xgens)
With aborting the computation when we have reached gap number = genus, it takes about 400 seconds to compute this basis.
xjab := samba(cons(xt, gens), 6)$QSAMBA(C,X1,QTOPRED);
-- numOfGaps:=[4224, 6] -- numOfGaps:=[4224, 6] -- numOfGaps:=[3177, 6] -- numOfGaps:=[2140, 6] -- numOfGaps:=[1113, 6] -- numOfGaps:=[92, 6] -- numOfGaps:=[91, 6] -- numOfGaps:=[91, 6] -- numOfGaps:=[91, 6] -- numOfGaps:=[90, 6] -- numOfGaps:=[90, 6] -- numOfGaps:=[90, 6] -- numOfGaps:=[89, 6] -- numOfGaps:=[89, 6] -- numOfGaps:=[89, 6] -- numOfGaps:=[88, 6] -- numOfGaps:=[88, 6] -- numOfGaps:=[88, 6] -- numOfGaps:=[87, 6] -- numOfGaps:=[87, 6] -- numOfGaps:=[87, 6] -- numOfGaps:=[86, 6] -- numOfGaps:=[86, 6] -- numOfGaps:=[86, 6] -- numOfGaps:=[85, 6] -- numOfGaps:=[85, 6] -- numOfGaps:=[84, 6] -- numOfGaps:=[84, 6] -- numOfGaps:=[83, 6] -- numOfGaps:=[83, 6] -- numOfGaps:=[82, 6] -- numOfGaps:=[82, 6] -- numOfGaps:=[81, 6] -- numOfGaps:=[81, 6] -- numOfGaps:=[80, 6] -- numOfGaps:=[80, 6] -- numOfGaps:=[79, 6] -- numOfGaps:=[79, 6] -- numOfGaps:=[78, 6] -- numOfGaps:=[78, 6] -- numOfGaps:=[77, 6] -- numOfGaps:=[77, 6] -- numOfGaps:=[76, 6] -- numOfGaps:=[76, 6] -- numOfGaps:=[75, 6] -- numOfGaps:=[75, 6] -- numOfGaps:=[74, 6] -- numOfGaps:=[74, 6] -- numOfGaps:=[73, 6] -- numOfGaps:=[73, 6] -- numOfGaps:=[72, 6] -- numOfGaps:=[72, 6] -- numOfGaps:=[71, 6] -- numOfGaps:=[71, 6] -- numOfGaps:=[70, 6] -- numOfGaps:=[70, 6] -- numOfGaps:=[69, 6] -- numOfGaps:=[69, 6] -- numOfGaps:=[68, 6] -- numOfGaps:=[68, 6] -- numOfGaps:=[67, 6] -- numOfGaps:=[67, 6] -- numOfGaps:=[66, 6] -- numOfGaps:=[66, 6] -- numOfGaps:=[65, 6] -- numOfGaps:=[64, 6] -- numOfGaps:=[63, 6] -- numOfGaps:=[62, 6] -- numOfGaps:=[61, 6] -- numOfGaps:=[60, 6] -- numOfGaps:=[59, 6] -- numOfGaps:=[58, 6] -- numOfGaps:=[57, 6] -- numOfGaps:=[56, 6] -- numOfGaps:=[55, 6] -- numOfGaps:=[54, 6] -- numOfGaps:=[53, 6] -- numOfGaps:=[52, 6] -- numOfGaps:=[51, 6] -- numOfGaps:=[50, 6] -- numOfGaps:=[49, 6] -- numOfGaps:=[48, 6] -- numOfGaps:=[47, 6] -- numOfGaps:=[46, 6] -- numOfGaps:=[45, 6] -- numOfGaps:=[44, 6] -- numOfGaps:=[43, 6] -- numOfGaps:=[42, 6] -- numOfGaps:=[41, 6] -- numOfGaps:=[40, 6] -- numOfGaps:=[39, 6] -- numOfGaps:=[38, 6] -- numOfGaps:=[37, 6] -- numOfGaps:=[36, 6] -- numOfGaps:=[35, 6] -- numOfGaps:=[34, 6] -- numOfGaps:=[33, 6] -- numOfGaps:=[32, 6] -- numOfGaps:=[31, 6] -- numOfGaps:=[30, 6] -- numOfGaps:=[29, 6] -- numOfGaps:=[28, 6] -- numOfGaps:=[27, 6] -- numOfGaps:=[26, 6] -- numOfGaps:=[25, 6] -- numOfGaps:=[24, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[16, 6] -- numOfGaps:=[15, 6] -- numOfGaps:=[14, 6] -- numOfGaps:=[13, 6] -- numOfGaps:=[12, 6] -- numOfGaps:=[11, 6] -- numOfGaps:=[10, 6] -- numOfGaps:=[9, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[7, 6] -- numOfGaps:=[6, 6]
assertEquals(numberOfGaps xjab, 6)
xjabtopbas := sort(smallerMod5?, basis xjab);
assertEquals([qetaGrade x for x in xjabtopbas], [16,7,8,9])
Let us reduce even more, namely the non-leading terms.
)set stream calc 25
xjabbas := [tailReduce(x, xjab)$QRED(C,X1) for x in xjabtopbas];
The basis elements together with their representation in terms of the original series $t$, $u$, $j_0$, and $j_2$ where $j_0=j$ is Klein's $j$-invariant and $j_2(\tau) := j(11^2\tau)$.
bpols := [x1Pol(C,x) for x in xjabbas];
)set stream calc 2
We can reduce $f$ with respect to xjab
in order to find a
polynomial expressing $f$ in terms of $t$, $u$, $j_0$, and $j_2$.
redfj := reduce(xf, xjab)$QTOPRED(C,X1);
assertTrue(zero? redfj)
Write out the data to a file.
fjrel := integerPrimitivePart x1Pol(C,redfj);
fn: FileName := filename(basedir, "fj", "input")
writeValueToFile(fn, "fjrelation", f1d fjrel)
makedir(basedir)$QETAAUX
)set stream calc 20
fh := open(filename(basedir,"bj", "input"), "output")$TextFile
for x in xjabbas for i in 1.. repeat _
writeLine!(fh, "bj" string(i) ":=" f1d(x) ";")
close! fh;
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
Method 2: integral basis obtained with the trace map¶
Preperatory steps¶
-------------------------------------------------------------------
--setup
-------------------------------------------------------------------
We can generate a new modular function by applying the trace to a modular function from $M^\infty(242)$.
Atkin-Lehner involution $W_2^{242}$¶
The trace $\mathrm{tr}_{121}^{242}: M^\infty(242) \to M^\infty(121)$ is given through the Atkin-Lehner involution. See, for example, \cite{Kohnen_WeierstrassPointsAtInfinity_2004}.
In our case we have
$$f|\mathrm{tr}_{121}^{242} = f + 2 f|W_2^{242}|U_2$$
where
$$
W_2^{242}=
\begin{pmatrix}
2 & -1\\
242 & -120
\end{pmatrix}
$$
is given below and $U_2$ is the operator described
in qeta.tex
.
We can split $W_2^{242}$ into an element of $SL_2(\mathbb{Z})$ and a triangular matrix.
alw := matrixAtkinLehner(242, 2)$QETAAUX
sm := splitMatrix(alw(1,1), alw(1,2), alw(2,1), alw(2,2))
gamma := sm.red;
The second matrix just corresponds to going from $\tau$ to $2\tau$. In other words, $$ (f|\mathrm{tr}_{121}^{242})(\tau) = f(\tau) + 2 (f_{\gamma,2}|U_2)(\tau) $$ where $f_{\gamma,2}(\tau) := (f|\gamma)(2\tau)$.
w := widthM0(242, gamma)
The width of the Atkin-Lehner involution $W_2^{242}$ is 2, so the resulting series will be in $q^{1/2}$ which together with the above $\tau\mapsto 2\tau$ neutalizes and we can simply read the resulting series as a series in $q$.
Monoid basis for $E^\infty(242)$¶
Since we can only compute with series coming from eta-quotients, we temporarily switch to level 242 and take the trace of a series from there.
gen242 := genus()$GAMMA0(242);
assertEquals(gen242, 22)
mspecs242 := mSPECSInfM0(242, etaFunctionIndices 242);
assertEquals(#mspecs242, 94)
egens242 := [specM0A1(C) spec for spec in mspecs242];
l := [qetaGrade(x) for x in egens242];
assertEquals(l(1..17),_
[15,55,55,55,55,55,55,60,60,60,60,60,65,65,65,65,66])
For all the series we compute that we need at most a second root of unity, i.e. we continue our computation in $C=\mathbb{Q}$.
mspecs242(1..12)
We have tried to compute the algebra basis for N=121 with the addition of one of the series coming from the N=242 generators and found that the eta-quotient corresponding to $(6, -3, -1, 1, 5, -8)$ works best in the sense that it yields a basis with number of gaps equal to 6 whereas for other indices we get bases with a higher number of gaps.
$$1: (-1, 2, 0, 0, 1, -2) \to 8$$ $$4: (6, -3, -1, 1, 5, -8) \to 6$$ $$6: (0, 0, -4, 8, 4, -8) \to 31$$ $$7: (0, 0, 7, -3, 3, -7) \to 31$$ $$12: (7, -3, -1, 1, 4, -8) \to 6$$
Functions $g$ and $h$¶
So apply the trace function from $M^\infty(242)$ to $M^\infty(121)$.
We do not want to modify trfs, xiord, and CX. Therefore, we call trace without using specTraceM0A1.
It should give the same result as:
trfs := [unitSL2Z]
xiord := 2; xi := -1; CX := C
EXTENDEDCOEFFICIENTRING(C, xiord, CX, xi)
xg := toX1(C, specTraceM0A1(C)(mspecs242.1,nn), 'G)
xh := toX1(C, specTraceM0A1(C)(mspecs242.4,nn), 'H)
YEQQSTools ==> SymbolicEtaQuotientQSeriesTools(C, 2, C, -1, QMOD0)
traceExpan ==> etaQuotientTraceExpansions $ YEQQSTools
tracennInf(spec) ==> traceExpan(spec,nn,[unitSL2Z]).unitSL2Z
xg := toX1(C, tracennInf(mspecs242.1), 'G)
xh := toX1(C, tracennInf(mspecs242.4), 'H)
-------------------------------------------------------------------
--endsetup
-------------------------------------------------------------------
xgab
=samba($\{t, u, g\}$)¶
-------------------------------------------------------------------
--test:bg
-------------------------------------------------------------------
Now we can add this element to the algebra basis computed earlier and hope that we end with a algebra basis for all modular functions of level 121, i.e., $M^\infty(121)$.
xtracebas := [xt, xu, xg]
xgab := samba(xtracebas, 6)$QSAMBA(C,X1,QTOPRED);
assertEquals(numberOfGaps(xgab), 8)
-- numOfGaps:=[1200, 6] -- numOfGaps:=[902, 6] -- numOfGaps:=[607, 6] -- numOfGaps:=[315, 6] -- numOfGaps:=[24, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[16, 6] -- numOfGaps:=[15, 6] -- numOfGaps:=[14, 6] -- numOfGaps:=[13, 6] -- numOfGaps:=[12, 6] -- numOfGaps:=[11, 6] -- numOfGaps:=[10, 6] -- numOfGaps:=[9, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[8, 6]
xgabtopbas := sort(smallerMod5?, basis xgab);
assertEquals([qetaGrade x for x in xgabtopbas], [16,12,13,9])
Let us tail-reduce the Laurent series up to the term of order 0.
)set stream calc 2
xgabbas := [tailReduce(x, xgab)$QRED(C,X1) for x in xgabtopbas];
The gap number is 8, i.e., it does not yield an integral basis for $M^\infty(121)$.
And indeed our modular generating series for $p(11n+6)$ is not in the algebra $C[t,u,g]$.
xr := reduce(xf, xgab)$QTOPRED(C,X1);
assertEquals(qetaGrade xr, 8)
Write out the data to a file.
makedir(basedir)$QETAAUX
fh := open(filename(basedir,"bg", "input"), "output")$TextFile
for x in xgabbas for i in 1.. repeat _
writeLine!(fh, "bg" string(i) ":=" f1d(x) ";")
close! fh;
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
xfgab=samba($\{t, u,f,g\}$)¶
-------------------------------------------------------------------
--test:bfg
-------------------------------------------------------------------
By adding the generating series $f$ for $p(11n+6)$ we indeed arrive at an integral basis.
xtracebas := [xt, xu, xf, xg];
xfgab := samba(xtracebas, 6)$QSAMBA(C,X1,QTOPRED);
assertEquals(numberOfGaps(xfgab), 6)
-- numOfGaps:=[1296, 6] -- numOfGaps:=[974, 6] -- numOfGaps:=[655, 6] -- numOfGaps:=[339, 6] -- numOfGaps:=[24, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[16, 6] -- numOfGaps:=[15, 6] -- numOfGaps:=[14, 6] -- numOfGaps:=[13, 6] -- numOfGaps:=[12, 6] -- numOfGaps:=[11, 6] -- numOfGaps:=[10, 6] -- numOfGaps:=[9, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[7, 6] -- numOfGaps:=[6, 6]
xfgabtopbas := sort(smallerMod5?, basis xfgab);
assertEquals([qetaGrade x for x in xfgabtopbas], [16,7,8,9])
xfgabbas := [tailReduce(x, xfgab)$QRED(C,X1) for x in xfgabtopbas];
fgrels := [x1Pol(C,x) for x in xfgabbas];
assertEquals(removeDuplicates [variables x for x in fgrels],_
[['U,'T,'G,'F]]$List(List Symbol))
The degrees of the polynomial with respect to the variables is given below.
assertEquals([degree(x, 'T) for x in fgrels], [29,28,28,28])
assertEquals([degree(x, 'U) for x in fgrels], [1,1,1,1])
assertEquals([degree(x, 'F) for x in fgrels], [1,1,1,1])
assertEquals([degree(x, 'G) for x in fgrels], [3,3,3,3])
Let's compute the bitlenth of the biggest coefficients of the representation polynomials.
fgrelslc := [[leadingCoefficient m for m in monomials x] for x in fgrels];
[max [length denom c for c in l] for l in fgrelslc]
Write out the data to a file.
makedir(basedir)$QETAAUX
)set stream calc 17
fh := open(filename(basedir,"bfg", "input"), "output")$TextFile
for x in xfgabbas for i in 1.. repeat _
writeLine!(fh, "bfg" string(i) ":=" f1d(x) ";")
close! fh;
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
xghab=samba($\{t,u,g,h\}$)¶
-------------------------------------------------------------------
--test:bgh
-------------------------------------------------------------------
We also arrive at an integral basis if we add both of the series $g$ and $h$ coming from computing the trace of functions from $M^\infty(242)$.
xtracebas := [xt, xu, xg, xh]
xghab := samba(xtracebas, 6)$QSAMBA(C,X1,QTOPRED);
assertEquals(numberOfGaps(xghab), 6)
-- numOfGaps:=[1320, 6] -- numOfGaps:=[992, 6] -- numOfGaps:=[667, 6] -- numOfGaps:=[345, 6] -- numOfGaps:=[24, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[16, 6] -- numOfGaps:=[15, 6] -- numOfGaps:=[14, 6] -- numOfGaps:=[13, 6] -- numOfGaps:=[12, 6] -- numOfGaps:=[11, 6] -- numOfGaps:=[10, 6] -- numOfGaps:=[9, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[7, 6] -- numOfGaps:=[6, 6]
xghabtopbas := sort(smallerMod5?, basis xghab);
assertEquals([qetaGrade x for x in xghabtopbas], [16,7,8,9])
Let us tail-reduce the Laurent series up to the term of order 0.
xghabbas := [tailReduce(x, xghab)$QRED(C,X1) for x in xghabtopbas];
Let us express the generating series $f$ for $p(11n+6)$ as a relation in terms of the original algebra basis elements (in fact, the powers of $z=\frac{1}{11}(u-t^{10})$).
xtracebas := concat([xt, xg, xh], basis xabz);
xghabz := samba(xtracebas, 6)$QSAMBA(C,X1,QTOPRED);
assertEquals(numberOfGaps(xghabz), 6)
-- numOfGaps:=[4704, 6] -- numOfGaps:=[3530, 6] -- numOfGaps:=[2359, 6] -- numOfGaps:=[1191, 6] -- numOfGaps:=[24, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[16, 6] -- numOfGaps:=[15, 6] -- numOfGaps:=[14, 6] -- numOfGaps:=[13, 6] -- numOfGaps:=[12, 6] -- numOfGaps:=[11, 6] -- numOfGaps:=[10, 6] -- numOfGaps:=[9, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[7, 6] -- numOfGaps:=[6, 6]
xghabztopbas := sort(smallerMod5?, basis xghabz);
assertEquals([qetaGrade x for x in xghabztopbas], [16,7,8,9])
Of course the reduction yields zero.
xr := reduce(xf, xghabz)$QRED(C,X1);
assertTrue(zero? xr)
We thus obtain a relation of $f$ in terms of $h$, $g$, $z$, and $t$.
xrpol := integerPrimitivePart(x1Pol(C,xr));
assertEquals(variables(xrpol), ['Z,'T,'H,'G,'F])
assertEquals(# monomials(xrpol),190)
However, this relation does not show that the coefficients of $f$ are divisible by 11, because there is a factor of $11^6$ in the coefficient of $F$ whereas the content of the polynomial without $F$ is 1.
z := exponent(coefficient(xrpol, 'F, 1)::IntegerLocalizedAtPrime(11));
assertEquals(z, 6)
assertEquals(gcd(coefficient(xrpol, 'F, 1), 11),11)
assertTrue(one? content coefficient(xrpol, 'F, 0))
Write out the data to a file.
makedir(basedir)$QETAAUX
)set stream calc 17
fh := open(filename(basedir,"bgh", "input"), "output")$TextFile
for x in xghabbas for i in 1.. repeat _
writeLine!(fh, "bgh" string(i) ":=" f1d(x) ";")
close! fh;
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
xhab=samba($\{t,u,h\}$)¶
-------------------------------------------------------------------
--test:time43-bh
-------------------------------------------------------------------
It is sufficient to add only $h$ to the generators in order to get an integral basis for $M^\infty(121)$.
xtracebas := [xt, xu, xh];
xhab := samba(xtracebas, 6)$QSAMBA(C,X1,QTOPRED);
assertEquals(numberOfGaps(xhab), 6)
-- numOfGaps:=[1320, 6] -- numOfGaps:=[999, 6] -- numOfGaps:=[679, 6] -- numOfGaps:=[368, 6] -- numOfGaps:=[58, 6] -- numOfGaps:=[57, 6] -- numOfGaps:=[57, 6] -- numOfGaps:=[56, 6] -- numOfGaps:=[55, 6] -- numOfGaps:=[54, 6] -- numOfGaps:=[53, 6] -- numOfGaps:=[52, 6] -- numOfGaps:=[51, 6] -- numOfGaps:=[50, 6] -- numOfGaps:=[49, 6] -- numOfGaps:=[48, 6] -- numOfGaps:=[47, 6] -- numOfGaps:=[46, 6] -- numOfGaps:=[45, 6] -- numOfGaps:=[44, 6] -- numOfGaps:=[43, 6] -- numOfGaps:=[42, 6] -- numOfGaps:=[41, 6] -- numOfGaps:=[40, 6] -- numOfGaps:=[39, 6] -- numOfGaps:=[38, 6] -- numOfGaps:=[37, 6] -- numOfGaps:=[36, 6] -- numOfGaps:=[35, 6] -- numOfGaps:=[34, 6] -- numOfGaps:=[33, 6] -- numOfGaps:=[32, 6] -- numOfGaps:=[31, 6] -- numOfGaps:=[30, 6] -- numOfGaps:=[29, 6] -- numOfGaps:=[28, 6] -- numOfGaps:=[27, 6] -- numOfGaps:=[26, 6] -- numOfGaps:=[25, 6] -- numOfGaps:=[24, 6] -- numOfGaps:=[23, 6] -- numOfGaps:=[22, 6] -- numOfGaps:=[21, 6] -- numOfGaps:=[20, 6] -- numOfGaps:=[19, 6] -- numOfGaps:=[18, 6] -- numOfGaps:=[17, 6] -- numOfGaps:=[16, 6] -- numOfGaps:=[15, 6] -- numOfGaps:=[14, 6] -- numOfGaps:=[13, 6] -- numOfGaps:=[12, 6] -- numOfGaps:=[11, 6] -- numOfGaps:=[10, 6] -- numOfGaps:=[9, 6] -- numOfGaps:=[8, 6] -- numOfGaps:=[7, 6] -- numOfGaps:=[6, 6]
xhabtopbas := sort(smallerMod5?, basis xhab);
assertEquals([qetaGrade x for x in xhabtopbas], [16,7,8,9])
Let us tail-reduce the Laurent series up to the term of order 0.
xhabbas := [tailReduce(x, xhab)$QRED(C,X1) for x in xhabtopbas];
hrels := [x1Pol(C,x) for x in xhabbas];
assertEquals(removeDuplicates [variables x for x in hrels],_
[['U,'T,'H]]$List(List Symbol))
The degrees of the polynomial with respect to the variables is given below.
assertEquals([degree(x, 'T) for x in hrels], [74,73,73,73])
assertEquals([degree(x, 'U) for x in hrels], [2,2,2,2])
assertEquals([degree(x, 'H) for x in hrels], [2,2,2,2])
Let's compute the bitlenth of the biggest coefficients of the representation polynomials.
hrelslc := [[leadingCoefficient m for m in monomials x] for x in hrels];
[max [length denom c for c in l] for l in hrelslc]
There must be a relation for $f$ in terms of $\{t,u,h\}$.
xr := reduce(xf, xhab)$QRED(C,X1);
assertTrue(zero? xr)
xrpol := integerPrimitivePart(x1Pol(C,xr));
assertEquals(variables(xrpol), ['U,'T,'H,'F])
assertEquals(# monomials(xrpol), 415)
However, this relation does not show that the coefficients of $f$ are divisible by 11, because there is a factor of $11^{26}$ in the coefficient of $F$ whereas the content of the polynomial without $F$ is 1.
z := exponent(coefficient(xrpol, 'F, 1)::IntegerLocalizedAtPrime(11));
assertEquals(z,24)
assertEquals(gcd(coefficient(xrpol, 'F, 1), 11),11)
assertTrue(one? content coefficient(xrpol, 'F, 0))
There must be a relation for $g$ in terms of $\{t,u,h\}$.
xr := reduce(xg, xhab)$QRED(C,X1);
assertTrue(zero? xr)
xrpol := x1Pol(C,xr);
assertEquals(# monomials(xrpol), 367)
Write out the data to a file.
makedir(basedir)$QETAAUX
)set stream calc 17
fh := open(filename(basedir,"bh", "input"), "output")$TextFile
for x in xhabbas for i in 1.. repeat _
writeLine!(fh, "bh" string(i) ":=" f1d(x) ";")
close! fh;
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
Denominator polynomial $d^*$ for $h$ with respect to xab
¶
-------------------------------------------------------------------
--test:time265-ds
-------------------------------------------------------------------
We compute a polynomial $d^*(T)$ such that $d^*(t)h \in \mathbb{Q}[t, u]$. (Takes about 3 min.)
Multiply with powers of $t$¶
e1:=39; e2:=129
rhs := [reduce(xt^e1*xh, xab)$QRED(C,X1)];
for i in e1+1..e2 repeat (_
rhs := cons(reduce(xt*first(rhs), xab)$QRED(C,X1), rhs))
rhs := reverse! rhs;
assertEquals(removeDuplicates [qetaGrade x for x in rhs], [191])
lh := [[qetaCoefficient(first x, i) for i in 0..191] for x in rhs];
Extract the 192 coefficients corresponding to the orders $-191, \ldots, 0$ and compute the kernel of the corresponding matrix. (Nullspace computation takes about 50 sec.)
math := transpose matrix lh;
assertEquals([nrows math, ncols math], [192,91])
nsh := nullSpace math;
assertEquals(#nsh,1)
Extract the coefficients from the vector in the nullspace.
Check that the resulting vector indeed yields a relation.
lincomph := [c*rr for c in chs for rr in rhs];
lch := reduce(_+, lincomph);
assertTrue(zero? lch)
assertTrue(zero? qetaCoefficient(lch, 0))
Indeed, we have just shown a relation for $t^{39}h-h_{39}, \ldots, t^{129}h-h_{129}$.
In the second component of this "zero" is it's relation in terms of $H$, $T$, and $U$. The "denominator polynomial" is given by the coefficient of $H$.
dh := x1Pol(C,lch);
assertEquals(variables dh, ['U,'T,'H])
assertEquals([degree(dh, x) for x in variables dh],[4,140,1])
Computation of the corresponding polynomials $c_0,..,c_4$¶
In order to find the respective cofactors to the $c_1$
from above, we must do the whole computation with
different attached values, namely $T$, and $U$
for the elements in basis xab
.
In this section we compute a polynomial $c^*(T, ZZ) := \sum_{k=0}^4 c^*_k(T) U^k \in \mathbb{Q}[T,U]$ such that $d^*(t)h = c^*(t, z)$.
ch1:=coefficient(dh,H,1);
ch0:=coefficient(dh,H,0);
assertEquals(variables ch0, ['U,'T])
ch0s := [coefficient(ch0, 'U, i) for i in 0..4];
l := cons(degree(ch1, 'T), [degree(x, 'T) for x in ch0s]);
assertEquals(l, [129,140,130,120,110,100])
assertEquals(gcd cons(ch1,ch0s), T^39)
Factors of $d^*(T)$¶
dstarfactored := factor ch1;
udstar := (unit dstarfactored)::QQ -- the constant common factor
Now we sort by degree and the size of the second coefficient.
dstarfactors := factors dstarfactored;
dstarfactorssorted := sort(smallerSecondCoefficient?, dstarfactors);
assertEquals([x.exponent for x in dstarfactorssorted], [1,2,2,1,1,1])
[39, 1, 2, 2, 1, 1, 1]
assertEquals([x.factor for x in dstarfactorssorted], [_
T,_
T^2-11,_
T^2-2*T+11,_
T^2-3*T+11,_
T^25-55*T^24+1925*T^23-50215*T^22+1116830*T^21-19094526*T^20_
+234488925*T^19-1994909455*T^18+10473000120*T^17_
-10225933245*T^16-403942642466*T^15+4582611990165*T^14_
-29455266425530*T^13+124114279278275*T^12-278010412252430*T^11_
-516227631579440*T^10+8590272458708655*T^9_
-48185757511261315*T^8+182477586874892210*T^7_
-514859434575326060*T^6+1096675319198574181*T^5_
-1713935680161223640*T^4+1816851879425670505*T^3_
-1077108618890647200*T^2+163292428440793630*T+4177248169415651,_
T^25+430*T^24-31200*T^23+578905*T^22-6007240*T^21+42281581*T^20_
-218350660*T^19+851271410*T^18-2472691265*T^17+4848984855*T^16_
-3205367440*T^15-18988485230*T^14+93248895025*T^13_
-243431953930*T^12+416601090015*T^11-403942642466*T^10_
-112485265695*T^9+1267233014520*T^8-2655224484605*T^7_
+3433152350925*T^6-3075192506826*T^5+1978532471630*T^4_
-978548291765*T^3+412640845925*T^2-129687123005*T+25937424601,_
T^30-920*T^29-19225*T^28+1258030*T^27-19448535*T^26+75396538*T^25_
+2157132615*T^24-50735009930*T^23+643909614260*T^22_
-5980486211480*T^21+44473273280260*T^20-276140775186430*T^19_
+1465665176339650*T^18-6744922810982730*T^17_
+27144546684208910*T^16-95977332323506700*T^15_
+298590013526298010*T^14-816135660128910330*T^13_
+1950800349708074150*T^12-4042977089504521630*T^11_
+7162465135059153260*T^10-10594796133295720280*T^9_
+12547976761628658460*T^8-10875499956118688330*T^7_
+5086405868720041965*T^6+1955592019551431338*T^5_
-5548894011786504885*T^4+3948237050766319630*T^3_
-663699140967073475*T^2-349369846896581720*T+4177248169415651])
There is one factor that is not already a factor of cf1
.
fdstarfactors := [x.factor for x in dstarfactorssorted];
[x for x in fdstarfactors | not member?(x, fdfactorsexpected)]
Now we sort by degree and the size of the second coefficient.
dendstar := denom udstar
Multiplying by the denominator of the constant factor of ch1
and dividing by the common factor give the polynomial $d^*(T)$
from the article.
dstar := (-dendstar * ch1/T^39)::Pol(ZZ); degree(dstar)
Here we collect all the coefficient polynomials $c^*_k(t)$ for $k=0,\ldots,4$ after they have been multiplied by the constant denominator.
cstaris := [(denom(udstar)*(x/T^39)::Polynomial(QQ)) for x in ch0s];
Unfortunately, we find that not all denominators have been cleared by multiplication with the denominator of $d^*$. In fact, we would have to multiply the whole relation by 11^4 in order to turn it into a relation with integer coefficients. Thus, our relation does not exhibit that $p(11n+6)$ is divisible by 11 for all $n\in\mathbb{N}$.
z := lcm [lcm [denom leadingCoefficient mon for mon in monomials x]_
for x in cstaris];
assertEquals(z, 11^4)
Write out the data to a file.
makedir(basedir)$QETAAUX
fh := open(filename(basedir,"ds", "input"), "output")$TextFile
for x in dstarfactorssorted for i in 1.. repeat_
writeLine!(fh, "exponent" string(i) ":=" f1d(x.exponent) ";")
for x in dstarfactorssorted for i in 1.. repeat _
writeLine!(fh, "ds" string(i) ":=" f1d(x.factor) ";")
close! fh;
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------
Method 3: integral basis by using Maple's algcurves¶
-------------------------------------------------------------------
--test:time3725-bv
-------------------------------------------------------------------
Minimal polynomial and discriminant¶
xz5r := reduce(xz^5, xabz)$QRED(C,X1);
assertTrue(zero? xz5r)
p5 := x1Pol(C,xz5r);
c5 := coefficient(p5, 'Z, 5);
p := 1/c5 * p5;
discfactors := factors factor discriminant(p, 'Z);
discfactorssorted := sort(smallerSecondCoefficient?, discfactors);
assertEquals([x.exponent for x in discfactorssorted], [4,2,4,4,1,2,2,2])
All the factors of our $d$ polynomial are also factors of the discriminant. We remove the trivial factor of $T^4$.
fdiscfactors := [x.factor for x in discfactorssorted];
l := removeDuplicates [member?(x, fdiscfactors) for x in fdfactorsexpected];
assertEquals(l, [true])
But not all factors of the discriminant are factors of $d$.
l := [member?(x, fdfactorsexpected) for x in fdiscfactors];
assertEquals(l,[true,true,true,true,false,false,true,true]$List(Boolean))
xu5r := reduce(xu^5, xab)$QRED(C,X1);
assertTrue(zero? xu5r)
p := x1Pol(C,xu5r);
assertEquals(p,_
1/108347059433883722041830251*U^5_
+(-5/108347059433883722041830251*T^10_
-2756/9849732675807611094711841*T^9_
-467690/9849732675807611094711841*T^8_
-1561204/895430243255237372246531*T^7_
-19603535/895430243255237372246531*T^6_
-9071001/81402749386839761113321*T^5_
-19603535/81402749386839761113321*T^4_
-1561204/7400249944258160101211*T^3_
-467690/7400249944258160101211*T^2 -2756/672749994932560009201*T_
-5/672749994932560009201)*U^4_
+(10/108347059433883722041830251*T^20_
-10250/9849732675807611094711841*T^19_
+2110692/9849732675807611094711841*T^18_
-6680835/895430243255237372246531*T^17_
+115828261/895430243255237372246531*T^16_
-118310975/81402749386839761113321*T^15_
+978927291/81402749386839761113321*T^14_
-575857717/7400249944258160101211*T^13_
+3019431117/7400249944258160101211*T^12_
-1189902646/672749994932560009201*T^11_
+4310301700/672749994932560009201*T^10_
-1189902646/61159090448414546291*T^9_
+3019431117/61159090448414546291*T^8_
-575857717/5559917313492231481*T^7_
+978927291/5559917313492231481*T^6_
-118310975/505447028499293771*T^5_
+115828261/505447028499293771*T^4 -6680835/45949729863572161*T^3_
+2110692/45949729863572161*T^2 -10250/4177248169415651*T_
+10/4177248169415651)*U^3_
+(-10/108347059433883722041830251*T^30_
-1840/9849732675807611094711841*T^29_
-64610/9849732675807611094711841*T^28_
+575396/895430243255237372246531*T^27_
-17702800/895430243255237372246531*T^26_
+30432597/81402749386839761113321*T^25_
-418611475/81402749386839761113321*T^24_
+411548321/7400249944258160101211*T^23_
-3657564624/7400249944258160101211*T^22_
+20642500/5559917313492231481*T^21_
-1469323818/61159090448414546291*T^20_
+754476860/5559917313492231481*T^19_
-3754698734/5559917313492231481*T^18_
+1506378024/505447028499293771*T^17_
-538231420/45949729863572161*T^16_
+1888549018/45949729863572161*T^15_
-538231420/4177248169415651*T^14 +1506378024/4177248169415651*T^13_
-3754698734/4177248169415651*T^12 +754476860/379749833583241*T^11_
-1469323818/379749833583241*T^10 +20642500/3138428376721*T^9_
-3657564624/379749833583241*T^8 +411548321/34522712143931*T^7_
-418611475/34522712143931*T^6 +30432597/3138428376721*T^5_
-17702800/3138428376721*T^4 +575396/285311670611*T^3_
-64610/285311670611*T^2 -1840/25937424601*T -10/25937424601)*U^2_
+(5/108347059433883722041830251*T^40_
+200/9849732675807611094711841*T^39_
-11670/9849732675807611094711841*T^38_
+2650/81402749386839761113321*T^37_
-515951/895430243255237372246531*T^36_
+597970/81402749386839761113321*T^35_
-5746926/81402749386839761113321*T^34_
+3791255/7400249944258160101211*T^33_
-19347270/7400249944258160101211*T^32_
+4008355/672749994932560009201*T^31_
+32139275/672749994932560009201*T^30_
-45591375/61159090448414546291*T^29_
+362111510/61159090448414546291*T^28_
-190104575/5559917313492231481*T^27_
+845062981/5559917313492231481*T^26_
-23000775/45949729863572161*T^25_
+472340551/505447028499293771*T^24_
+78902210/45949729863572161*T^23_
-1175497010/45949729863572161*T^22 +439316/3138428376721*T^21_
-203391415/379749833583241*T^20 +439316/285311670611*T^19_
-1175497010/379749833583241*T^18 +78902210/34522712143931*T^17_
+472340551/34522712143931*T^16 -23000775/285311670611*T^15_
+845062981/3138428376721*T^14 -190104575/285311670611*T^13_
+362111510/285311670611*T^12 -45591375/25937424601*T^11_
+32139275/25937424601*T^10 +4008355/2357947691*T^9_
-19347270/2357947691*T^8 +3791255/214358881*T^7_
-5746926/214358881*T^6 +597970/19487171*T^5 -515951/19487171*T^4_
+2650/161051*T^3 -11670/1771561*T^2 +200/161051*T +5/161051)*U_
-1/108347059433883722041830251*T^50_
+5/9849732675807611094711841*T^49_
-135/9849732675807611094711841*T^48_
+215/895430243255237372246531*T^47_
-2720/895430243255237372246531*T^46_
+216/7400249944258160101211*T^45_
-17700/81402749386839761113321*T^44_
+9250/7400249944258160101211*T^43 -325/61159090448414546291*T^42_
+9665/672749994932560009201*T^41 -405/61159090448414546291*T^40_
-7680/61159090448414546291*T^39 +1545/5559917313492231481*T^38_
+18675/5559917313492231481*T^37 -16925/505447028499293771*T^36_
+78526/505447028499293771*T^35 -16935/45949729863572161*T^34_
-7515/45949729863572161*T^33 +18955/4177248169415651*T^32_
-48580/4177248169415651*T^31 -1269/34522712143931*T^30_
+154615/379749833583241*T^29 -596565/379749833583241*T^28_
+87400/34522712143931*T^27 +171385/34522712143931*T^26_
-117501/3138428376721*T^25 +171385/3138428376721*T^24_
+87400/285311670611*T^23 -596565/285311670611*T^22_
+154615/25937424601*T^21 -1269/214358881*T^20_
-48580/2357947691*T^19 +18955/214358881*T^18 -7515/214358881*T^17_
-16935/19487171*T^16 +78526/19487171*T^15 -16925/1771561*T^14_
+18675/1771561*T^13 +1545/161051*T^12 -7680/161051*T^11_
-405/14641*T^10 +9665/14641*T^9 -325/121*T^8 +9250/1331*T^7_
-17700/1331*T^6 +216/11*T^5 -2720/121*T^4 +215/11*T^3 -135/11*T^2_
+5*T-1)
assertEquals(variables(p), ['U,'T])
The above polynomial p(T, U) is the respective relation between $t$ and $u$, i.e., $p(t, u)=0$. For the following computation with Maple it has been stored in the file p.maple together with the Maple commands:
with(algcurves);
ib := integral_basis(p,T,U):
lprint(ib);
to compute and print the resulting integral basis (not yet
order-complete).
Via read("p.maple");
this file is evaluated in
Maple.
It gives the integral basis [1, U, U^2, U^3, v(T, U)]
where $v$ is a rational function in $T$ and $U$ and
stored in the file
v.input.
First check whether the file exists locally.
v: Fraction Polynomial ZZ := 0
fn := "v.input" :: FileName
if exists? fn then systemCommand("read v.input )quiet")$MoreSystemCommands;
Then try in the data directory and read it from there.
if zero? v then (_
fn := filename(basedir,"v", "input");_
if exists? fn then _
systemCommand("read " (fn::String) " )quiet")$MoreSystemCommands);
Otherwise read it from the web.
if zero? v then (_
githubraw := "https://raw.githubusercontent.com";_
vurl := githubraw "/hemmecke/qeta-data/master/integralbasis/v.input";_
systemCommand("system curl -L " vurl ">v.input")$MoreSystemCommands;_
systemCommand("read v.input )quiet")$MoreSystemCommands);
Compute the respective $q$-expansion corresponding to $v$ by plugging $t$ and $u$ into the numerator and denominator of $v$.
dv := denom v;
nv := numer v;
degv := degree(nv,'U)
cus := [coefficient(nv, 'U, i) for i in 0..degv];
assertEquals(removeDuplicates [variables x for x in cons(dv,cus)],[[T],[]])
assertEquals([degree(x,'T) for x in cus],[394, 394, 394, 394, 0])
cat := x1A1(C,xt) :: CachedPower A1 C;
cau := x1A1(C,xu) :: CachedPower A1 C;
evTpol(p: Polynomial C, ct: CachedPower A1 C): A1 C == (_
z: A1 C := 0;_
sers := [leadingCoefficient(m)*power!(ct,degree(m,T)) for m in monomials p];_
reduce(_+, reverse! sers, 0)$List(A1 C))
Function declaration evTpol : (Polynomial(Fraction(Integer)), CachedPower( ModularFunctionQSeriesInfinity(Fraction(Integer)))) -> ModularFunctionQSeriesInfinity(Fraction(Integer)) has been added to workspace.
fdv := evTpol(dv, cat);
Compiling function evTpol with type (Polynomial(Fraction(Integer)), CachedPower(ModularFunctionQSeriesInfinity(Fraction(Integer)))) -> ModularFunctionQSeriesInfinity(Fraction(Integer))
nvs :=[evTpol(x,cat)*power!(cau,i) for x in cus for i in 0..degv];
fnv := reduce(_+, nvs, 0)$List(A1 C);
After normalizing the leading coefficient of the series to 1, we obtain a series of order -1670.
fv0 := (fnv/fdv);
fv := (1/qetaLeadingCoefficient(fv0))*fv0;
xv := toX1(C, fv, 'V);
assertEquals(qetaGrade fv, 1670)
Since we already know that
$\langle 1, u, u^2, u^3, v(t,u)\rangle_{\mathbb{C}[t]}=M^\infty(121)$,
computing an order-complete basis (with respect to $t$) from
it via the samba
algorithm, does not require us to
consider products of basis elements.
We simply need to interreduce the basis elements,
i.e., we choose a selection strategy that first reduces
basis elements that become reducible after adding a new
basis element and only then consider products of basis
elements.
The computation of of an order-complete basis avab
takes about
0.5 hours.
)set mess time on
)set stream calc 1
avgens := [x1A1(C, x) for x in [xt, xu, xu^2, xu^3, xv]]
step! ==> oneVerboseStep!(2,257,1,1)$QCOMP(C,A1,QTOPRED)
-- avab := samba(avgens, 6, step!)$QSAMBA(C,A1,QTOPRED);
avab := samba(avgens, 6)$QSAMBA(C,A1,QTOPRED);
avabtopbas := sort(smallerMod5?, basis avab);
-- numOfGaps:=[40080, 6] -- numOfGaps:=[30069, 6] -- numOfGaps:=[20068, 6] -- numOfGaps:=[20068, 6] -- numOfGaps:=[10077, 6] -- numOfGaps:=[10077, 6] -- numOfGaps:=[96, 6] -- numOfGaps:=[96, 6] -- numOfGaps:=[96, 6] -- numOfGaps:=[96, 6] -- numOfGaps:=[96, 6] -- numOfGaps:=[96, 6] -- numOfGaps:=[96, 6] -- numOfGaps:=[96, 6] -- numOfGaps:=[95, 6] -- numOfGaps:=[95, 6] -- numOfGaps:=[94, 6] -- numOfGaps:=[94, 6] -- numOfGaps:=[93, 6] -- numOfGaps:=[93, 6] -- numOfGaps:=[92, 6] -- numOfGaps:=[92, 6] -- numOfGaps:=[91, 6] -- numOfGaps:=[91, 6] -- numOfGaps:=[90, 6] -- numOfGaps:=[90, 6] -- numOfGaps:=[89, 6] -- numOfGaps:=[89, 6] -- numOfGaps:=[88, 6] -- numOfGaps:=[88, 6] -- numOfGaps:=[87, 6] -- numOfGaps:=[87, 6] -- numOfGaps:=[86, 6] -- numOfGaps:=[86, 6] -- numOfGaps:=[85, 6] -- numOfGaps:=[84, 6] -- numOfGaps:=[83, 6] -- numOfGaps:=[82, 6] -- numOfGaps:=[81, 6] -- numOfGaps:=[80, 6] -- numOfGaps:=[79, 6] -- numOfGaps:=[78, 6] -- numOfGaps:=[77, 6] -- numOfGaps:=[76, 6] -- numOfGaps:=[75, 6] -- numOfGaps:=[74, 6] -- numOfGaps:=[73, 6] -- numOfGaps:=[72, 6] -- numOfGaps:=[71, 6] -- numOfGaps:=[70, 6] -- numOfGaps:=[69, 6] -- numOfGaps:=[68, 6] -- numOfGaps:=[67, 6] -- numOfGaps:=[66, 6] -- numOfGaps:=[65, 6] -- numOfGaps:=[64, 6] -- numOfGaps:=[63, 6] -- numOfGaps:=[62, 6] -- numOfGaps:=[61, 6] -- numOfGaps:=[60, 6] -- numOfGaps:=[59, 6] -- numOfGaps:=[58, 6] -- numOfGaps:=[57, 6] -- numOfGaps:=[56, 6] -- numOfGaps:=[55, 6] -- numOfGaps:=[54, 6] -- numOfGaps:=[53, 6] -- numOfGaps:=[52, 6] -- numOfGaps:=[51, 6] -- numOfGaps:=[50, 6] -- numOfGaps:=[49, 6] -- numOfGaps:=[48, 6] -- numOfGaps:=[47, 6] -- numOfGaps:=[46, 6] -- numOfGaps:=[45, 6] -- numOfGaps:=[44, 6] -- numOfGaps:=[42, 6] -- numOfGaps:=[42, 6] -- numOfGaps:=[42, 6] -- numOfGaps:=[6, 6]
Compiling function smallerMod5? with type (ModularFunctionQSeriesInfinity( Fraction(Integer)), ModularFunctionQSeriesInfinity(Fraction(Integer))) -> Boolean
Let us reduce even more, namely the non-leading terms.
)set stream calc 25
avabbas := [tailReduce(x, avab)$QRED(C,A1) for x in avabtopbas]
Now we create a samba basis with xt
and the above elements,
naming them B1
up to B4
.
bsyms := indexedSymbols("B", # basis avab);
xvgens := cons(xt, [toX1(C, x, b) for x in avabbas for b in bsyms]);
xvab := samba(xvgens, 6)$QSAMBA(C,X1,QTOPRED);
assertEquals(numberOfGaps(xvab), 6)
-- numOfGaps:=[384, 6] -- numOfGaps:=[289, 6] -- numOfGaps:=[194, 6] -- numOfGaps:=[99, 6] -- numOfGaps:=[99, 6] -- numOfGaps:=[99, 6] -- numOfGaps:=[6, 6]
xvabbas := basis xvab
assertEquals([qetaGrade x for x in xvabbas], [16,7,8,9])
We have just computed a basis $B=\{1,b_1,b_2,b_3,b_4\}$ such that \begin{align*} M^\infty(121) &= \langle 1,u,u^2,u^3,v(t,u)\rangle_{\setC[t]}= \langle 1,b_1,b_2,b_3,b_4\rangle_{\setC[t]}. \end{align*}
Since $\{1,u,u^2,u^3,v(t,u)\}$ is an integral basis of $M^\infty(121)$ over $\setC[t]$, also $B$ is an integral basis, i.e., each element $\phi$ of $M^\infty(121)$ can be expressed as \begin{align*} \phi &= p_0(t) + p_1(t)b_1 + p_2(t)b_2 + p_3(t)b_3 + p_4(t)b_4. \end{align*} for some polynomials $p_i(T)\in\setC[T]$.
In particular, we can express $u,u^2,u^3,v(t,u)$ as a $\setQ[t]$-linear combination of the elements of $B$.
)set stream calc 0
-- Set the trace argument to 1 to see some output during the computation
tr0 := traceEnter(0)$QTOPRED(C,X1);
trl := traceLoop(0)$QTOPRED(C,X1);
trr := traceReturn(0)$QTOPRED(C,X1);
treduce := tracedTopReduce(tr0,trl,trr)$QTOPRED(C,X1);
xu1r := treduce(xu, xvab);
xu2r := treduce(xu^2, xvab);
xu3r := treduce(xu^3, xvab);
xv1r := treduce(xv, xvab);
xrs := [xu1r, xu2r, xu3r, xv1r];
assertEquals([zero? x for x in xrs], [true,true,true,true])
upols := [integerPrimitivePart x1Pol(C,x) for x in xrs];
assertEquals([# monomials x for x in upols], [46, 96, 146, 1666])
[[degree m for m in monomials x] for x in upols]
assertEquals([max [wholePart floor((log(euclideanSize numer leadingCoefficient m)/log(10.0))::Float) for m in monomials x] for x in upols], [8, 18, 29, 840])
Write out the data to a file.
makedir(basedir)$QETAAUX
)set stream calc 1700
fh := open(filename(basedir,"bv", "input"), "output")$TextFile
for x in xvabbas for i in 1.. repeat _
writeLine!(fh, "bv" string(i) ":=" f1d(x1A1(C, x)) ";")
uvbsyms := concat([U,V], bsyms)
for x in upols for var in ["pu1", "pu2", "pu3", "pv1"] repeat _
writeLine!(fh, var ":=" f1d(x::MultivariatePolynomial(uvbsyms,UnivariatePolynomial('T,ZZ))) ";")
close! fh;
And now the factors of the discriminant polynomial.
fh := open(filename(basedir,"dz", "input"), "output")$TextFile
for x in discfactorssorted for i in 1.. repeat_
writeLine!(fh, "exponent" string(i) ":=" f1d(x.exponent) ";")
for x in discfactorssorted for i in 1.. repeat _
writeLine!(fh, "dz" string(i) ":=" f1d(x.factor) ";")
close! fh;
-------------------------------------------------------------------
--endtest
-------------------------------------------------------------------