Isomorphisms between Weierstrass models of elliptic curves#
AUTHORS:
Robert Bradshaw (2007): initial version
John Cremona (Jan 2008): isomorphisms, automorphisms and twists in all characteristics
Lorenz Panny (2021):
EllipticCurveHominterface
- class sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism(E=None, urst=None, F=None)#
Bases:
EllipticCurveHom,baseWIClass representing a Weierstrass isomorphism between two elliptic curves.
INPUT:
E– anEllipticCurve, orNone(see below).urst– a 4-tuple \((u,r,s,t)\), abaseWIobject, orNone(see below).F– anEllipticCurve, orNone(see below).
Given two Elliptic Curves
EandF(represented by Weierstrass models as usual), and a transformationurstfromEtoF, construct an isomorphism fromEtoF. An exception is raised ifurst(E) != F. At most one ofE,F,urstcan beNone. In this case, the missing input is constructed from the others in such a way thaturst(E) == Fholds, and an exception is raised if this is impossible (typically becauseEandFare not isomorphic).Users will not usually need to use this class directly, but instead use methods such as
isomorphism_to()orisomorphisms().Explicitly, the isomorphism defined by \((u,r,s,t)\) maps a point \((x,y)\) to the point
\[((x-r) / u^2, \; (y - s(x-r) - t) / u^3) .\]If the domain \(E\) has Weierstrass coefficients \([a_1,a_2,a_3,a_4,a_6]\), the codomain \(F\) is given by
\[\begin{split}a_1' &= (a_1 + 2s) / u \\ a_2' &= (a_2 - a_1s + 3r - s^2) / u^2 \\ a_3' &= (a_3 + a_1r + 2t) / u^3 \\ a_4' &= (a_4 + 2a_2r - a_1(rs+t) - a_3s + 3r^2 - 2st) / u^4 \\ a_6' &= (a_6 - a_1rt + a_2r^2 - a_3t + a_4r + r^3 - t^2) / u^6 .\end{split}\]EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import * sage: WeierstrassIsomorphism(EllipticCurve([0,1,2,3,4]), (-1,2,3,4)) Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field To: Elliptic Curve defined by y^2 - 6*x*y - 10*y = x^3 - 2*x^2 - 11*x - 2 over Rational Field Via: (u,r,s,t) = (-1, 2, 3, 4) sage: E = EllipticCurve([0,1,2,3,4]) sage: F = EllipticCurve(E.cremona_label()) sage: WeierstrassIsomorphism(E, None, F) Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field To: Elliptic Curve defined by y^2 = x^3 + x^2 + 3*x + 5 over Rational Field Via: (u,r,s,t) = (1, 0, 0, -1) sage: w = WeierstrassIsomorphism(None, (1,0,0,-1), F) sage: w._domain == E True
- dual()#
Return the dual isogeny of this isomorphism.
For isomorphisms, the dual is just the inverse.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism sage: E = EllipticCurve(QuadraticField(-3), [0,1]) # needs sage.rings.number_field sage: w = WeierstrassIsomorphism(E, (CyclotomicField(3).gen(),0,0,0)) # needs sage.rings.number_field sage: (w.dual() * w).rational_maps() # needs sage.rings.number_field (x, y)
sage: E1 = EllipticCurve([11,22,33,44,55]) sage: E2 = E1.short_weierstrass_model() sage: iso = E1.isomorphism_to(E2) sage: iso.dual() == ~iso True
- inseparable_degree()#
Return the inseparable degree of this Weierstrass isomorphism.
For isomorphisms, this method always returns one.
- is_identity()#
Check if this Weierstrass isomorphism is the identity.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism sage: p = 97 sage: Fp = GF(p) sage: E = EllipticCurve(Fp, [1, 28]) sage: ws = WeierstrassIsomorphism(E, None, E) sage: ws.is_identity() False
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism sage: p = 97 sage: Fp = GF(p) sage: E = EllipticCurve(Fp, [1, 28]) sage: ws = WeierstrassIsomorphism(E, (1, 0, 0, 0), None) sage: ws.is_identity() True
- kernel_polynomial()#
Return the kernel polynomial of this isomorphism.
Isomorphisms have trivial kernel by definition, hence this method always returns \(1\).
EXAMPLES:
sage: E1 = EllipticCurve([11,22,33,44,55]) sage: E2 = EllipticCurve_from_j(E1.j_invariant()) sage: iso = E1.isomorphism_to(E2) sage: iso.kernel_polynomial() 1 sage: psi = E1.isogeny(iso.kernel_polynomial(), codomain=E2); psi Isogeny of degree 1 from Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 over Rational Field sage: psi in {iso, -iso} True
- order()#
Compute the order of this Weierstrass isomorphism if it is an automorphism.
A
ValueErroris raised if the domain is not equal to the codomain.A
NotImplementedErroris raised if the order of the automorphism is not 1, 2, 3, 4 or 6.EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import * sage: p = 97 sage: Fp = GF(p) sage: E = EllipticCurve(Fp, [1, 28]) sage: ws = WeierstrassIsomorphism(E, None, E) sage: ws.order() 2
- rational_maps()#
Return the pair of rational maps defining this isomorphism.
EXAMPLES:
sage: E1 = EllipticCurve([11,22,33,44,55]) sage: E2 = EllipticCurve_from_j(E1.j_invariant()) sage: iso = E1.isomorphism_to(E2); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 over Rational Field To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 over Rational Field Via: (u,r,s,t) = (1, -17, -5, 77) sage: iso.rational_maps() (x + 17, 5*x + y + 8) sage: f = E2.defining_polynomial()(*iso.rational_maps(), 1) sage: I = E1.defining_ideal() sage: x,y,z = I.ring().gens() sage: f in I + Ideal(z-1) True
sage: # needs sage.rings.finite_rings sage: E = EllipticCurve(GF(65537), [1,1,1,1,1]) sage: w = E.isomorphism_to(E.short_weierstrass_model()) sage: f,g = w.rational_maps() sage: P = E.random_point() sage: w(P).xy() == (f(P.xy()), g(P.xy())) True
- scaling_factor()#
Return the Weierstrass scaling factor associated to this Weierstrass isomorphism.
The scaling factor is the constant \(u\) (in the base field) such that \(\varphi^* \omega_2 = u \omega_1\), where \(\varphi: E_1\to E_2\) is this isomorphism and \(\omega_i\) are the standard Weierstrass differentials on \(E_i\) defined by \(\mathrm dx/(2y+a_1x+a_3)\).
EXAMPLES:
sage: E = EllipticCurve(QQbar, [0,1]) # needs sage.rings.number_field sage: all(f.scaling_factor() == f.formal()[1] for f in E.automorphisms()) # needs sage.rings.number_field True
ALGORITHM: The scaling factor equals the \(u\) component of the tuple \((u,r,s,t)\) defining the isomorphism.
- x_rational_map()#
Return the \(x\)-coordinate rational map of this isomorphism.
EXAMPLES:
sage: E1 = EllipticCurve([11,22,33,44,55]) sage: E2 = EllipticCurve_from_j(E1.j_invariant()) sage: iso = E1.isomorphism_to(E2); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55 over Rational Field To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681 over Rational Field Via: (u,r,s,t) = (1, -17, -5, 77) sage: iso.x_rational_map() x + 17 sage: iso.x_rational_map() == iso.rational_maps()[0] True
- class sage.schemes.elliptic_curves.weierstrass_morphism.baseWI(u=1, r=0, s=0, t=0)#
Bases:
objectThis class implements the basic arithmetic of isomorphisms between Weierstrass models of elliptic curves.
These are specified by lists of the form \([u,r,s,t]\) (with \(u \neq 0\)) which specifies a transformation \((x,y) \mapsto (x',y')\) where
\((x,y) = (u^2x'+r , u^3y' + su^2x' + t).\)
INPUT:
u,r,s,t(default \((1,0,0,0)\)) – standard parameters of an isomorphism between Weierstrass models.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import * sage: baseWI() (1, 0, 0, 0) sage: baseWI(2,3,4,5) (2, 3, 4, 5) sage: R.<u,r,s,t> = QQ[] sage: baseWI(u,r,s,t) (u, r, s, t)
- is_identity()#
Return
Trueif this is the identity isomorphism.EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import * sage: w = baseWI(); w.is_identity() True sage: w = baseWI(2,3,4,5); w.is_identity() False
- tuple()#
Return the parameters \(u,r,s,t\) as a tuple.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import * sage: w = baseWI(2,3,4,5) sage: w.tuple() (2, 3, 4, 5)
- sage.schemes.elliptic_curves.weierstrass_morphism.identity_morphism(E)#
Given an elliptic curve \(E\), return the identity morphism on \(E\) as a
WeierstrassIsomorphism.EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism sage: E = EllipticCurve([5,6,7,8,9]) sage: id_ = identity_morphism(E) sage: id_.rational_maps() (x, y)
- sage.schemes.elliptic_curves.weierstrass_morphism.negation_morphism(E)#
Given an elliptic curve \(E\), return the negation endomorphism \([-1]\) of \(E\) as a
WeierstrassIsomorphism.EXAMPLES:
sage: from sage.schemes.elliptic_curves.weierstrass_morphism import negation_morphism sage: E = EllipticCurve([5,6,7,8,9]) sage: neg = negation_morphism(E) sage: neg.rational_maps() (x, -5*x - y - 7)