Skip to content

Commit 8fec3f7

Browse files
committed
establish interface for instantiated classical modular polynomials
1 parent 6ea1fe9 commit 8fec3f7

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

src/doc/en/reference/arithmetic_curves/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Maps between them
2525
sage/schemes/elliptic_curves/hom_scalar
2626
sage/schemes/elliptic_curves/hom_frobenius
2727
sage/schemes/elliptic_curves/isogeny_small_degree
28+
sage/schemes/elliptic_curves/mod_poly
2829

2930

3031
Elliptic curves over number fields

src/sage/schemes/elliptic_curves/all.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,6 @@
4040

4141
from .ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel
4242

43+
from .mod_poly import classical_modular_polynomial
44+
4345
from .heegner import heegner_points, heegner_point
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
r"""
2+
Modular polynomials for elliptic curves
3+
4+
For a positive integer `\ell`, the classical modular polynomial
5+
`\Phi_\ell\in\ZZ[X,Y]` is characterized by the property that its
6+
zero set is exactly the set of pairs of `j`-invariants connected
7+
by a cyclic `\ell`-isogeny.
8+
9+
The functions in this file compute *evaluations* `\Phi_\ell(j,Y)`
10+
of `\Phi_\ell`, univariate polynomials whose roots are exactly
11+
the `j`-invariants of `\ell`-isogeny neighbours of the given `j`.
12+
13+
Currently, the only supported algorithm is a simple database lookup
14+
followed by evaluation. Nevertheless, it makes sense to use the
15+
interface provided by :func:`classical_modular_polynomial` already,
16+
as better algorithms may be implemented and automatically selected
17+
in the future.
18+
19+
AUTHORS:
20+
21+
- Lorenz Panny (2023)
22+
"""
23+
24+
from sage.structure.parent import Parent
25+
from sage.structure.element import parent
26+
from sage.rings.integer_ring import ZZ
27+
from sage.rings.polynomial.polynomial_ring import polygen, polygens
28+
from sage.databases.db_modular_polynomials import ClassicalModularPolynomialDatabase
29+
30+
def classical_modular_polynomial(l, inst=None):
31+
r"""
32+
Return the classical modular polynomial `\Psi_\ell`,
33+
either as a bivariate polynomial over `\ZZ`, a bivariate
34+
polynomial over another ring, or a univariate polynomial
35+
which is the result of evaluating `\Psi_\ell` at a given
36+
`j`-invariant.
37+
38+
INPUT:
39+
40+
- ``l`` -- positive integer.
41+
42+
- ``inst`` -- either ``None``, a ring, or a ring element.
43+
44+
- If ``None`` is given, the original modular polynomial
45+
is returned as an element of `\ZZ[X,Y]`.
46+
47+
- If a ring `R` is given, the base change of the modular
48+
polynomial to `R[X,Y]` is returned.
49+
50+
- If a ring element `j \in R` is given, the evaluation
51+
`\Psi_\ell(j,Y)` is returned as an element of the
52+
univariate polynomial ring `R[Y]`.
53+
54+
The Kohel database
55+
:class:`~sage.databases.db_modular_polynomials.ClassicalModularPolynomialDatabase`
56+
may need to be installed.
57+
58+
EXAMPLES::
59+
60+
sage: classical_modular_polynomial(2)
61+
-X^2*Y^2 + X^3 + 1488*X^2*Y + 1488*X*Y^2 + Y^3 - 162000*X^2 + 40773375*X*Y - 162000*Y^2 + 8748000000*X + 8748000000*Y - 157464000000000
62+
sage: classical_modular_polynomial(3, Zmod(10))
63+
9*X^3*Y^3 + 2*X^3*Y^2 + 2*X^2*Y^3 + X^4 + 4*X^3*Y + 6*X^2*Y^2 + 4*X*Y^3 + Y^4
64+
sage: j = Mod(1728, 419)
65+
sage: classical_modular_polynomial(3, j)
66+
Y^4 + 230*Y^3 + 84*Y^2 + 118*Y + 329
67+
68+
TESTS::
69+
70+
sage: q = random_prime(50)^randrange(1,4)
71+
sage: j = GF(q).random_element()
72+
sage: l = random_prime(50)
73+
sage: Y = polygen(parent(j), 'Y')
74+
sage: classical_modular_polynomial(l,j) == classical_modular_polynomial(l)(j,Y)
75+
True
76+
"""
77+
l = ZZ(l)
78+
79+
db = ClassicalModularPolynomialDatabase()
80+
try:
81+
Psi = db[l]
82+
except ValueError:
83+
raise NotImplementedError('modular polynomial is not in database and computing it on the fly is not yet implemented')
84+
85+
if inst is None:
86+
X,Y = polygen(ZZ, 'X,Y')
87+
elif isinstance(inst, Parent):
88+
R = inst
89+
X,Y = polygen(R, 'X,Y')
90+
else:
91+
j = inst
92+
X,Y = j, polygen(parent(j), 'Y')
93+
94+
return Psi(X, Y)

0 commit comments

Comments
 (0)