Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 47ccfd5

Browse files
committed
#18589 isogeny improvement
1 parent f9ab830 commit 47ccfd5

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

src/sage/schemes/elliptic_curves/isogeny_small_degree.py

+35-2
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,13 @@ def isogenies_prime_degree_general(E, l):
19071907
[Isogeny of degree 43 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43]
19081908
[Isogeny of degree 47 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47]
19091909
1910+
See :trac:`18589`: the following example took 20s before, now only 4s::
1911+
1912+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
1913+
sage: K.<i> = QuadraticField(-1)
1914+
sage: E = EllipticCurve(K,[0,0,0,1,0])
1915+
sage: [phi.codomain().ainvs() for phi in E.isogenies_prime_degree(37)] # long time
1916+
[(0, 0, 0, -840*i + 1081, 0), (0, 0, 0, 840*i + 1081, 0)]
19101917
"""
19111918
if not l.is_prime():
19121919
raise ValueError("%s is not prime."%l)
@@ -1916,7 +1923,33 @@ def isogenies_prime_degree_general(E, l):
19161923
return isogenies_3(E)
19171924

19181925
psi_l = E.division_polynomial(l)
1919-
factors = [h for h,e in psi_l.factor() if (l-1)/2 % h.degree() == 0]
1926+
1927+
# Every kernel polynomial is a product of irreducible factors of
1928+
# the division polynomial of the same degree, where this degree is
1929+
# a divisor of (l-1)/2, so we keep only such factors:
1930+
1931+
factors = [h for h,e in psi_l.factor() if (l-1)//2 % h.degree() == 0]
1932+
1933+
# Special case 1: if there is just one relevant irreducible factor,
1934+
# then it must have degree (l-1)/2, and it must be a kernel poly;
1935+
# then we do not need to check, which saves a lot of time.
1936+
1937+
if len(factors)==1:
1938+
h = factors[0]
1939+
return [E.isogeny(h)]
1940+
1941+
# Special case 2: more than one relevant irreducible factor, but
1942+
# their degrees add up to (l-1)/2. Then their product is a kernel
1943+
# poly.
1944+
1945+
from sage.misc.all import prod
1946+
if sum([h.degree() for h in factors]) == (l-1)//2:
1947+
h = prod(factors)
1948+
return [E.isogeny(h)]
1949+
1950+
# General case: look for products of factors which can be kernel
1951+
# polynomials:
1952+
19201953
a = _least_semi_primitive(l)
19211954
m = E.multiplication_by_m(a, x_only=True)
19221955
F = psi_l.parent()
@@ -1936,7 +1969,7 @@ def mult(f):
19361969
S.append(g)
19371970
if g in factors:
19381971
factors.remove(g)
1939-
if mult(S[-1]) == f:
1972+
if len(S)==1 or (mult(S[-1]) == f):
19401973
ker.append(prod(S))
19411974
return [E.isogeny(k) for k in ker]
19421975

0 commit comments

Comments
 (0)