Skip to content

Commit 2b9f3e0

Browse files
author
Release Manager
committed
gh-36637: sums of elliptic-curve morphisms Here we add a new `EllipticCurveHom` child class representing formal sums of elliptic-curve morphisms with the same domain and codomain. One of the main features is a conversion function from formal sums to a more explicit representation of the same morphism as an isogeny chain, which will come in handy for endomorphism-ring-related computations. In the process, we also generalize `point_of_order()` from primes to prime powers. There is certainly a lot of potential for optimizations; some ideas are mentioned in the code. Since I think it's fair to say that this version is already much better than what we currently have for sums of isogenies (i.e., nothing), I'd suggest merging this as is and dealing with bottlenecks later as they arise. Cc: @JohnCremona @defeo @GiacomoPope @remyoudompheng URL: #36637 Reported by: Lorenz Panny Reviewer(s): John Cremona, Lorenz Panny
2 parents 3a9254d + fbe441e commit 2b9f3e0

File tree

11 files changed

+1009
-229
lines changed

11 files changed

+1009
-229
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ Maps between them
1818
:maxdepth: 1
1919

2020
sage/schemes/elliptic_curves/hom
21+
sage/schemes/elliptic_curves/hom_composite
22+
sage/schemes/elliptic_curves/hom_sum
2123
sage/schemes/elliptic_curves/weierstrass_morphism
2224
sage/schemes/elliptic_curves/ell_curve_isogeny
2325
sage/schemes/elliptic_curves/hom_velusqrt
24-
sage/schemes/elliptic_curves/hom_composite
2526
sage/schemes/elliptic_curves/hom_scalar
2627
sage/schemes/elliptic_curves/hom_frobenius
2728
sage/schemes/elliptic_curves/isogeny_small_degree

src/sage/schemes/elliptic_curves/ell_curve_isogeny.py

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2879,28 +2879,19 @@ def kernel_polynomial(self):
28792879
self.__init_kernel_polynomial()
28802880
return self.__kernel_polynomial
28812881

2882-
def is_separable(self):
2882+
def inseparable_degree(self):
28832883
r"""
2884-
Determine whether or not this isogeny is separable.
2884+
Return the inseparable degree of this isogeny.
28852885
2886-
Since :class:`EllipticCurveIsogeny` only implements
2887-
separable isogenies, this method always returns ``True``.
2886+
Since this class only implements separable isogenies,
2887+
this method always returns one.
28882888
2889-
EXAMPLES::
2890-
2891-
sage: E = EllipticCurve(GF(17), [0,0,0,3,0])
2892-
sage: phi = EllipticCurveIsogeny(E, E((0,0)))
2893-
sage: phi.is_separable()
2894-
True
2895-
2896-
::
2889+
TESTS::
28972890
2898-
sage: E = EllipticCurve('11a1')
2899-
sage: phi = EllipticCurveIsogeny(E, E.torsion_points())
2900-
sage: phi.is_separable()
2901-
True
2891+
sage: EllipticCurveIsogeny.inseparable_degree(None)
2892+
1
29022893
"""
2903-
return True
2894+
return Integer(1)
29042895

29052896
def _set_pre_isomorphism(self, preWI):
29062897
"""

src/sage/schemes/elliptic_curves/ell_field.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2082,13 +2082,13 @@ def compute_model(E, name):
20822082

20832083
raise NotImplementedError(f'cannot compute {name} model')
20842084

2085-
def point_of_order(E, l):
2085+
def point_of_order(E, n):
20862086
r"""
20872087
Given an elliptic curve `E` over a finite field or a number field
2088-
and an integer `\ell \geq 1`, construct a point of order `\ell` on `E`,
2088+
and an integer `n \geq 1`, construct a point of order `n` on `E`,
20892089
possibly defined over an extension of the base field of `E`.
20902090
2091-
Currently only prime values of `\ell` are supported.
2091+
Currently only prime powers `n` are supported.
20922092
20932093
EXAMPLES::
20942094
@@ -2103,6 +2103,13 @@ def point_of_order(E, l):
21032103
sage: P.curve().a_invariants()
21042104
(1, 2, 3, 4, 5)
21052105
2106+
::
2107+
2108+
sage: Q = point_of_order(E, 8); Q
2109+
(69*x^5 + 24*x^4 + 100*x^3 + 65*x^2 + 88*x + 97 : 65*x^5 + 28*x^4 + 5*x^3 + 45*x^2 + 42*x + 18 : 1)
2110+
sage: 8*Q == 0 and 4*Q != 0
2111+
True
2112+
21062113
::
21072114
21082115
sage: from sage.schemes.elliptic_curves.ell_field import point_of_order
@@ -2111,10 +2118,23 @@ def point_of_order(E, l):
21112118
(x : -Y : 1)
21122119
sage: P.base_ring()
21132120
Number Field in Y with defining polynomial Y^2 - x^3 - 7*x - 7 over its base field
2121+
sage: P.base_ring().base_field()
2122+
Number Field in x with defining polynomial x^4 + 14*x^2 + 28*x - 49/3
21142123
sage: P.order()
21152124
3
21162125
sage: P.curve().a_invariants()
21172126
(0, 0, 0, 7, 7)
2127+
2128+
::
2129+
2130+
sage: Q = point_of_order(E, 4); Q # random
2131+
(x : Y : 1)
2132+
sage: Q.base_ring()
2133+
Number Field in Y with defining polynomial Y^2 - x^3 - 7*x - 7 over its base field
2134+
sage: Q.base_ring().base_field()
2135+
Number Field in x with defining polynomial x^6 + 35*x^4 + 140*x^3 - 245*x^2 - 196*x - 735
2136+
sage: Q.order()
2137+
4
21182138
"""
21192139
# Construct the field extension defined by the given polynomial,
21202140
# in such a way that the result is recognized by Sage as a field.
@@ -2127,14 +2147,16 @@ def ffext(poly):
21272147
return poly.splitting_field(rng.variable_name())
21282148
return fld.extension(poly, rng.variable_name())
21292149

2130-
l = ZZ(l)
2131-
if l == 1:
2150+
n = ZZ(n)
2151+
if n == 1:
21322152
return E(0)
21332153

2134-
if not l.is_prime():
2135-
raise NotImplementedError('composite orders are currently unsupported')
2154+
l,m = n.is_prime_power(get_data=True)
2155+
if not m:
2156+
raise NotImplementedError('only prime-power orders are currently supported')
21362157

2137-
xpoly = E.division_polynomial(l)
2158+
xpoly = E.division_polynomial(n).radical()
2159+
xpoly //= E.division_polynomial(n//l).radical()
21382160
if xpoly.degree() < 1: # supersingular and l == p
21392161
raise ValueError('curve does not have any points of the specified order')
21402162

@@ -2149,4 +2171,6 @@ def ffext(poly):
21492171
xx = FF(xx)
21502172

21512173
EE = E.change_ring(FF)
2152-
return EE.lift_x(xx)
2174+
pt = EE.lift_x(xx)
2175+
pt.set_order(n, check=False)
2176+
return pt

src/sage/schemes/elliptic_curves/ell_point.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,9 +1359,10 @@ def set_order(self, value=None, *, multiple=None, check=True):
13591359
raise ValueError('Value %s illegal for point order' % value)
13601360
E = self.curve()
13611361
q = E.base_ring().cardinality()
1362-
low, hi = Hasse_bounds(q)
1363-
if value > hi:
1364-
raise ValueError('Value %s illegal: outside max Hasse bound' % value)
1362+
if q < oo:
1363+
_, hi = Hasse_bounds(q)
1364+
if value > hi:
1365+
raise ValueError('Value %s illegal: outside max Hasse bound' % value)
13651366
if value * self != E(0):
13661367
raise ValueError('Value %s illegal: %s * %s is not the identity' % (value, value, self))
13671368
if hasattr(self, '_order') and self._order != value: # already known

0 commit comments

Comments
 (0)