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

Adding methods .x() and .y() for EllipticCurvePoint #37092

Merged
merged 2 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/sage/schemes/elliptic_curves/ell_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ def _reduce_point(self, R, p):

sage: E = EllipticCurve([1,-1,0,94,9])
sage: R = E([0,3]) + 5*E([8,31])
sage: factor(R.xy()[0].denominator())
sage: factor(R.x().denominator())
2^2 * 11^2 * 1457253032371^2

Since 11 is a factor of the denominator, this point corresponds to the
Expand Down
64 changes: 55 additions & 9 deletions src/sage/schemes/elliptic_curves/ell_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,11 +773,57 @@ def xy(self):
...
ZeroDivisionError: rational division by zero
"""
if self[2] == 1:
if self[2].is_one():
return self[0], self[1]
else:
return self[0]/self[2], self[1]/self[2]

def x(self):
"""
Return the `x` coordinate of this point, as an element of the base field.
If this is the point at infinity, a :class:`ZeroDivisionError` is raised.

EXAMPLES::

sage: E = EllipticCurve('389a')
sage: P = E([-1,1])
sage: P.x()
-1
sage: Q = E(0); Q
(0 : 1 : 0)
sage: Q.x()
Traceback (most recent call last):
...
ZeroDivisionError: rational division by zero
"""
if self[2].is_one():
return self[0]
else:
return self[0]/self[2]

def y(self):
"""
Return the `y` coordinate of this point, as an element of the base field.
If this is the point at infinity, a :class:`ZeroDivisionError` is raised.

EXAMPLES::

sage: E = EllipticCurve('389a')
sage: P = E([-1,1])
sage: P.y()
1
sage: Q = E(0); Q
(0 : 1 : 0)
sage: Q.y()
Traceback (most recent call last):
...
ZeroDivisionError: rational division by zero
"""
if self[2].is_one():
return self[1]
else:
return self[1]/self[2]

def is_divisible_by(self, m):
"""
Return True if there exists a point `Q` defined over the same
Expand Down Expand Up @@ -1473,7 +1519,7 @@ def _miller_(self, Q, n):
sage: Fx.<b> = GF((2,(4*5)))
sage: Ex = EllipticCurve(Fx, [0,0,1,1,1])
sage: phi = Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0])
sage: Px = Ex(phi(P.xy()[0]), phi(P.xy()[1]))
sage: Px = Ex(phi(P.x()), phi(P.y()))
sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1,
....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b)
sage: Px._miller_(Qx,41) == b^17 + b^13 + b^12 + b^9 + b^8 + b^6 + b^4 + 1
Expand Down Expand Up @@ -1658,7 +1704,7 @@ def weil_pairing(self, Q, n, algorithm=None):
sage: Fx.<b> = GF((2, 4*5))
sage: Ex = EllipticCurve(Fx, [0,0,1,1,1])
sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0])
sage: Px = Ex(phi(P.xy()[0]), phi(P.xy()[1]))
sage: Px = Ex(phi(P.x()), phi(P.y()))
sage: O = Ex(0)
sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1,
....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b)
Expand Down Expand Up @@ -1898,7 +1944,7 @@ def tate_pairing(self, Q, n, k, q=None):
sage: Fx.<b> = GF((2,4*5))
sage: Ex = EllipticCurve(Fx,[0,0,1,1,1])
sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0])
sage: Px = Ex(phi(P.xy()[0]), phi(P.xy()[1]))
sage: Px = Ex(phi(P.x()), phi(P.y()))
sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1,
....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b)
sage: Px.tate_pairing(Qx, n=41, k=4)
Expand Down Expand Up @@ -2070,7 +2116,7 @@ def ate_pairing(self, Q, n, k, t, q=None):
sage: Fx.<b> = GF(q^k)
sage: Ex = EllipticCurve(Fx, [0,0,1,1,1])
sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0])
sage: Px = Ex(phi(P.xy()[0]), phi(P.xy()[1]))
sage: Px = Ex(phi(P.x()), phi(P.y()))
sage: Qx = Ex(b^19+b^18+b^16+b^12+b^10+b^9+b^8+b^5+b^3+1,
....: b^18+b^13+b^10+b^8+b^5+b^4+b^3+b)
sage: Qx = Ex(Qx[0]^q, Qx[1]^q) - Qx # ensure Qx is in ker(pi - q)
Expand Down Expand Up @@ -3862,14 +3908,14 @@ def padic_elliptic_logarithm(self,Q, p):
for k in range(0,p):
Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + k * p for t in E.a_invariants() ])

P_Qps = Eqp.lift_x(ZZ(self.xy()[0]), all=True)
P_Qps = Eqp.lift_x(ZZ(self.x()), all=True)
for P_Qp in P_Qps:
if F(P_Qp.xy()[1]) == self.xy()[1]:
if F(P_Qp.y()) == self.y():
break

Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True)
Q_Qps = Eqp.lift_x(ZZ(Q.x()), all=True)
for Q_Qp in Q_Qps:
if F(Q_Qp.xy()[1]) == Q.xy()[1]:
if F(Q_Qp.y()) == Q.y():
break

pP = p * P_Qp
Expand Down
2 changes: 1 addition & 1 deletion src/sage/schemes/elliptic_curves/height.py
Original file line number Diff line number Diff line change
Expand Up @@ -1177,7 +1177,7 @@ def psi(self, xi, v):
3.51086196882538
sage: L(P) / L.real_period()
0.867385122699931
sage: xP = v(P.xy()[0])
sage: xP = v(P.x())
sage: H = E.height_function()
sage: H.psi(xP, v)
0.867385122699931
Expand Down
2 changes: 1 addition & 1 deletion src/sage/schemes/elliptic_curves/hom_sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def to_isogeny_chain(self):
from sage.groups.generic import multiples
from sage.misc.misc_c import prod
x = polygen(Kl.base_ring())
poly = prod(x - T.xy()[0] for T in multiples(Kl, l//2, Kl))
poly = prod(x - T.x() for T in multiples(Kl, l//2, Kl))
poly = poly.change_ring(self.base_ring())

psi = phi.codomain().isogeny(poly)
Expand Down
26 changes: 13 additions & 13 deletions src/sage/schemes/elliptic_curves/hom_velusqrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ class FastEllipticPolynomial:
Fast elliptic polynomial prod(Z - x(i*P) for i in range(1,n,2)) with n = 19, P = (4 : 35 : 1)
sage: hP(7)
19
sage: prod(7 - (i*P).xy()[0] for i in range(1,P.order(),2))
sage: prod(7 - (i*P).x() for i in range(1,P.order(),2))
19

Passing `Q` changes the index set::
Expand All @@ -269,7 +269,7 @@ class FastEllipticPolynomial:
sage: hPQ = FastEllipticPolynomial(E, P.order(), P, Q)
sage: hPQ(7)
58
sage: prod(7 - (Q+i*P).xy()[0] for i in range(P.order()))
sage: prod(7 - (Q+i*P).x() for i in range(P.order()))
58

The call syntax has an optional keyword argument ``derivative``, which
Expand All @@ -279,7 +279,7 @@ class FastEllipticPolynomial:
sage: hP(7, derivative=True)
(19, 15)
sage: R.<Z> = E.base_field()[]
sage: HP = prod(Z - (i*P).xy()[0] for i in range(1,P.order(),2))
sage: HP = prod(Z - (i*P).x() for i in range(1,P.order(),2))
sage: HP
Z^9 + 16*Z^8 + 57*Z^7 + 6*Z^6 + 45*Z^5 + 31*Z^4 + 46*Z^3 + 10*Z^2 + 28*Z + 41
sage: HP(7)
Expand All @@ -292,7 +292,7 @@ class FastEllipticPolynomial:
sage: hPQ(7, derivative=True)
(58, 62)
sage: R.<Z> = E.base_field()[]
sage: HPQ = prod(Z - (Q+i*P).xy()[0] for i in range(P.order()))
sage: HPQ = prod(Z - (Q+i*P).x() for i in range(P.order()))
sage: HPQ
Z^19 + 53*Z^18 + 67*Z^17 + 39*Z^16 + 56*Z^15 + 32*Z^14 + 44*Z^13 + 6*Z^12 + 27*Z^11 + 29*Z^10 + 38*Z^9 + 48*Z^8 + 38*Z^7 + 43*Z^6 + 21*Z^5 + 25*Z^4 + 33*Z^3 + 49*Z^2 + 60*Z
sage: HPQ(7)
Expand Down Expand Up @@ -342,9 +342,9 @@ def __init__(self, E, n, P, Q=None):
)

I, J, K = IJK
xI = (R.xy()[0] for R in _points_range(I, P, Q))
xJ = [R.xy()[0] for R in _points_range(J, P )]
xK = (R.xy()[0] for R in _points_range(K, P, Q))
xI = (R.x() for R in _points_range(I, P, Q))
xJ = [R.x() for R in _points_range(J, P )]
xK = (R.x() for R in _points_range(K, P, Q))

self.hItree = ProductTree(Z - xi for xi in xI)

Expand Down Expand Up @@ -766,7 +766,7 @@ def _raw_eval(self, x, y=None):
sage: phi._raw_codomain
Elliptic Curve defined by y^2 = x^3 + ... over Finite Field of size 65537
sage: Q = E(42, 15860)
sage: phi._raw_eval(Q.xy()[0])
sage: phi._raw_eval(Q.x())
11958
sage: phi._raw_eval(*Q.xy())
(11958, 42770)
Expand Down Expand Up @@ -794,8 +794,8 @@ def _raw_eval(self, x, y=None):
h0, h0d = self._h0(x, derivative=True)
h1, h1d = self._h1(x, derivative=True)

# assert h0 == prod(x - ( i*self._P).xy()[0] for i in range(1,self._P.order(),2))
# assert h1 == prod(x - (self._Q+i*self._P).xy()[0] for i in range( self._P.order() ))
# assert h0 == prod(x - ( i*self._P).x() for i in range(1,self._P.order(),2))
# assert h1 == prod(x - (self._Q+i*self._P).x() for i in range( self._P.order() ))

if not h0:
return ()
Expand All @@ -805,8 +805,8 @@ def _raw_eval(self, x, y=None):
if y is None:
return xx

# assert h0d == sum(prod(x - ( i*self._P).xy()[0] for i in range(1,self._P.order(),2) if i!=j) for j in range(1,self._P.order(),2))
# assert h1d == sum(prod(x - (self._Q+i*self._P).xy()[0] for i in range( self._P.order() ) if i!=j) for j in range( self._P.order() ))
# assert h0d == sum(prod(x - ( i*self._P).x() for i in range(1,self._P.order(),2) if i!=j) for j in range(1,self._P.order(),2))
# assert h1d == sum(prod(x - (self._Q+i*self._P).x() for i in range( self._P.order() ) if i!=j) for j in range( self._P.order() ))

yy = y * (h1d - 2 * h1 / h0 * h0d) / h0**2

Expand Down Expand Up @@ -1026,7 +1026,7 @@ def kernel_polynomial(self):
x^15 + 21562*x^14 + 8571*x^13 + 20029*x^12 + 1775*x^11 + 60402*x^10 + 17481*x^9 + 46543*x^8 + 46519*x^7 + 18590*x^6 + 36554*x^5 + 36499*x^4 + 48857*x^3 + 3066*x^2 + 23264*x + 53937
sage: h == E.isogeny(K).kernel_polynomial()
True
sage: h(K.xy()[0])
sage: h(K.x())
0

TESTS::
Expand Down
Loading