Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

""" 

Rational point sets on a Jacobian 

 

EXAMPLES:: 

 

sage: x = QQ['x'].0 

sage: f = x^5 + x + 1 

sage: C = HyperellipticCurve(f); C 

Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1 

sage: C(QQ) 

Set of rational points of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1 

sage: P = C([0,1,1]) 

sage: J = C.jacobian(); J 

Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1 

sage: Q = J(QQ)(P); Q 

(x, y - 1) 

sage: Q + Q 

(x^2, y - 1/2*x - 1) 

sage: Q*3 

(x^2 - 1/64*x + 1/8, y + 255/512*x + 65/64) 

 

:: 

 

sage: F.<a> = GF(3) 

sage: R.<x> = F[] 

sage: f = x^5-1 

sage: C = HyperellipticCurve(f) 

sage: J = C.jacobian() 

sage: X = J(F) 

sage: a = x^2-x+1 

sage: b = -x +1 

sage: c = x-1 

sage: d = 0 

sage: D1 = X([a,b]) 

sage: D1 

(x^2 + 2*x + 1, y + x + 2) 

sage: D2 = X([c,d]) 

sage: D2 

(x + 2, y) 

sage: D1+D2 

(x^2 + 2*x + 2, y + 2*x + 1) 

""" 

#***************************************************************************** 

# Copyright (C) 2006 David Kohel <kohel@maths.usyd.edu> 

# Distributed under the terms of the GNU General Public License (GPL) 

# http://www.gnu.org/licenses/ 

#***************************************************************************** 

from __future__ import absolute_import 

from six import integer_types 

 

from sage.rings.all import PolynomialRing, Integer, ZZ 

 

from sage.rings.integer import is_Integer 

from sage.rings.polynomial.polynomial_element import is_Polynomial 

 

from sage.schemes.generic.homset import SchemeHomset_points 

from sage.schemes.generic.morphism import is_SchemeMorphism 

from .jacobian_morphism import JacobianMorphism_divisor_class_field 

 

class JacobianHomset_divisor_classes(SchemeHomset_points): 

def __init__(self, Y, X, **kwds): 

R = X.base_ring() 

S = Y.coordinate_ring() 

SchemeHomset_points.__init__(self, Y, X, **kwds) 

P2 = X.curve()._printing_ring 

if S != R: 

y = str(P2.gen()) 

x = str(P2.base_ring().gen()) 

P1 = PolynomialRing(S,name=x) 

P2 = PolynomialRing(P1,name=y) 

self._printing_ring = P2 

 

def __call__(self, P): 

r""" 

Returns a rational point P in the abstract Homset J(K), given: 

 

0. A point P in J = Jac(C), returning P; 1. A point P on the curve 

C such that J = Jac(C), where C is an odd degree model, returning 

[P - oo]; 2. A pair of points (P, Q) on the curve C such that J = 

Jac(C), returning [P-Q]; 2. A list of polynomials (a,b) such that 

`b^2 + h*b - f = 0 mod a`, returning [(a(x),y-b(x))]. 

 

EXAMPLES:: 

 

sage: P.<x> = PolynomialRing(QQ) 

sage: f = x^5 - x + 1; h = x 

sage: C = HyperellipticCurve(f,h,'u,v') 

sage: P = C(0,1,1) 

sage: J = C.jacobian() 

sage: Q = J(QQ)(P) 

sage: for i in range(6): i*Q 

(1) 

(u, v - 1) 

(u^2, v + u - 1) 

(u^2, v + 1) 

(u, v + 1) 

(1) 

 

:: 

 

sage: F.<a> = GF(3) 

sage: R.<x> = F[] 

sage: f = x^5-1 

sage: C = HyperellipticCurve(f) 

sage: J = C.jacobian() 

sage: X = J(F) 

sage: a = x^2-x+1 

sage: b = -x +1 

sage: c = x-1 

sage: d = 0 

sage: D1 = X([a,b]) 

sage: D1 

(x^2 + 2*x + 1, y + x + 2) 

sage: D2 = X([c,d]) 

sage: D2 

(x + 2, y) 

sage: D1+D2 

(x^2 + 2*x + 2, y + 2*x + 1) 

 

""" 

if isinstance(P, integer_types + (Integer,)) and P == 0: 

R = PolynomialRing(self.value_ring(), 'x') 

return JacobianMorphism_divisor_class_field(self, (R(1),R(0))) 

elif isinstance(P,(list,tuple)): 

if len(P) == 1 and P[0] == 0: 

R = PolynomialRing(self.value_ring(), 'x') 

return JacobianMorphism_divisor_class_field(self, (R(1),R(0))) 

elif len(P) == 2: 

P1 = P[0] 

P2 = P[1] 

if is_Integer(P1) and is_Integer(P2): 

R = PolynomialRing(self.value_ring(), 'x') 

P1 = R(P1) 

P2 = R(P2) 

return JacobianMorphism_divisor_class_field(self, tuple([P1,P2])) 

if is_Integer(P1) and is_Polynomial(P2): 

R = PolynomialRing(self.value_ring(), 'x') 

P1 = R(P1) 

return JacobianMorphism_divisor_class_field(self, tuple([P1,P2])) 

if is_Integer(P2) and is_Polynomial(P1): 

R = PolynomialRing(self.value_ring(), 'x') 

P2 = R(P2) 

return JacobianMorphism_divisor_class_field(self, tuple([P1,P2])) 

if is_Polynomial(P1) and is_Polynomial(P2): 

return JacobianMorphism_divisor_class_field(self, tuple(P)) 

if is_SchemeMorphism(P1) and is_SchemeMorphism(P2): 

return self(P1) - self(P2) 

raise TypeError("Argument P (= %s) must have length 2."%P) 

elif isinstance(P,JacobianMorphism_divisor_class_field) and self == P.parent(): 

return P 

elif is_SchemeMorphism(P): 

x0 = P[0]; y0 = P[1] 

R, x = PolynomialRing(self.value_ring(), 'x').objgen() 

return self((x-x0,R(y0))) 

raise TypeError("Argument P (= %s) does not determine a divisor class"%P) 

 

def _cmp_(self,other): 

if self.curve() == other.curve(): 

return 0 

else: 

return -1 

 

def _morphism(self, *args, **kwds): 

return JacobianMorphism_divisor_class_field(*args, **kwds) 

 

def curve(self): 

return self.codomain().curve() 

 

def value_ring(self): 

""" 

Returns S for a homset X(T) where T = Spec(S). 

""" 

from sage.schemes.generic.scheme import is_AffineScheme 

T = self.domain() 

if is_AffineScheme(T): 

return T.coordinate_ring() 

else: 

raise TypeError("Domain of argument must be of the form Spec(S).") 

 

def base_extend(self, R): 

if R != ZZ: 

raise NotImplementedError("Jacobian point sets viewed as modules over rings other than ZZ not implemented") 

return self