Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/generic/divisor_group.py
4095 views
1
"""
2
AUTHORS:
3
4
- David Kohel (2006): Initial version
5
6
- Volker Braun (2010-07-16): Documentation, doctests, coercion fixes, bugfixes.
7
"""
8
9
#*******************************************************************************
10
# Copyright (C) 2010 Volker Braun <[email protected]>
11
# Copyright (C) 2006 David Kohel <[email protected]>
12
# Distributed under the terms of the GNU General Public License (GPL)
13
# http://www.gnu.org/licenses/
14
#*******************************************************************************
15
16
from sage.schemes.generic.divisor import Divisor_generic, Divisor_curve
17
from sage.structure.formal_sum import FormalSums
18
from sage.structure.unique_representation import UniqueRepresentation
19
from sage.rings.integer_ring import ZZ
20
from sage.rings.rational_field import QQ
21
22
23
def DivisorGroup(scheme, base_ring=None):
24
r"""
25
Return the group of divisors on the scheme.
26
27
INPUT:
28
29
- ``scheme`` -- a scheme.
30
31
- ``base_ring`` -- usually either `\ZZ` (default) or `\QQ`. The
32
coefficient ring of the divisors. Not to be confused with the
33
base ring of the scheme!
34
35
OUTPUT:
36
37
An instance of ``DivisorGroup_generic``.
38
39
EXAMPLES::
40
41
sage: from sage.schemes.generic.divisor_group import DivisorGroup
42
sage: DivisorGroup(Spec(ZZ))
43
Group of ZZ-Divisors on Spectrum of Integer Ring
44
sage: DivisorGroup(Spec(ZZ), base_ring=QQ)
45
Group of QQ-Divisors on Spectrum of Integer Ring
46
"""
47
if base_ring==None:
48
base_ring = ZZ
49
50
from sage.schemes.plane_curves.curve import Curve_generic
51
if isinstance(scheme, Curve_generic):
52
DG = DivisorGroup_curve(scheme, base_ring)
53
else:
54
DG = DivisorGroup_generic(scheme, base_ring)
55
56
return DG
57
58
59
def is_DivisorGroup(x):
60
r"""
61
Return whether ``x`` is a :class:`DivisorGroup_generic`.
62
63
INPUT:
64
65
- ``x`` -- anything.
66
67
OUTPUT:
68
69
``True`` or ``False``.
70
71
EXAMPLES::
72
73
sage: from sage.schemes.generic.divisor_group import is_DivisorGroup, DivisorGroup
74
sage: Div = DivisorGroup(Spec(ZZ), base_ring=QQ)
75
sage: is_DivisorGroup(Div)
76
True
77
sage: is_DivisorGroup('not a divisor')
78
False
79
"""
80
return isinstance(x, DivisorGroup_generic)
81
82
83
class DivisorGroup_generic(FormalSums):
84
r"""
85
The divisor group on a variety.
86
"""
87
88
@staticmethod
89
def __classcall__(cls, scheme, base_ring=ZZ):
90
"""
91
Set the default value for the base ring.
92
93
EXAMPLES::
94
95
sage: from sage.schemes.generic.divisor_group import DivisorGroup_generic
96
sage: DivisorGroup_generic(Spec(ZZ),ZZ) == DivisorGroup_generic(Spec(ZZ)) # indirect test
97
True
98
"""
99
# Must not call super().__classcall__()!
100
return UniqueRepresentation.__classcall__(cls, scheme, base_ring)
101
102
def __init__(self, scheme, base_ring):
103
r"""
104
Construct a :class:`DivisorGroup_generic`.
105
106
INPUT:
107
108
- ``scheme`` -- a scheme.
109
110
- ``base_ring`` -- the coefficient ring of the divisor
111
group.
112
113
Implementation note: :meth:`__classcall__` sets default value
114
for ``base_ring``.
115
116
EXAMPLES::
117
118
sage: from sage.schemes.generic.divisor_group import DivisorGroup_generic
119
sage: DivisorGroup_generic(Spec(ZZ), QQ)
120
Group of QQ-Divisors on Spectrum of Integer Ring
121
"""
122
super(DivisorGroup_generic,self).__init__(base_ring)
123
self._scheme = scheme
124
125
def _repr_(self):
126
r"""
127
Return a string representation of the divisor group.
128
129
EXAMPLES::
130
131
sage: from sage.schemes.generic.divisor_group import DivisorGroup
132
sage: DivisorGroup(Spec(ZZ), base_ring=QQ)
133
Group of QQ-Divisors on Spectrum of Integer Ring
134
"""
135
ring = self.base_ring()
136
if ring == ZZ:
137
base_ring_str = 'ZZ'
138
elif ring == QQ:
139
base_ring_str = 'QQ'
140
else:
141
base_ring_str = '('+str(ring)+')'
142
return 'Group of '+base_ring_str+'-Divisors on '+str(self._scheme)
143
144
def _element_constructor_(self, x, check=True, reduce=True):
145
r"""
146
Construct an element of the divisor group.
147
148
EXAMPLES::
149
150
sage: from sage.schemes.generic.divisor_group import DivisorGroup
151
sage: DivZZ=DivisorGroup(Spec(ZZ))
152
sage: DivZZ([(2,5)])
153
2*V(5)
154
"""
155
if isinstance(x, Divisor_generic):
156
P = x.parent()
157
if P is self:
158
return x
159
elif P == self:
160
return Divisor_generic(x._data, check=False, reduce=False, parent=self)
161
else:
162
x = x._data
163
if isinstance(x, list):
164
return Divisor_generic(x, check=check, reduce=reduce, parent=self)
165
if x == 0:
166
return Divisor_generic([], check=False, reduce=False, parent=self)
167
else:
168
return Divisor_generic([(self.base_ring()(1), x)], check=False, reduce=False, parent=self)
169
170
def __cmp__(self, right):
171
r"""
172
Compare the divisor group.
173
174
INPUT:
175
176
- ``right`` -- anything.
177
178
OUTPUT:
179
180
``+1``, ``0``, or ``-1`` depending on how ``self`` and
181
``right`` compare.
182
183
EXAMPLES::
184
185
sage: from sage.schemes.generic.divisor_group import DivisorGroup
186
sage: D1 = DivisorGroup(Spec(ZZ));
187
sage: D2 = DivisorGroup(Spec(ZZ),base_ring=QQ);
188
sage: D3 = DivisorGroup(Spec(QQ));
189
sage: abs(cmp(D1,D1))
190
0
191
sage: abs(cmp(D1,D2))
192
1
193
sage: abs(cmp(D1,D3))
194
1
195
sage: abs(cmp(D2,D2))
196
0
197
sage: abs(cmp(D2,D3))
198
1
199
sage: abs(cmp(D3,D3))
200
0
201
sage: abs(cmp(D1, 'something'))
202
1
203
"""
204
if not is_DivisorGroup(right): return -1
205
c = cmp(self.base_ring(), right.base_ring())
206
if c!=0: return c
207
return cmp(self._scheme, right._scheme)
208
209
def scheme(self):
210
r"""
211
Return the scheme supporting the divisors.
212
213
EXAMPLES::
214
215
sage: from sage.schemes.generic.divisor_group import DivisorGroup
216
sage: Div = DivisorGroup(Spec(ZZ)) # indirect test
217
sage: Div.scheme()
218
Spectrum of Integer Ring
219
"""
220
return self._scheme
221
222
def _an_element_(self):
223
r"""
224
Return an element of the divisor group.
225
226
EXAMPLES::
227
228
sage: A.<x, y> = AffineSpace(2, CC)
229
sage: C = Curve(y^2 - x^9 - x)
230
sage: from sage.schemes.generic.divisor_group import DivisorGroup
231
sage: DivisorGroup(C).an_element() # indirect test
232
0
233
"""
234
return self._scheme.divisor([], base_ring=self.base_ring(), check=False, reduce=False)
235
236
def base_extend(self, R):
237
"""
238
EXAMPLES::
239
240
sage: from sage.schemes.generic.divisor_group import DivisorGroup
241
sage: DivisorGroup(Spec(ZZ),ZZ).base_extend(QQ)
242
Group of QQ-Divisors on Spectrum of Integer Ring
243
sage: DivisorGroup(Spec(ZZ),ZZ).base_extend(GF(7))
244
Group of (Finite Field of size 7)-Divisors on Spectrum of Integer Ring
245
246
Divisor groups are unique::
247
248
sage: A.<x, y> = AffineSpace(2, CC)
249
sage: C = Curve(y^2 - x^9 - x)
250
sage: DivisorGroup(C,ZZ).base_extend(QQ) is DivisorGroup(C,QQ)
251
True
252
"""
253
if self.base_ring().has_coerce_map_from(R):
254
return self
255
elif R.has_coerce_map_from(self.base_ring()):
256
return DivisorGroup(self.scheme(), base_ring=R)
257
258
259
class DivisorGroup_curve(DivisorGroup_generic):
260
r"""
261
Special case of the group of divisors on a curve.
262
"""
263
264
def _element_constructor_(self, x, check=True, reduce=True):
265
r"""
266
Construct an element of the divisor group.
267
268
EXAMPLES::
269
270
sage: A.<x, y> = AffineSpace(2, CC)
271
sage: C = Curve(y^2 - x^9 - x)
272
sage: DivZZ=C.divisor_group(ZZ)
273
sage: DivQQ=C.divisor_group(QQ)
274
sage: DivQQ( DivQQ.an_element() ) # indirect test
275
0
276
sage: DivZZ( DivZZ.an_element() ) # indirect test
277
0
278
sage: DivQQ( DivZZ.an_element() ) # indirect test
279
0
280
"""
281
if isinstance(x, Divisor_curve):
282
P = x.parent()
283
if P is self:
284
return x
285
elif P == self:
286
return Divisor_curve(x._data, check=False, reduce=False, parent=self)
287
else:
288
x = x._data
289
if isinstance(x, list):
290
return Divisor_curve(x, check=check, reduce=reduce, parent=self)
291
if x == 0:
292
return Divisor_curve([], check=False, reduce=False, parent=self)
293
else:
294
return Divisor_curve([(self.base_ring()(1), x)], check=False, reduce=False, parent=self)
295
296
297
298