Fractional morphisms of elliptic curves¶
Algorithms involving advanced computations with endomorphisms or isogenies of elliptic curves sometimes involve divisions of elliptic-curve morphisms by integers. This operation yields another well-defined morphism whenever the kernel of the numerator contains the kernel of the denominator.
The class EllipticCurveHom_fractional
represents symbolic
fractions EllipticCurveHom
whose
kernel contains the to_isogeny_chain()
).
EXAMPLES:
Division by an integer:
sage: E = EllipticCurve(GF(419), [-1, 0])
sage: phi = (E.frobenius_isogeny() + 1) / 2
sage: phi
Fractional elliptic-curve morphism of degree 105:
Numerator: Sum morphism:
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
Via: (Frobenius endomorphism of degree 419:
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419,
Scalar-multiplication endomorphism [1]
of Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419)
Denominator: 2
sage: phi.degree()
105
sage: phi.to_isogeny_chain()
Composite morphism of degree 105 = 1*3*5*7:
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [-Integer(1), Integer(0)])
>>> phi = (E.frobenius_isogeny() + Integer(1)) / Integer(2)
>>> phi
Fractional elliptic-curve morphism of degree 105:
Numerator: Sum morphism:
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
Via: (Frobenius endomorphism of degree 419:
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419,
Scalar-multiplication endomorphism [1]
of Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419)
Denominator: 2
>>> phi.degree()
105
>>> phi.to_isogeny_chain()
Composite morphism of degree 105 = 1*3*5*7:
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
E = EllipticCurve(GF(419), [-1, 0]) phi = (E.frobenius_isogeny() + 1) / 2 phi phi.degree() phi.to_isogeny_chain()
Right division of isogenies:
sage: E = EllipticCurve(GF(419), [1, 0])
sage: ker = E(125, 70)
sage: phi = E.isogeny(ker); phi
Isogeny of degree 35
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
sage: psi = E.isogeny(5*ker); psi
Isogeny of degree 7
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
to Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
sage: chi = phi.divide_right(psi); chi
Fractional elliptic-curve morphism of degree 5:
Numerator: Composite morphism of degree 245 = 7*35:
From: Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
Denominator: 7
sage: phi == chi * psi
True
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [Integer(1), Integer(0)])
>>> ker = E(Integer(125), Integer(70))
>>> phi = E.isogeny(ker); phi
Isogeny of degree 35
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
>>> psi = E.isogeny(Integer(5)*ker); psi
Isogeny of degree 7
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
to Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
>>> chi = phi.divide_right(psi); chi
Fractional elliptic-curve morphism of degree 5:
Numerator: Composite morphism of degree 245 = 7*35:
From: Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
Denominator: 7
>>> phi == chi * psi
True
E = EllipticCurve(GF(419), [1, 0]) ker = E(125, 70) phi = E.isogeny(ker); phi psi = E.isogeny(5*ker); psi chi = phi.divide_right(psi); chi phi == chi * psi
Left division of isogenies:
sage: E = EllipticCurve(GF(419), [1, 0])
sage: ker = E(125, 70)
sage: phi = E.isogeny(ker); phi
Isogeny of degree 35
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
sage: tmp = E.isogeny(7*ker)
sage: psi = tmp.codomain().isogeny(tmp(ker)); psi
Isogeny of degree 7
from Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
sage: chi = phi.divide_left(psi); chi
Fractional elliptic-curve morphism of degree 5:
Numerator: Composite morphism of degree 245 = 35*7:
From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
Denominator: 7
sage: phi == psi * chi
True
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [Integer(1), Integer(0)])
>>> ker = E(Integer(125), Integer(70))
>>> phi = E.isogeny(ker); phi
Isogeny of degree 35
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
>>> tmp = E.isogeny(Integer(7)*ker)
>>> psi = tmp.codomain().isogeny(tmp(ker)); psi
Isogeny of degree 7
from Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
>>> chi = phi.divide_left(psi); chi
Fractional elliptic-curve morphism of degree 5:
Numerator: Composite morphism of degree 245 = 35*7:
From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
To: Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
Denominator: 7
>>> phi == psi * chi
True
E = EllipticCurve(GF(419), [1, 0]) ker = E(125, 70) phi = E.isogeny(ker); phi tmp = E.isogeny(7*ker) psi = tmp.codomain().isogeny(tmp(ker)); psi chi = phi.divide_left(psi); chi phi == psi * chi
AUTHORS:
Lorenz Panny (2024)
- class sage.schemes.elliptic_curves.hom_fractional.EllipticCurveHom_fractional(phi, d, *, check=True)[source]¶
Bases:
EllipticCurveHom
This class represents a (symbolic) quotient of an isogeny divided by an integer.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.hom_fractional import EllipticCurveHom_fractional sage: phi = EllipticCurve([1,1]).scalar_multiplication(-2) sage: EllipticCurveHom_fractional(phi, 2) Fractional elliptic-curve morphism of degree 1: Numerator: Scalar-multiplication endomorphism [-2] of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field Denominator: 2 sage: EllipticCurveHom_fractional(phi, 3) Traceback (most recent call last): ... ValueError: Scalar-multiplication endomorphism [-2] of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field is not divisible by 3
>>> from sage.all import * >>> from sage.schemes.elliptic_curves.hom_fractional import EllipticCurveHom_fractional >>> phi = EllipticCurve([Integer(1),Integer(1)]).scalar_multiplication(-Integer(2)) >>> EllipticCurveHom_fractional(phi, Integer(2)) Fractional elliptic-curve morphism of degree 1: Numerator: Scalar-multiplication endomorphism [-2] of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field Denominator: 2 >>> EllipticCurveHom_fractional(phi, Integer(3)) Traceback (most recent call last): ... ValueError: Scalar-multiplication endomorphism [-2] of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field is not divisible by 3
from sage.schemes.elliptic_curves.hom_fractional import EllipticCurveHom_fractional phi = EllipticCurve([1,1]).scalar_multiplication(-2) EllipticCurveHom_fractional(phi, 2) EllipticCurveHom_fractional(phi, 3)
- dual()[source]¶
Return the dual of this fractional isogeny.
EXAMPLES:
sage: E = EllipticCurve(GF(419), [1,0]) sage: phi = E.isogeny(E(185, 73)) sage: ((phi + phi) / 2).dual() == phi.dual() True
>>> from sage.all import * >>> E = EllipticCurve(GF(Integer(419)), [Integer(1),Integer(0)]) >>> phi = E.isogeny(E(Integer(185), Integer(73))) >>> ((phi + phi) / Integer(2)).dual() == phi.dual() True
E = EllipticCurve(GF(419), [1,0]) phi = E.isogeny(E(185, 73)) ((phi + phi) / 2).dual() == phi.dual()
- formal(*args)[source]¶
Return the formal isogeny corresponding to this fractional isogeny as a power series in the variable
on the domain curve.EXAMPLES:
sage: E = EllipticCurve(GF(419), [-1,0]) sage: pi = E.frobenius_isogeny() sage: ((1 + pi) / 2).formal() 210*t + 26*t^5 + 254*t^9 + 227*t^13 + 36*t^17 + 74*t^21 + O(t^23)
>>> from sage.all import * >>> E = EllipticCurve(GF(Integer(419)), [-Integer(1),Integer(0)]) >>> pi = E.frobenius_isogeny() >>> ((Integer(1) + pi) / Integer(2)).formal() 210*t + 26*t^5 + 254*t^9 + 227*t^13 + 36*t^17 + 74*t^21 + O(t^23)
E = EllipticCurve(GF(419), [-1,0]) pi = E.frobenius_isogeny() ((1 + pi) / 2).formal()
- inseparable_degree()[source]¶
Return the inseparable degree of this morphism.
EXAMPLES:
sage: E = EllipticCurve(GF(419), [-1,0]) sage: pi = E.frobenius_isogeny() sage: ((1 + pi) / 2).inseparable_degree() 1 sage: E = EllipticCurve(GF(419), [-1,0]) sage: pi = E.frobenius_isogeny() sage: ((3*pi - pi) / 2).inseparable_degree() 419
>>> from sage.all import * >>> E = EllipticCurve(GF(Integer(419)), [-Integer(1),Integer(0)]) >>> pi = E.frobenius_isogeny() >>> ((Integer(1) + pi) / Integer(2)).inseparable_degree() 1 >>> E = EllipticCurve(GF(Integer(419)), [-Integer(1),Integer(0)]) >>> pi = E.frobenius_isogeny() >>> ((Integer(3)*pi - pi) / Integer(2)).inseparable_degree() 419
E = EllipticCurve(GF(419), [-1,0]) pi = E.frobenius_isogeny() ((1 + pi) / 2).inseparable_degree() E = EllipticCurve(GF(419), [-1,0]) pi = E.frobenius_isogeny() ((3*pi - pi) / 2).inseparable_degree()
- kernel_polynomial()[source]¶
Return the kernel polynomial of this fractional isogeny.
EXAMPLES:
sage: E = EllipticCurve(GF(419), [1,0]) sage: phi = E.isogeny(E(185, 73)); phi.kernel_polynomial() x^2 + 304*x + 39 sage: ((phi + phi) / 2).kernel_polynomial() x^2 + 304*x + 39
>>> from sage.all import * >>> E = EllipticCurve(GF(Integer(419)), [Integer(1),Integer(0)]) >>> phi = E.isogeny(E(Integer(185), Integer(73))); phi.kernel_polynomial() x^2 + 304*x + 39 >>> ((phi + phi) / Integer(2)).kernel_polynomial() x^2 + 304*x + 39
E = EllipticCurve(GF(419), [1,0]) phi = E.isogeny(E(185, 73)); phi.kernel_polynomial() ((phi + phi) / 2).kernel_polynomial()
- rational_maps()[source]¶
Return the pair of explicit rational maps defining this fractional isogeny.
EXAMPLES:
sage: E = EllipticCurve(GF(419), [1,0]) sage: phi = E.isogeny(E(185, 73)); phi.rational_maps() ((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155), (x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179)) sage: ((phi + phi) / 2).rational_maps() ((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155), (x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179))
>>> from sage.all import * >>> E = EllipticCurve(GF(Integer(419)), [Integer(1),Integer(0)]) >>> phi = E.isogeny(E(Integer(185), Integer(73))); phi.rational_maps() ((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155), (x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179)) >>> ((phi + phi) / Integer(2)).rational_maps() ((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155), (x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179))
E = EllipticCurve(GF(419), [1,0]) phi = E.isogeny(E(185, 73)); phi.rational_maps() ((phi + phi) / 2).rational_maps()
- scaling_factor()[source]¶
Return the Weierstrass scaling factor associated to this fractional isogeny.
The scaling factor is the constant
(in the base field) such that , where is this morphism and are the standard Weierstrass differentials on defined by .EXAMPLES:
sage: E = EllipticCurve(GF(419), [-1,0]) sage: pi = E.frobenius_isogeny() sage: ((1 + pi) / 2).scaling_factor() 210
>>> from sage.all import * >>> E = EllipticCurve(GF(Integer(419)), [-Integer(1),Integer(0)]) >>> pi = E.frobenius_isogeny() >>> ((Integer(1) + pi) / Integer(2)).scaling_factor() 210
E = EllipticCurve(GF(419), [-1,0]) pi = E.frobenius_isogeny() ((1 + pi) / 2).scaling_factor()
- to_isogeny_chain()[source]¶
Convert this fractional elliptic-curve morphism into a (non-fractional)
EllipticCurveHom_composite
object representing the same morphism.EXAMPLES:
sage: p = 419 sage: E = EllipticCurve(GF(p^2), [1,0]) sage: iota = E.automorphisms()[2] # sqrt(-1) sage: pi = E.frobenius_isogeny() # sqrt(-p) sage: endo = (iota + pi) / 2 sage: endo.degree() 105 sage: endo.to_isogeny_chain() Composite morphism of degree 105 = 1*3*5*7: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2 To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2 sage: endo.to_isogeny_chain() == endo True
>>> from sage.all import * >>> p = Integer(419) >>> E = EllipticCurve(GF(p**Integer(2)), [Integer(1),Integer(0)]) >>> iota = E.automorphisms()[Integer(2)] # sqrt(-1) >>> pi = E.frobenius_isogeny() # sqrt(-p) >>> endo = (iota + pi) / Integer(2) >>> endo.degree() 105 >>> endo.to_isogeny_chain() Composite morphism of degree 105 = 1*3*5*7: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2 To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2 >>> endo.to_isogeny_chain() == endo True
p = 419 E = EllipticCurve(GF(p^2), [1,0]) iota = E.automorphisms()[2] # sqrt(-1) pi = E.frobenius_isogeny() # sqrt(-p) endo = (iota + pi) / 2 endo.degree() endo.to_isogeny_chain() endo.to_isogeny_chain() == endo
- x_rational_map()[source]¶
Return the
-coordinate rational map of this fractional isogeny.EXAMPLES:
sage: E = EllipticCurve(GF(419), [1,0]) sage: phi = E.isogeny(E(185, 73)); phi.x_rational_map() (x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264) sage: ((phi + phi) / 2).x_rational_map() (x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264)
>>> from sage.all import * >>> E = EllipticCurve(GF(Integer(419)), [Integer(1),Integer(0)]) >>> phi = E.isogeny(E(Integer(185), Integer(73))); phi.x_rational_map() (x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264) >>> ((phi + phi) / Integer(2)).x_rational_map() (x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264)
E = EllipticCurve(GF(419), [1,0]) phi = E.isogeny(E(185, 73)); phi.x_rational_map() ((phi + phi) / 2).x_rational_map()