Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a specialized parent object for elliptic-curve morphisms #36972

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/sage/schemes/elliptic_curves/ell_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,24 @@ def division_field(self, n, names='t', map=False, **kwds):
L = L, F_to_K.post_compose(K_to_L)
return L

def _Hom_(*args, **kwds):
r"""
Hook to make :class:`~sage.categories.homset.Hom`
set the correct parent
:class:`~sage.schemes.elliptic_curves.homset.EllipticCurveHomset`
for
:class:`~sage.schemes.elliptic_curves.hom.EllipticCurveHom`
objects.

EXAMPLES::

sage: E = EllipticCurve(GF(19), [1,0])
sage: type(E._Hom_(E))
<class 'sage.schemes.elliptic_curves.homset.EllipticCurveHomset_with_category'>
"""
from . import homset
return homset.EllipticCurveHomset(*args, **kwds)

def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, algorithm=None):
r"""
Return an elliptic-curve isogeny from this elliptic curve.
Expand Down
151 changes: 151 additions & 0 deletions src/sage/schemes/elliptic_curves/homset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
r"""
Homsets and endomorphism rings of elliptic curves

The set of homomorphisms between two elliptic curves (:class:`EllipticCurveHom`)
forms an abelian group under addition. Moreover, if the two curves are the same,
it even forms a (not always commutative) ring under composition.

This module encapsulates the set of homomorphisms between two given elliptic
curves as a Sage object.

.. NOTE::

Currently only little nontrivial functionality is available, but this will
hopefully change in the future.

EXAMPLES:

The only useful thing this class does at the moment is coercing integers into
the endomorphism ring as scalar multiplications::

sage: E = EllipticCurve([1,2,3,4,5])
sage: f = End(E)(7); f
Scalar-multiplication endomorphism [7] of Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
sage: f == E.scalar_multiplication(7)
True

::

sage: E = EllipticCurve(GF(431^2), [0,1])
sage: E.automorphisms()[0] == 1
True
sage: E.automorphisms()[1] == -1
True
sage: omega = E.automorphisms()[2]
sage: omega == 1
False
sage: omega^3 == 1
True
sage: (1 + omega + omega^2) == 0
True
sage: (2*omega + 1)^2 == -3
True

AUTHORS:

- Lorenz Panny (2023)
"""

# ****************************************************************************
# Copyright (C) 2023 Lorenz Panny
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# https://www.gnu.org/licenses/
# ****************************************************************************

from sage.rings.integer_ring import ZZ
from sage.categories.morphism import Morphism
from sage.schemes.generic.homset import SchemeHomset_generic


class EllipticCurveHomset(SchemeHomset_generic):
r"""
This class represents the set of all homomorphisms between two fixed
elliptic curves.

EXAMPLES::

sage: E = EllipticCurve(GF(419^2), [1,0])
sage: E.frobenius_isogeny() in End(E)
True
sage: phi = E.isogenies_prime_degree(7)[0]
sage: phi in End(E)
False
sage: phi in Hom(E, phi.codomain())
True

Note that domain and codomain are *not* taken up to isomorphism::

sage: iso = E.isomorphism_to(EllipticCurve(GF(419^2), [2,0]))
sage: iso in End(E)
False
"""
def __init__(self, *args, **kwds):
r"""
Construct the homset for a given pair of curves.

TESTS::

sage: E = EllipticCurve('37a1') # needs sage.schemes
sage: Hom(E, E).__class__ # needs sage.schemes
<class 'sage.schemes.elliptic_curves.homset.EllipticCurveHomset_with_category'>

::

sage: E1 = EllipticCurve(j=42)
sage: E2 = EllipticCurve(j=43)
sage: Hom(E1, E2)
Group of elliptic-curve morphisms
From: Elliptic Curve defined by y^2 = x^3 + 5901*x + 1105454 over Rational Field
To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 1510*x - 140675 over Rational Field
"""
super().__init__(*args, **kwds)

if self.domain() == self.codomain():

# set up automated coercion of integers to scalar multiplications
from sage.schemes.elliptic_curves.hom_scalar import EllipticCurveHom_scalar

class ScalarMultiplicationEmbedding(Morphism):

def __init__(self, End):
assert End.domain() is End.codomain()
super().__init__(ZZ, End)

def _call_(self, m):
return EllipticCurveHom_scalar(self.codomain().domain(), m)

self.register_coercion(ScalarMultiplicationEmbedding(self))

def _repr_(self):
r"""
Output a description of this homset, with special formatting
for endomorphism rings.

EXAMPLES::

sage: E1 = EllipticCurve([1,1])
sage: E2 = EllipticCurve([2,2])
sage: End(E1)
Ring of elliptic-curve endomorphisms
From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
To: Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
sage: Hom(E1, E1)
Ring of elliptic-curve endomorphisms
From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
To: Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
sage: Hom(E1, E2)
Group of elliptic-curve morphisms
From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
To: Elliptic Curve defined by y^2 = x^3 + 2*x + 2 over Rational Field
"""
if self.domain() == self.codomain():
s = 'Ring of elliptic-curve endomorphisms'
else:
s = 'Group of elliptic-curve morphisms'
s += f'\n From: {self.domain()}'
s += f'\n To: {self.codomain()}'
return s
4 changes: 0 additions & 4 deletions src/sage/schemes/generic/scheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,10 +645,6 @@ def _Hom_(self, Y, category=None, check=True):
sage: S._Hom_(P).__class__
<class 'sage.schemes.generic.homset.SchemeHomset_generic_with_category'>

sage: E = EllipticCurve('37a1') # needs sage.schemes
sage: Hom(E, E).__class__ # needs sage.schemes
<class 'sage.schemes.projective.projective_homset.SchemeHomset_polynomial_projective_space_with_category'>

sage: Hom(Spec(ZZ), Spec(ZZ)).__class__
<class 'sage.schemes.generic.homset.SchemeHomset_generic_with_category_with_equality_by_id'>
"""
Expand Down