Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/hyperelliptic_curves/jacobian_homset.py
4159 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 is_Polynomial, PolynomialRing, Integer, is_Integer, ZZ
51
from sage.schemes.generic.homset import SchemeHomset_points
52
from sage.schemes.generic.morphism import is_SchemeMorphism
53
from sage.schemes.generic.spec import Spec, is_Spec
54
from jacobian_morphism import JacobianMorphism_divisor_class_field
55
56
class JacobianHomset_divisor_classes(SchemeHomset_points):
57
def __init__(self, Y, X, **kwds):
58
R = X.base_ring()
59
S = Y.coordinate_ring()
60
SchemeHomset_points.__init__(self, Y, X, **kwds)
61
P2 = X.curve()._printing_ring
62
if S != R:
63
y = str(P2.gen())
64
x = str(P2.base_ring().gen())
65
P1 = PolynomialRing(S,name=x)
66
P2 = PolynomialRing(P1,name=y)
67
self._printing_ring = P2
68
69
def __call__(self, P):
70
r"""
71
Returns a rational point P in the abstract Homset J(K), given:
72
73
0. A point P in J = Jac(C), returning P; 1. A point P on the curve
74
C such that J = Jac(C), where C is an odd degree model, returning
75
[P - oo]; 2. A pair of points (P, Q) on the curve C such that J =
76
Jac(C), returning [P-Q]; 2. A list of polynomials (a,b) such that
77
`b^2 + h*b - f = 0 mod a`, returning [(a(x),y-b(x))].
78
79
EXAMPLES::
80
81
sage: P.<x> = PolynomialRing(QQ)
82
sage: f = x^5 - x + 1; h = x
83
sage: C = HyperellipticCurve(f,h,'u,v')
84
sage: P = C(0,1,1)
85
sage: J = C.jacobian()
86
sage: Q = J(QQ)(P)
87
sage: for i in range(6): i*Q
88
(1)
89
(u, v - 1)
90
(u^2, v + u - 1)
91
(u^2, v + 1)
92
(u, v + 1)
93
(1)
94
95
::
96
97
sage: F.<a> = GF(3)
98
sage: R.<x> = F[]
99
sage: f = x^5-1
100
sage: C = HyperellipticCurve(f)
101
sage: J = C.jacobian()
102
sage: X = J(F)
103
sage: a = x^2-x+1
104
sage: b = -x +1
105
sage: c = x-1
106
sage: d = 0
107
sage: D1 = X([a,b])
108
sage: D1
109
(x^2 + 2*x + 1, y + x + 2)
110
sage: D2 = X([c,d])
111
sage: D2
112
(x + 2, y)
113
sage: D1+D2
114
(x^2 + 2*x + 2, y + 2*x + 1)
115
116
"""
117
if isinstance(P,(int,long,Integer)) and P == 0:
118
R = PolynomialRing(self.value_ring(), 'x')
119
return JacobianMorphism_divisor_class_field(self, (R(1),R(0)))
120
elif isinstance(P,(list,tuple)):
121
if len(P) == 1 and P[0] == 0:
122
R = PolynomialRing(self.value_ring(), 'x')
123
return JacobianMorphism_divisor_class_field(self, (R(1),R(0)))
124
elif len(P) == 2:
125
P1 = P[0]
126
P2 = P[1]
127
if is_Integer(P1) and is_Integer(P2):
128
R = PolynomialRing(self.value_ring(), 'x')
129
P1 = R(P1)
130
P2 = R(P2)
131
return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
132
if is_Integer(P1) and is_Polynomial(P2):
133
R = PolynomialRing(self.value_ring(), 'x')
134
P1 = R(P1)
135
return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
136
if is_Integer(P2) and is_Polynomial(P1):
137
R = PolynomialRing(self.value_ring(), 'x')
138
P2 = R(P2)
139
return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
140
if is_Polynomial(P1) and is_Polynomial(P2):
141
return JacobianMorphism_divisor_class_field(self, tuple(P))
142
if is_SchemeMorphism(P1) and is_SchemeMorphism(P2):
143
return self(P1) - self(P2)
144
raise TypeError, "Argument P (= %s) must have length 2."%P
145
elif isinstance(P,JacobianMorphism_divisor_class_field) and self == P.parent():
146
return P
147
elif is_SchemeMorphism(P):
148
x0 = P[0]; y0 = P[1]
149
R, x = PolynomialRing(self.value_ring(), 'x').objgen()
150
return self((x-x0,R(y0)))
151
raise TypeError, "Argument P (= %s) does not determine a divisor class"%P
152
153
def _cmp_(self,other):
154
if self.curve() == other.curve():
155
return 0
156
else:
157
return -1
158
159
def _morphism(self, *args, **kwds):
160
return JacobianMorphism_divisor_class_field(*args, **kwds)
161
162
def curve(self):
163
return self.codomain().curve()
164
165
def value_ring(self):
166
"""
167
Returns S for a homset X(T) where T = Spec(S).
168
"""
169
T = self.domain()
170
if is_Spec(T):
171
return T.coordinate_ring()
172
else:
173
raise TypeError, "Domain of argument must be of the form Spec(S)."
174
175
def base_extend(self, R):
176
if R != ZZ:
177
raise NotImplementedError, "Jacobian point sets viewed as modules over rings other than ZZ not implemented"
178
return self
179
180