Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/toric/divisor_class.pyx
4107 views
1
r"""
2
Toric rational divisor classes
3
4
This module is a part of the framework for :mod:`toric varieties
5
<sage.schemes.toric.variety>`.
6
7
AUTHORS:
8
9
- Volker Braun and Andrey Novoseltsev (2010-09-05): initial version.
10
11
TESTS:
12
13
Toric rational divisor clases are elements of the rational class group of a
14
toric variety, represented as rational vectors in some basis::
15
16
sage: dP6 = toric_varieties.dP6()
17
sage: Cl = dP6.rational_class_group()
18
sage: D = Cl([1, -2, 3, -4])
19
sage: D
20
Divisor class [1, -2, 3, -4]
21
sage: E = Cl([1/2, -2/3, 3/4, -4/5])
22
sage: E
23
Divisor class [1/2, -2/3, 3/4, -4/5]
24
25
They behave much like ordinary vectors::
26
27
sage: D + E
28
Divisor class [3/2, -8/3, 15/4, -24/5]
29
sage: 2 * D
30
Divisor class [2, -4, 6, -8]
31
sage: E / 10
32
Divisor class [1/20, -1/15, 3/40, -2/25]
33
sage: D * E
34
Traceback (most recent call last):
35
...
36
TypeError: cannot multiply two divisor classes!
37
38
The only special method is :meth:`~ToricRationalDivisorClass.lift` to get a
39
divisor representing a divisor class::
40
41
sage: D.lift()
42
V(x) - 2*V(u) + 3*V(y) - 4*V(v)
43
sage: E.lift()
44
1/2*V(x) - 2/3*V(u) + 3/4*V(y) - 4/5*V(v)
45
"""
46
47
48
#*****************************************************************************
49
# Copyright (C) 2010 Volker Braun <[email protected]>
50
# Copyright (C) 2010 Andrey Novoseltsev <[email protected]>
51
# Copyright (C) 2010 William Stein <[email protected]>
52
#
53
# Distributed under the terms of the GNU General Public License (GPL)
54
#
55
# http://www.gnu.org/licenses/
56
#*****************************************************************************
57
58
59
include '../../ext/cdefs.pxi' # Needed for mpq* stuff
60
include '../../ext/stdsage.pxi' # Needed for PY_NEW
61
62
from sage.misc.all import latex
63
from sage.modules.all import vector
64
from sage.modules.vector_rational_dense cimport Vector_rational_dense
65
from sage.rings.all import QQ
66
from sage.rings.rational cimport Rational
67
from sage.structure.element cimport Element, Vector
68
from sage.structure.element import is_Vector
69
70
71
def is_ToricRationalDivisorClass(x):
72
r"""
73
Check if ``x`` is a toric rational divisor class.
74
75
INPUT:
76
77
- ``x`` -- anything.
78
79
OUTPUT:
80
81
- ``True`` if ``x`` is a toric rational divisor class, ``False`` otherwise.
82
83
EXAMPLES::
84
85
sage: from sage.schemes.toric.divisor_class import (
86
... is_ToricRationalDivisorClass)
87
sage: is_ToricRationalDivisorClass(1)
88
False
89
sage: dP6 = toric_varieties.dP6()
90
sage: D = dP6.rational_class_group().gen(0)
91
sage: D
92
Divisor class [1, 0, 0, 0]
93
sage: is_ToricRationalDivisorClass(D)
94
True
95
"""
96
return isinstance(x, ToricRationalDivisorClass)
97
98
99
cdef class ToricRationalDivisorClass(Vector_rational_dense):
100
r"""
101
Create a toric rational divisor class.
102
103
.. WARNING::
104
105
You probably should not construct divisor classes explicitly.
106
107
INPUT:
108
109
- same as for
110
:class:`~sage.modules.vector_rational_dense.Vector_rational_dense`.
111
112
OUTPUT:
113
114
- toric rational divisor class.
115
116
TESTS::
117
118
sage: dP6 = toric_varieties.dP6()
119
sage: Cl = dP6.rational_class_group()
120
sage: D = dP6.divisor(2)
121
sage: Cl(D)
122
Divisor class [0, 0, 1, 0]
123
"""
124
125
def __reduce__(self):
126
"""
127
Prepare ``self`` for pickling.
128
129
TESTS::
130
131
sage: dP6 = toric_varieties.dP6()
132
sage: Cl = dP6.rational_class_group()
133
sage: D = Cl([1, -2, 3, -4])
134
sage: D
135
Divisor class [1, -2, 3, -4]
136
sage: loads(dumps(D))
137
Divisor class [1, -2, 3, -4]
138
"""
139
return (_ToricRationalDivisorClass_unpickle_v1,
140
(self._parent, list(self), self._degree, self._is_mutable))
141
142
cdef _new_c(self):
143
cdef ToricRationalDivisorClass y
144
y = PY_NEW(ToricRationalDivisorClass)
145
y._init(self._degree, self._parent)
146
return y
147
148
cpdef _act_on_(self, other, bint self_on_left):
149
"""
150
Act on ``other``.
151
152
INPUT:
153
154
- ``other`` - something that
155
:class:`~sage.modules.vector_rational_dense.Vector_rational_dense`
156
can act on *except* for another toric rational divisor class.
157
158
OUTPUT:
159
160
- standard output for ``self`` acting as a rational vector on
161
``other`` if the latter one is not a toric rational divisor class.
162
163
TESTS::
164
165
sage: dP6 = toric_varieties.dP6()
166
sage: Cl = dP6.rational_class_group()
167
sage: D = Cl([1, -2, 3, -4])
168
sage: D
169
Divisor class [1, -2, 3, -4]
170
sage: D * D
171
Traceback (most recent call last):
172
...
173
TypeError: cannot multiply two divisor classes!
174
175
We test standard behaviour::
176
177
sage: v = vector([1, 2, 3, 4])
178
sage: v * D # indirect doctest
179
-10
180
sage: D * v # indirect doctest
181
-10
182
sage: v = vector([1, 2/3, 4/5, 6/7])
183
sage: v * D # indirect doctest
184
-143/105
185
sage: D * v # indirect doctest
186
-143/105
187
sage: A = matrix(4, range(16))
188
sage: A * D # indirect doctest
189
(-8, -16, -24, -32)
190
sage: D * A # indirect doctest
191
(-32, -34, -36, -38)
192
sage: B = A / 3
193
sage: B * D # indirect doctest
194
(-8/3, -16/3, -8, -32/3)
195
sage: D * B # indirect doctest
196
(-32/3, -34/3, -12, -38/3)
197
"""
198
# If we don't treat vectors separately, they get converted into
199
# divisor classes where multiplication is prohibited on purpose.
200
if isinstance(other, Vector_rational_dense):
201
return Vector_rational_dense._dot_product_(self, other)
202
cdef Vector v
203
if is_Vector(other) and not is_ToricRationalDivisorClass(other):
204
try:
205
v = vector(QQ, other)
206
if v._degree == self._degree:
207
return Vector_rational_dense._dot_product_(self, v)
208
except TypeError:
209
pass
210
# Now let the standard framework work...
211
return Vector_rational_dense._act_on_(self, other, self_on_left)
212
213
cpdef Element _dot_product_(self, Vector right):
214
r"""
215
Raise a ``TypeError`` exception.
216
217
Dot product is not defined on toric rational divisor classes.
218
219
INPUT:
220
221
- ``right`` - vector.
222
223
OUTPUT:
224
225
- ``TypeError`` exception is raised.
226
227
TESTS::
228
229
sage: c = toric_varieties.dP8().rational_class_group().gens()
230
sage: c[0]._dot_product_(c[1])
231
Traceback (most recent call last):
232
...
233
TypeError: cannot multiply two divisor classes!
234
sage: c[0] * c[1] # indirect doctest
235
Traceback (most recent call last):
236
...
237
TypeError: cannot multiply two divisor classes!
238
"""
239
raise TypeError("cannot multiply two divisor classes!")
240
241
def _latex_(self):
242
r"""
243
Return a LaTeX representation of ``self``.
244
245
OUTPUT:
246
247
- string.
248
249
TESTS::
250
251
sage: D = toric_varieties.dP6().divisor(0).divisor_class()
252
sage: D._latex_()
253
'\\left[ 1, 0, 0, 0 \\right]_{\\mathop{Cl}_{\\QQ}\\left(\\mathbb{P}_{\\Delta^{2}}\\right)}'
254
"""
255
return r"\left[ %s \right]_{%s}" % (
256
", ".join([latex(e) for e in self]), latex(self.parent()))
257
258
def _repr_(self):
259
r"""
260
Return a string representation of ``self``.
261
262
OUTPUT:
263
264
- string.
265
266
EXAMPLES::
267
268
sage: toric_varieties.dP6().divisor(0).divisor_class()._repr_()
269
'Divisor class [1, 0, 0, 0]'
270
"""
271
return 'Divisor class %s' % list(self)
272
273
def lift(self):
274
r"""
275
Return a divisor representing this divisor class.
276
277
OUTPUT:
278
279
An instance of :class:`ToricDivisor` representing ``self``.
280
281
EXAMPLES::
282
283
sage: X = toric_varieties.Cube_nonpolyhedral()
284
sage: D = X.divisor([0,1,2,3,4,5,6,7]); D
285
V(z1) + 2*V(z2) + 3*V(z3) + 4*V(z4) + 5*V(z5) + 6*V(z6) + 7*V(z7)
286
sage: D.divisor_class()
287
Divisor class [29, 6, 8, 10, 0]
288
sage: Dequiv = D.divisor_class().lift(); Dequiv
289
6*V(z1) - 17*V(z2) - 22*V(z3) - 7*V(z4) + 25*V(z6) + 32*V(z7)
290
sage: Dequiv == D
291
False
292
sage: Dequiv.divisor_class() == D.divisor_class()
293
True
294
"""
295
Cl = self.parent()
296
return Cl._variety.divisor(Cl._lift_matrix * self)
297
298
299
def _ToricRationalDivisorClass_unpickle_v1(parent, entries,
300
degree, is_mutable):
301
"""
302
Unpickle a :class:`toric rational divisor class
303
<ToricRationalDivisorClass>`.
304
305
INPUT:
306
307
- ``parent`` -- rational divisor class group of a toric variety;
308
309
- ``entries`` -- list of rationals specifying the divisor class;
310
311
- ``degree`` -- integer, dimension of the ``parent``;
312
313
- ``is_mutable`` -- boolean, whether the divisor class is mutable.
314
315
OUTPUT:
316
317
- :class:`toric rational divisor class <ToricRationalDivisorClass>`.
318
319
TESTS::
320
321
sage: dP6 = toric_varieties.dP6()
322
sage: Cl = dP6.rational_class_group()
323
sage: D = Cl([1, -2, 3, -4])
324
sage: D
325
Divisor class [1, -2, 3, -4]
326
sage: loads(dumps(D)) # indirect test
327
Divisor class [1, -2, 3, -4]
328
sage: from sage.schemes.toric.divisor_class import (
329
... _ToricRationalDivisorClass_unpickle_v1)
330
sage: _ToricRationalDivisorClass_unpickle_v1(
331
... Cl, [1, -2, 3, -4], 4, True)
332
Divisor class [1, -2, 3, -4]
333
"""
334
cdef ToricRationalDivisorClass v
335
v = PY_NEW(ToricRationalDivisorClass)
336
v._init(degree, parent)
337
cdef Rational z
338
for i from 0 <= i < degree:
339
z = Rational(entries[i])
340
mpq_init(v._entries[i])
341
mpq_set(v._entries[i], z.value)
342
v._is_mutable = is_mutable
343
return v
344
345