Skip to content

Commit

Permalink
establish interface for instantiated classical modular polynomials
Browse files Browse the repository at this point in the history
  • Loading branch information
yyyyx4 committed Sep 4, 2023
1 parent 6ea1fe9 commit 3054650
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/doc/en/reference/arithmetic_curves/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Maps between them
sage/schemes/elliptic_curves/hom_scalar
sage/schemes/elliptic_curves/hom_frobenius
sage/schemes/elliptic_curves/isogeny_small_degree
sage/schemes/elliptic_curves/mod_poly


Elliptic curves over number fields
Expand Down
2 changes: 2 additions & 0 deletions src/sage/schemes/elliptic_curves/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@

from .ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel

from .mod_poly import classical_modular_polynomial

from .heegner import heegner_points, heegner_point
94 changes: 94 additions & 0 deletions src/sage/schemes/elliptic_curves/mod_poly.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
r"""
Modular polynomials for elliptic curves
For a positive integer `\ell`, the classical modular polynomial
`\Phi_\ell\in\ZZ[X,Y]` is characterized by the property that its
zero set is exactly the set of pairs of `j`-invariants connected
by a cyclic `\ell`-isogeny.
The functions in this file compute *evaluations* `\Phi_\ell(j,Y)`
of `\Phi_\ell`, univariate polynomials whose roots are exactly
the `j`-invariants of `\ell`-isogeny neighbours of the given `j`.
Currently, the only supported algorithm is a simple database lookup
followed by evaluation. Nevertheless, it makes sense to use the
interface provided by :func:`classical_modular_polynomial` already,
as better algorithms may be implemented and automatically selected
in the future.
AUTHORS:
- Lorenz Panny (2023)
"""

from sage.structure.parent import Parent
from sage.structure.element import parent
from sage.rings.integer_ring import ZZ
from sage.rings.polynomial.polynomial_ring import polygen, polygens
from sage.databases.db_modular_polynomials import ClassicalModularPolynomialDatabase

def classical_modular_polynomial(l, inst=None):
r"""
Return the classical modular polynomial `\Phi_\ell`,
either as a bivariate polynomial over `\ZZ`, a bivariate
polynomial over another ring, or a univariate polynomial
which is the result of evaluating `\Phi_\ell` at a given
`j`-invariant.
INPUT:
- ``l`` -- positive integer.
- ``inst`` -- either ``None``, a ring, or a ring element.
- If ``None`` is given, the original modular polynomial
is returned as an element of `\ZZ[X,Y]`.
- If a ring `R` is given, the base change of the modular
polynomial to `R[X,Y]` is returned.
- If a ring element `j \in R` is given, the evaluation
`\Phi_\ell(j,Y)` is returned as an element of the
univariate polynomial ring `R[Y]`.
The Kohel database
:class:`~sage.databases.db_modular_polynomials.ClassicalModularPolynomialDatabase`
may need to be installed.
EXAMPLES::
sage: classical_modular_polynomial(2)
-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
sage: classical_modular_polynomial(3, Zmod(10))
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
sage: j = Mod(1728, 419)
sage: classical_modular_polynomial(3, j)
Y^4 + 230*Y^3 + 84*Y^2 + 118*Y + 329
TESTS::
sage: q = random_prime(50)^randrange(1,4)
sage: j = GF(q).random_element()
sage: l = random_prime(50)
sage: Y = polygen(parent(j), 'Y')
sage: classical_modular_polynomial(l,j) == classical_modular_polynomial(l)(j,Y)
True
"""
l = ZZ(l)

db = ClassicalModularPolynomialDatabase()
try:
Phi = db[l]
except ValueError:
raise NotImplementedError('modular polynomial is not in database and computing it on the fly is not yet implemented')

if inst is None:
X,Y = polygen(ZZ, 'X,Y')
elif isinstance(inst, Parent):
R = inst
X,Y = polygen(R, 'X,Y')
else:
j = inst
X,Y = j, polygen(parent(j), 'Y')

return Phi(X, Y)

0 comments on commit 3054650

Please sign in to comment.