Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py
8820 views
1
"""
2
Rational point sets on a Jacobian
3
4
EXAMPLES::
5
6
sage: x = QQ['x'].0
7
sage: f = x^5 + x + 1
8
sage: C = HyperellipticCurve(f); C
9
Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
10
sage: C(QQ)
11
Set of rational points of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
12
sage: P = C([0,1,1])
13
sage: J = C.jacobian(); J
14
Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
15
sage: Q = J(QQ)(P); Q
16
(x, y - 1)
17
sage: Q + Q
18
(x^2, y - 1/2*x - 1)
19
sage: Q*3
20
(x^2 - 1/64*x + 1/8, y + 255/512*x + 65/64)
21
22
::
23
24
sage: F.<a> = GF(3)
25
sage: R.<x> = F[]
26
sage: f = x^5-1
27
sage: C = HyperellipticCurve(f)
28
sage: J = C.jacobian()
29
sage: X = J(F)
30
sage: a = x^2-x+1
31
sage: b = -x +1
32
sage: c = x-1
33
sage: d = 0
34
sage: D1 = X([a,b])
35
sage: D1
36
(x^2 + 2*x + 1, y + x + 2)
37
sage: D2 = X([c,d])
38
sage: D2
39
(x + 2, y)
40
sage: D1+D2
41
(x^2 + 2*x + 2, y + 2*x + 1)
42
"""
43
44
#*****************************************************************************
45
# Copyright (C) 2006 David Kohel <[email protected]>
46
# Distributed under the terms of the GNU General Public License (GPL)
47
# http://www.gnu.org/licenses/
48
#*****************************************************************************
49
50
from sage.rings.all import PolynomialRing, Integer, ZZ
51
52
from sage.rings.integer import is_Integer
53
from sage.rings.polynomial.polynomial_element import is_Polynomial
54
55
from sage.schemes.generic.homset import SchemeHomset_points
56
from sage.schemes.generic.morphism import is_SchemeMorphism
57
from sage.schemes.generic.spec import Spec, is_Spec
58
from jacobian_morphism import JacobianMorphism_divisor_class_field
59
60
class JacobianHomset_divisor_classes(SchemeHomset_points):
61
def __init__(self, Y, X, **kwds):
62
R = X.base_ring()
63
S = Y.coordinate_ring()
64
SchemeHomset_points.__init__(self, Y, X, **kwds)
65
P2 = X.curve()._printing_ring
66
if S != R:
67
y = str(P2.gen())
68
x = str(P2.base_ring().gen())
69
P1 = PolynomialRing(S,name=x)
70
P2 = PolynomialRing(P1,name=y)
71
self._printing_ring = P2
72
73
def __call__(self, P):
74
r"""
75
Returns a rational point P in the abstract Homset J(K), given:
76
77
0. A point P in J = Jac(C), returning P; 1. A point P on the curve
78
C such that J = Jac(C), where C is an odd degree model, returning
79
[P - oo]; 2. A pair of points (P, Q) on the curve C such that J =
80
Jac(C), returning [P-Q]; 2. A list of polynomials (a,b) such that
81
`b^2 + h*b - f = 0 mod a`, returning [(a(x),y-b(x))].
82
83
EXAMPLES::
84
85
sage: P.<x> = PolynomialRing(QQ)
86
sage: f = x^5 - x + 1; h = x
87
sage: C = HyperellipticCurve(f,h,'u,v')
88
sage: P = C(0,1,1)
89
sage: J = C.jacobian()
90
sage: Q = J(QQ)(P)
91
sage: for i in range(6): i*Q
92
(1)
93
(u, v - 1)
94
(u^2, v + u - 1)
95
(u^2, v + 1)
96
(u, v + 1)
97
(1)
98
99
::
100
101
sage: F.<a> = GF(3)
102
sage: R.<x> = F[]
103
sage: f = x^5-1
104
sage: C = HyperellipticCurve(f)
105
sage: J = C.jacobian()
106
sage: X = J(F)
107
sage: a = x^2-x+1
108
sage: b = -x +1
109
sage: c = x-1
110
sage: d = 0
111
sage: D1 = X([a,b])
112
sage: D1
113
(x^2 + 2*x + 1, y + x + 2)
114
sage: D2 = X([c,d])
115
sage: D2
116
(x + 2, y)
117
sage: D1+D2
118
(x^2 + 2*x + 2, y + 2*x + 1)
119
120
"""
121
if isinstance(P,(int,long,Integer)) and P == 0:
122
R = PolynomialRing(self.value_ring(), 'x')
123
return JacobianMorphism_divisor_class_field(self, (R(1),R(0)))
124
elif isinstance(P,(list,tuple)):
125
if len(P) == 1 and P[0] == 0:
126
R = PolynomialRing(self.value_ring(), 'x')
127
return JacobianMorphism_divisor_class_field(self, (R(1),R(0)))
128
elif len(P) == 2:
129
P1 = P[0]
130
P2 = P[1]
131
if is_Integer(P1) and is_Integer(P2):
132
R = PolynomialRing(self.value_ring(), 'x')
133
P1 = R(P1)
134
P2 = R(P2)
135
return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
136
if is_Integer(P1) and is_Polynomial(P2):
137
R = PolynomialRing(self.value_ring(), 'x')
138
P1 = R(P1)
139
return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
140
if is_Integer(P2) and is_Polynomial(P1):
141
R = PolynomialRing(self.value_ring(), 'x')
142
P2 = R(P2)
143
return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
144
if is_Polynomial(P1) and is_Polynomial(P2):
145
return JacobianMorphism_divisor_class_field(self, tuple(P))
146
if is_SchemeMorphism(P1) and is_SchemeMorphism(P2):
147
return self(P1) - self(P2)
148
raise TypeError, "Argument P (= %s) must have length 2."%P
149
elif isinstance(P,JacobianMorphism_divisor_class_field) and self == P.parent():
150
return P
151
elif is_SchemeMorphism(P):
152
x0 = P[0]; y0 = P[1]
153
R, x = PolynomialRing(self.value_ring(), 'x').objgen()
154
return self((x-x0,R(y0)))
155
raise TypeError, "Argument P (= %s) does not determine a divisor class"%P
156
157
def _cmp_(self,other):
158
if self.curve() == other.curve():
159
return 0
160
else:
161
return -1
162
163
def _morphism(self, *args, **kwds):
164
return JacobianMorphism_divisor_class_field(*args, **kwds)
165
166
def curve(self):
167
return self.codomain().curve()
168
169
def value_ring(self):
170
"""
171
Returns S for a homset X(T) where T = Spec(S).
172
"""
173
T = self.domain()
174
if is_Spec(T):
175
return T.coordinate_ring()
176
else:
177
raise TypeError, "Domain of argument must be of the form Spec(S)."
178
179
def base_extend(self, R):
180
if R != ZZ:
181
raise NotImplementedError, "Jacobian point sets viewed as modules over rings other than ZZ not implemented"
182
return self
183
184