Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/toric/chow_group.py
4108 views
1
r"""
2
The Chow group of a toric variety
3
4
In general, the Chow group is an algebraic version of a homology
5
theory. That is, the objects are formal linear combinations of
6
submanifolds modulo relations. In particular, the objects of the Chow
7
group are formal linear combinations of algebraic subvarieties and the
8
equivalence relation is rational equivalence. There is no relative
9
version of the Chow group, so it is not a generalized homology
10
theory.
11
12
The Chow groups of smooth or mildly singular toric varieties are
13
almost the same as the homology groups:
14
15
* For smooth toric varieties, `A_{k}(X) = H_{2k}(X,\ZZ)`. While they
16
are the same, using the cohomology ring instead of the Chow group
17
will be much faster! The cohomology ring does not try to keep track
18
of torsion and uses Groebner bases to encode the cup product.
19
20
* For simplicial toric varieties, `A_{k}(X)\otimes \QQ =
21
H_{2k}(X,\QQ)`.
22
23
Note that in these cases the odd-dimensional (co)homology groups
24
vanish. But for sufficiently singular toric varieties the Chow group
25
differs from the homology groups (and the odd-dimensional homology
26
groups no longer vanish). For singular varieties the Chow group is
27
much easier to compute than the (co)homology groups.
28
29
The toric Chow group of a toric variety is the Chow group generated by
30
the toric subvarieties, that is, closures of orbits under the torus
31
action. These are in one-to-one correspondence with the cones of the
32
fan and, therefore, the toric Chow group is a quotient of the free
33
Abelian group generated by the cones. In particular, the toric Chow
34
group has finite rank. One can show [FMSS1]_ that the toric Chow
35
groups equal the "full" Chow group of a toric variety, so there is no
36
need to distinguish these in the following.
37
38
AUTHORS:
39
40
- Volker Braun (2010-08-09): Initial version
41
42
REFERENCES:
43
44
.. [wp:ChowRing]
45
http://en.wikipedia.org/wiki/Chow_ring
46
47
.. [FMSS1]
48
Fulton, MacPherson, Sottile, Sturmfels:
49
*Intersection theory on spherical varieties*,
50
J. of Alg. Geometry 4 (1995), 181-193.
51
http://www.math.tamu.edu/~frank.sottile/ps/spherical.ps.gz
52
53
.. [FultonChow]
54
Chapter 5.1 "Chow Groups" of Fulton, William:
55
*Introduction to Toric Varieties*,
56
Princeton University Press
57
58
59
EXAMPLES::
60
61
sage: X = toric_varieties.Cube_deformation(7)
62
sage: X.is_smooth()
63
False
64
sage: X.is_orbifold()
65
False
66
sage: A = X.Chow_group()
67
sage: A.degree()
68
(Z, C7, C2 x C2 x Z^5, Z)
69
sage: A.degree(2).ngens()
70
7
71
sage: a = sum( A.gen(i) * (i+1) for i in range(0,A.ngens()) ) # an element of A
72
sage: a # long time (2s on sage.math, 2011)
73
( 3 | 1 mod 7 | 0 mod 2, 1 mod 2, 4, 5, 6, 7, 8 | 9 )
74
75
The Chow group elements are printed as ``( a0 | a1 mod 7 | a2 mod 2,
76
a3 mod 2, a4, a5, a6, a7, a8 | a9 )``, which denotes the element of
77
the Chow group in the same basis as ``A.degree()``. The ``|``
78
separates individual degrees, so the example means:
79
80
* The degree-0 part is `3 \in \ZZ`.
81
82
* The degree-1 part is `1 \in \ZZ_7`.
83
84
* The torsion of the degree-2 Chow group is `(0, 1) \in
85
\ZZ_2\oplus\ZZ_2`.
86
87
* The free part of the degree-2 Chow group is `(4, 5, 6, 7, 8) \in
88
\ZZ^5`.
89
90
* The degree-3 part is `9 \in \ZZ`.
91
92
Note that the generators ``A.gens()`` are not sorted in any way. In
93
fact, they may be of mixed degree. Use ``A.gens(degree=d)`` to obtain
94
the generators in a fixed degree ``d``. See
95
:meth:`ChowGroup_class.gens` for more details.
96
97
Cones of toric varieties can determine their own Chow cycle::
98
99
sage: A = X.Chow_group(); A
100
Chow group of 3-d toric variety covered by 6 affine patches
101
sage: cone = X.fan(dim=2)[3]; cone
102
2-d cone of Rational polyhedral fan in 3-d lattice N
103
sage: A_cone = A(cone); A_cone
104
( 0 | 1 mod 7 | 0 mod 2, 0 mod 2, 0, 0, 0, 0, 0 | 0 )
105
sage: A_cone.degree()
106
1
107
sage: 2 * A_cone
108
( 0 | 2 mod 7 | 0 mod 2, 0 mod 2, 0, 0, 0, 0, 0 | 0 )
109
sage: A_cone + A.gen(0)
110
( 0 | 1 mod 7 | 0 mod 2, 1 mod 2, 0, 0, 0, 0, 0 | 0 )
111
112
Chow cycles can be of mixed degrees::
113
114
sage: mixed = sum(A.gens()); mixed
115
( 1 | 4 mod 7 | 1 mod 2, 1 mod 2, 1, 1, 1, 1, 1 | 1 )
116
sage: mixed.project_to_degree(1)
117
( 0 | 4 mod 7 | 0 mod 2, 0 mod 2, 0, 0, 0, 0, 0 | 0 )
118
sage: sum( mixed.project_to_degree(i) for i in range(0,X.dimension()+1) ) == mixed
119
True
120
"""
121
122
#*****************************************************************************
123
# Copyright (C) 2010 Volker Braun <[email protected]>
124
#
125
# Distributed under the terms of the GNU General Public License (GPL)
126
#
127
# http://www.gnu.org/licenses/
128
#*****************************************************************************
129
130
from sage.misc.all import flatten
131
from sage.modules.fg_pid.fgp_module import FGP_Module_class
132
from sage.modules.fg_pid.fgp_element import FGP_Element
133
from sage.modules.free_module import FreeModule
134
from sage.structure.sage_object import SageObject
135
from sage.structure.factory import UniqueFactory
136
from sage.rings.all import ZZ, QQ, Infinity
137
138
from sage.geometry.cone import is_Cone
139
from sage.schemes.toric.variety import is_ToricVariety
140
from sage.schemes.toric.divisor import is_ToricDivisor
141
142
143
144
145
#*******************************************************************
146
class ChowCycle(FGP_Element):
147
"""
148
The elements of the Chow group.
149
150
.. WARNING::
151
152
Do not construct :class:`ChowCycle` objects manually. Instead,
153
use the parent :class:`ChowGroup<ChowGroup_class>` to obtain
154
generators or Chow cycles correspondig to cones of the fan.
155
156
EXAMPLES::
157
158
sage: P2 = toric_varieties.P2()
159
sage: A = P2.Chow_group()
160
sage: A.gens()
161
(( 1 | 0 | 0 ), ( 0 | 1 | 0 ), ( 0 | 0 | 1 ))
162
sage: cone = P2.fan(1)[0]
163
sage: A(cone)
164
( 0 | 1 | 0 )
165
sage: A( Cone([(1,0)]) )
166
( 0 | 1 | 0 )
167
"""
168
169
def __init__(self, parent, v, check=True):
170
r"""
171
Construct a :class:`ChowCycle`.
172
173
INPUT:
174
175
- ``parent`` -- a :class:`ChowGroup_class`.
176
177
- ``v`` -- a vector in the covering module, that is, with one
178
entry for each cone of the toric variety.
179
180
- ``check`` -- boolean (default: ``True``). Verify that ``v``
181
is in the covering module. Set to ``False`` if you want to
182
initialize from a coordinate vector.
183
184
TESTS::
185
186
sage: P2 = toric_varieties.P2()
187
sage: A = P2.Chow_group()
188
sage: from sage.schemes.toric.chow_group import ChowCycle
189
sage: ChowCycle(A, (0,1,2,3,11,12,13), check=False)
190
( 36 | 6 | 0 )
191
"""
192
FGP_Element.__init__(self, parent, v, check)
193
194
195
def _repr_(self):
196
r"""
197
Return a string representation of the Chow cycle.
198
199
OUTPUT:
200
201
See the module-level documentation for details.
202
203
EXAMPLES::
204
205
sage: P2 = toric_varieties.P2()
206
sage: A = P2.Chow_group()
207
sage: A.degree()
208
(Z, Z, Z)
209
sage: A.an_element()._repr_()
210
'( 1 | 0 | 0 )'
211
212
A more complicated example with torsion::
213
214
sage: X = toric_varieties.Cube_nonpolyhedral()
215
sage: A = X.Chow_group()
216
sage: A.degree()
217
(Z, 0, C2 x Z^5, Z)
218
sage: sum( A.gen(i) * (i+1) for i in range(0,A.ngens()) )
219
( 2 || 1 mod 2, 3, 4, 5, 6, 7 | 8 )
220
"""
221
A = self.parent()
222
s = '('
223
for degree in range(0,A.scheme().dimension()+1):
224
if degree>0:
225
s += '|'
226
generators = A.gens(degree=degree)
227
coefficients = A.coordinate_vector(self, degree=degree)
228
if len(generators)>0:
229
s += ' '
230
for i, gen in enumerate(generators):
231
if i>0:
232
s += ', '
233
s += str(coefficients[i])
234
if gen.order() != Infinity:
235
s += ' mod '+str(gen.order())
236
if len(generators)>0:
237
s += ' '
238
s += ')'
239
return s
240
241
242
def degree(self):
243
r"""
244
The degree of the Chow cycle.
245
246
OUTPUT:
247
248
Integer. The complex dimension of the subvariety representing
249
the Chow cycle. Raises a ``ValueError`` if the Chow cycle is a
250
sum of mixed degree cycles.
251
252
EXAMPLES::
253
254
sage: P2 = toric_varieties.P2()
255
sage: A = P2.Chow_group()
256
sage: [ a.degree() for a in A.gens() ]
257
[0, 1, 2]
258
"""
259
if '_dim' in self.__dict__:
260
return self._dim
261
262
ambient_dim = self.parent()._variety.dimension()
263
cone_dim = None
264
for i, cone in enumerate(self.parent()._cones):
265
if self.lift()[i]!=0:
266
if cone_dim not in [None,cone.dim()]:
267
raise ValueError, 'Chow cycle is not of definite degree.'
268
cone_dim = cone.dim()
269
self._dim = ambient_dim - cone_dim
270
return self._dim
271
272
273
def project_to_degree(self, degree):
274
r"""
275
Project a (mixed-degree) Chow cycle to the given ``degree``.
276
277
INPUT:
278
279
- ``degree`` -- integer. The degree to project to.
280
281
OUTPUT:
282
283
The projection of the Chow class to the given degree as a new
284
:class:`ChowCycle` of the same Chow group.
285
286
EXAMPLES::
287
288
sage: A = toric_varieties.P2().Chow_group()
289
sage: cycle = 10*A.gen(0) + 11*A.gen(1) + 12*A.gen(2)
290
sage: cycle
291
( 10 | 11 | 12 )
292
sage: cycle.project_to_degree(2)
293
( 0 | 0 | 12 )
294
"""
295
ambient_dim = self.parent()._variety.dimension()
296
v = list(self.lift())
297
for i in range(0,len(v)):
298
cone = self.parent()._cones[i]
299
if cone.dim() != ambient_dim-degree:
300
v[i] = 0
301
v = self.parent().cover()(v)
302
P = self.parent()
303
return P.element_class(P, v, check=False)
304
305
306
def count_points(self):
307
r"""
308
Return the number of points in the Chow cycle.
309
310
OUTPUT:
311
312
An element of ``self.base_ring()``, which is usually
313
`\ZZ`. The number of points in the Chow cycle.
314
315
EXAMPLES::
316
317
sage: P2 = toric_varieties.P2()
318
sage: A = P2.Chow_group()
319
sage: a = 5*A.gen(0) + 7*A.gen(1); a
320
( 5 | 7 | 0 )
321
sage: a.count_points()
322
5
323
324
In the case of a smooth complete toric variety, the Chow
325
(homology) groups are Poincare dual to the integral cohomology
326
groups. Here is such a smooth example::
327
328
sage: D = P2.divisor(1)
329
sage: a = D.Chow_cycle()
330
sage: aD = a.intersection_with_divisor(D)
331
sage: aD.count_points()
332
1
333
sage: P2.integrate( aD.cohomology_class() )
334
1
335
336
For toric varieties with at most orbifold singularities, the
337
isomorphism only holds over `\QQ`. But the normalization of
338
the integral is still chosen such that the intersection
339
numbers (which are potentially rational) computed both ways
340
agree::
341
342
sage: P1xP1_Z2 = toric_varieties.P1xP1_Z2()
343
sage: Dt = P1xP1_Z2.divisor(1); Dt
344
V(t)
345
sage: Dy = P1xP1_Z2.divisor(3); Dy
346
V(y)
347
sage: Dt.Chow_cycle(QQ).intersection_with_divisor(Dy).count_points()
348
1/2
349
sage: P1xP1_Z2.integrate( Dt.cohomology_class() * Dy.cohomology_class() )
350
1/2
351
"""
352
c0 = self.project_to_degree(0).lift()
353
return sum(c0)
354
355
356
def intersection_with_divisor(self, divisor):
357
"""
358
Intersect the Chow cycle with ``divisor``.
359
360
See [FultonChow]_ for a description of the toric algorithm.
361
362
INPUT:
363
364
- ``divisor`` -- a :class:`ToricDivisor
365
<sage.schemes.toric.divisor.ToricDivisor_generic>`
366
that can be moved away from the Chow cycle. For example, any
367
Cartier divisor. See also :meth:`ToricDivisor.move_away_from
368
<sage.schemes.toric.divisor.ToricDivisor_generic.move_away_from>`.
369
370
OUTPUT:
371
372
A new :class:`ChowCycle`. If the divisor is not Cartier then
373
this method potentially raises a ``ValueError``, indicating
374
that the divisor cannot be made transversal to the Chow cycle.
375
376
EXAMPLES::
377
378
sage: dP6 = toric_varieties.dP6()
379
sage: cone = dP6.fan().cone_containing(2); cone
380
1-d cone of Rational polyhedral fan in 2-d lattice N
381
sage: D = dP6.divisor(cone); D
382
V(y)
383
sage: A = dP6.Chow_group()
384
sage: A(cone)
385
( 0 | 0, 0, 0, 1 | 0 )
386
sage: intersection = A(cone).intersection_with_divisor(D); intersection
387
( -1 | 0, 0, 0, 0 | 0 )
388
sage: intersection.count_points()
389
-1
390
391
You can do the same computation over the rational Chow group
392
since there is no torsion in this case::
393
394
sage: A_QQ = dP6.Chow_group(base_ring=QQ)
395
sage: A_QQ(cone)
396
( 0 | 0, 0, 0, 1 | 0 )
397
sage: intersection_QQ = A_QQ(cone).intersection_with_divisor(D); intersection
398
( -1 | 0, 0, 0, 0 | 0 )
399
sage: intersection_QQ.count_points()
400
-1
401
sage: type(intersection_QQ.count_points())
402
<type 'sage.rings.rational.Rational'>
403
sage: type(intersection.count_points())
404
<type 'sage.rings.integer.Integer'>
405
406
TESTS:
407
408
The relations are the Chow cycles rationally equivalent to the
409
zero cycle. Their intersection with any divisor must be the zero cycle::
410
411
sage: [ r.intersection_with_divisor(D) for r in dP6.Chow_group().relation_gens() ]
412
[( 0 | 0, 0, 0, 0 | 0 ), ( 0 | 0, 0, 0, 0 | 0 ),
413
( 0 | 0, 0, 0, 0 | 0 ), ( 0 | 0, 0, 0, 0 | 0 ),
414
( 0 | 0, 0, 0, 0 | 0 ), ( 0 | 0, 0, 0, 0 | 0 ),
415
( 0 | 0, 0, 0, 0 | 0 )]
416
sage: [ r.intersection_with_divisor(D).lift() for r in dP6.Chow_group().relation_gens() ]
417
[(0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0),
418
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
419
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
420
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
421
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
422
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
423
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]
424
"""
425
assert is_ToricDivisor(divisor), str(divisor)+' is not a toric divisor.'
426
427
A = self.parent() # the Chow group
428
X = A._variety # the toric variety
429
intersection = A(0)
430
coefficients = self.lift()
431
432
for sigma_idx, sigma in enumerate(A._cones):
433
if sigma.dim()==X.dimension():
434
# full-dimensional cone = degree-0 Chow cycle
435
continue
436
coefficient = coefficients[sigma_idx]
437
if coefficient==0:
438
continue
439
D = divisor.move_away_from(sigma)
440
for gamma in sigma.facet_of():
441
# note: the relative quotients are of dimension one
442
n = gamma.relative_quotient(sigma).gen(0).lift()
443
perp = sigma.relative_orthogonal_quotient(gamma).gen(0).lift()
444
I_gamma = set(gamma.ambient_ray_indices()) - set(sigma.ambient_ray_indices())
445
i = I_gamma.pop() # index of a ray in gamma but not sigma
446
v_i = X.fan().ray(i)
447
a_i = D.coefficient(i)
448
s_i = (v_i*perp)/(n*perp)
449
b_gamma = a_i/s_i
450
# print sigma._points_idx, "\t", i, D, a_i, s_i, b_gamma, gamma.A()
451
intersection += self.base_ring()(coefficient*b_gamma) * A(gamma)
452
return intersection
453
454
455
def cohomology_class(self):
456
r"""
457
Return the (Poincare-dual) cohomology class.
458
459
Consider a simplicial cone of the fan, that is, a
460
`d`-dimensional cone spanned by `d` rays. Take the product of
461
the corresponding `d` homogeneous coordinates. This monomial
462
represents a cohomology classes of the toric variety `X`, see
463
:meth:`~sage.schemes.toric.variety.ToricVariety_field.cohomology_ring`.
464
Its cohomological degree is `2d`, which is the same degree as
465
the Poincare-dual of the (real) `\dim(X)-2d`-dimensional torus
466
orbit associated to the simplicial cone. By linearity, we can
467
associate a cohomology class to each Chow cycle of a
468
simplicial toric variety.
469
470
If the toric variety is compact and smooth, the associated
471
cohomology class actually is the Poincare dual (over the
472
integers) of the Chow cycle. In particular, integrals of dual
473
cohomology classes perform intersection computations.
474
475
If the toric variety is compact and has at most orbifold
476
singularities, the torsion parts in cohomology and the Chow
477
group can differ. But they are still isomorphic as rings over
478
the rationals. Moreover, the normalization of integration
479
(:meth:`volume_class
480
<sage.schemes.toric.variety.ToricVariety_field.volume_class>`)
481
and :meth:`count_points` are chosen to agree.
482
483
OUTPUT:
484
485
The
486
:class:`~sage.schemes.toric.variety.CohomologyClass`
487
which is associated to the Chow cycle.
488
489
If the toric variety is not simplicial, that is, has worse
490
than orbifold singularities, there is no way to associate a
491
cohomology class of the correct degree. In this case,
492
:meth:`cohomology_class` rasies a ``ValueError``.
493
494
EXAMPLES::
495
496
sage: dP6 = toric_varieties.dP6()
497
sage: cone = dP6.fan().cone_containing(2,3)
498
sage: HH = dP6.cohomology_ring()
499
sage: A = dP6.Chow_group()
500
sage: HH(cone)
501
[-w^2]
502
sage: A(cone)
503
( 1 | 0, 0, 0, 0 | 0 )
504
sage: A(cone).cohomology_class()
505
[-w^2]
506
507
Here is an example of a toric variety with orbifold
508
singularities, where we can also use the isomorphism with the
509
rational cohomology ring::
510
511
sage: WP4 = toric_varieties.P4_11169()
512
sage: A = WP4.Chow_group()
513
sage: HH = WP4.cohomology_ring()
514
sage: cone3d = Cone([(0,0,1,0), (0,0,0,1), (-9,-6,-1,-1)])
515
sage: A(cone3d)
516
( 0 | 1 | 0 | 0 | 0 )
517
sage: HH(cone3d)
518
[3*z4^3]
519
520
sage: D = -WP4.K() # the anticanonical divisor
521
sage: A(D)
522
( 0 | 0 | 0 | 18 | 0 )
523
sage: HH(D)
524
[18*z4]
525
526
sage: WP4.integrate( A(cone3d).cohomology_class() * D.cohomology_class() )
527
1
528
sage: WP4.integrate( HH(cone3d) * D.cohomology_class() )
529
1
530
sage: A(cone3d).intersection_with_divisor(D).count_points()
531
1
532
"""
533
toric_variety = self.parent().scheme()
534
if not toric_variety.is_orbifold():
535
raise(ValueError, 'The toric variety may have at most orbifold singularities!')
536
HH = toric_variety.cohomology_ring()
537
coeff = self.lift()
538
return sum([ HH(cone) * coeff[i] for i,cone in enumerate(self.parent()._cones) ])
539
540
541
#*******************************************************************
542
class ChowGroupFactory(UniqueFactory):
543
"""
544
Factory for :class:`ChowGroup_class`.
545
"""
546
547
def create_key_and_extra_args(self, toric_variety, base_ring=ZZ, check=True):
548
"""
549
Create a key that uniquely determines the :class:`ChowGroup_class`.
550
551
INPUT:
552
553
- ``toric_variety`` -- a toric variety.
554
555
- ``base_ring`` -- either `\ZZ` (default) or `\QQ`. The
556
coefficient ring of the Chow group.
557
558
- ``check`` -- boolean (default: ``True``).
559
560
EXAMPLES::
561
562
sage: from sage.schemes.toric.chow_group import *
563
sage: P2 = toric_varieties.P2()
564
sage: ChowGroup(P2, ZZ, check=True) == ChowGroup(P2, ZZ, check=False) # indirect doctest
565
True
566
"""
567
if not is_ToricVariety(toric_variety):
568
raise ValueError, 'First argument must be a toric variety.'
569
570
if not base_ring in [ZZ,QQ]:
571
raise ValueError, 'Base ring must be either ZZ or QQ.'
572
573
key = tuple([toric_variety, base_ring])
574
extra = {'check':check}
575
return key, extra
576
577
578
def create_object(self, version, key, **extra_args):
579
"""
580
Create a :class:`ChowGroup_class`.
581
582
INPUT:
583
584
- ``version`` -- object version. Currently not used.
585
586
- ``key`` -- a key created by :meth:`create_key_and_extra_args`.
587
588
- ``**extra_args`` -- Currently not used.
589
590
EXAMPLES::
591
592
sage: from sage.schemes.toric.chow_group import *
593
sage: P2 = toric_varieties.P2()
594
sage: ChowGroup(P2) # indirect doctest
595
Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches
596
"""
597
toric_variety, base_ring = key
598
check = extra_args['check']
599
return ChowGroup_class(toric_variety, base_ring, check)
600
601
602
ChowGroup = ChowGroupFactory('ChowGroup')
603
604
605
#*******************************************************************
606
class ChowGroup_class(FGP_Module_class):
607
r"""
608
The Chow group of a toric variety.
609
610
EXAMPLES::
611
612
sage: P2=toric_varieties.P2()
613
sage: from sage.schemes.toric.chow_group import ChowGroup_class
614
sage: A = ChowGroup_class(P2,ZZ,True); A
615
Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches
616
sage: A.an_element()
617
( 1 | 0 | 0 )
618
"""
619
620
Element = ChowCycle
621
622
def __init__(self, toric_variety, base_ring, check):
623
r"""
624
EXAMPLES::
625
626
sage: from sage.schemes.toric.chow_group import *
627
sage: P2=toric_varieties.P2()
628
sage: A = ChowGroup_class(P2,ZZ,True); A
629
Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches
630
sage: is_ChowGroup(A)
631
True
632
sage: is_ChowCycle(A.an_element())
633
True
634
635
TESTS::
636
637
sage: A_ZZ = P2.Chow_group()
638
sage: 2 * A_ZZ.an_element() * 3
639
( 6 | 0 | 0 )
640
sage: 1/2 * A_ZZ.an_element() * 1/3
641
Traceback (most recent call last):
642
...
643
TypeError: unsupported operand parent(s) for '*': 'Rational Field'
644
and 'Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches'
645
sage: A_ZZ.get_action(ZZ)
646
Right scalar multiplication by Integer Ring on Chow group of 2-d
647
CPR-Fano toric variety covered by 3 affine patches
648
sage: A_ZZ.get_action(QQ)
649
650
You can't multiply integer classes with fractional
651
numbers. For that you need to go to the rational Chow group::
652
653
sage: A_QQ = P2.Chow_group(QQ)
654
sage: 2 * A_QQ.an_element() * 3
655
( 0 | 0 | 6 )
656
sage: 1/2 * A_QQ.an_element() * 1/3
657
( 0 | 0 | 1/6 )
658
sage: A_QQ.get_action(ZZ)
659
Right scalar multiplication by Integer Ring on QQ-Chow group of 2-d
660
CPR-Fano toric variety covered by 3 affine patches
661
sage: A_QQ.get_action(QQ)
662
Right scalar multiplication by Rational Field on QQ-Chow group of 2-d
663
CPR-Fano toric variety covered by 3 affine patches
664
"""
665
self._variety = toric_variety
666
667
# cones are automatically sorted by dimension
668
self._cones = flatten( toric_variety.fan().cones() )
669
670
V = FreeModule(base_ring, len(self._cones))
671
W = self._rational_equivalence_relations(V)
672
673
super(ChowGroup_class,self).__init__(V, W, check)
674
675
676
def scheme(self):
677
r"""
678
Return the underlying toric variety.
679
680
OUTPUT:
681
682
A :class:`ToricVariety
683
<sage.schemes.toric.variety.ToricVariety_field>`.
684
685
EXAMPLES::
686
687
sage: P2 = toric_varieties.P2()
688
sage: A = P2.Chow_group()
689
sage: A.scheme()
690
2-d CPR-Fano toric variety covered by 3 affine patches
691
sage: A.scheme() is P2
692
True
693
"""
694
return self._variety
695
696
697
def _element_constructor_(self, x, check=True):
698
r"""
699
Construct a :class:`ChowCycle`.
700
701
INPUT:
702
703
- ``x`` -- a cone of the fan, a toric divisor, or a valid
704
input for
705
:class:sage.modules.fg_pid.fgp_module.FGP_Module_class`.
706
707
- ``check`` -- bool (default: ``True``). See
708
:class:sage.modules.fg_pid.fgp_module.FGP_Module_class`.
709
710
EXAMPLES::
711
712
sage: dP6 = toric_varieties.dP6()
713
sage: A = dP6.Chow_group()
714
sage: cone = dP6.fan(dim=1)[4]
715
sage: A(cone)
716
( 0 | 0, 1, 0, 0 | 0 )
717
sage: A(Cone(cone)) # isomorphic but not identical to a cone of the fan!
718
( 0 | 0, 1, 0, 0 | 0 )
719
sage: A( dP6.K() )
720
( 0 | -1, -2, -2, -1 | 0 )
721
"""
722
fan = self._variety.fan()
723
if is_Cone(x):
724
cone = fan.embed(x)
725
return self.element_class(self, self._cone_to_V(cone), False)
726
if is_ToricDivisor(x):
727
v = sum(x.coefficient(i)*self._cone_to_V(onecone)
728
for i,onecone in enumerate(fan(1)))
729
return self.element_class(self, v, False)
730
return super(ChowGroup_class,self)._element_constructor_(x, check)
731
732
733
def _coerce_map_from_(self, S):
734
"""
735
Return true if S canonically coerces to self.
736
737
EXAMPLES::
738
739
sage: A = toric_varieties.P2().Chow_group()
740
sage: A._coerce_map_from_(ZZ) # private method
741
False
742
sage: A.has_coerce_map_from(ZZ) # recommended usage
743
False
744
"""
745
# We might want to coerce Cone_of_fans into ChowCycles
746
# but cones don't have parents at the moment.
747
return super(ChowGroup_class,self)._coerce_map_from_(S)
748
749
750
def _rational_equivalence_relations(self, V):
751
r"""
752
Return the rational equivalence relations between the cones of the fan.
753
754
See :meth:`relation_gens` for details.
755
756
EXAMPLES::
757
758
sage: points_mod = lambda k: matrix([[ 1, 1, 2*k+1],[ 1,-1, 1],[-1, 1, 1],[-1,-1, 1],[-1,-1,-1],[-1, 1,-1],[ 1,-1,-1],[ 1, 1,-1]])
759
sage: points = lambda k: matrix([[1,1,1],[1,-1,1],[-1,1,1]]).solve_left(points_mod(k)).rows()
760
sage: cones = [[0,1,2,3],[4,5,6,7],[0,1,7,6],[4,5,3,2],[0,2,5,7],[4,6,1,3]]
761
sage: X_Delta = lambda k: ToricVariety( Fan(cones=cones, rays=points(k)) )
762
sage: from sage.schemes.toric.chow_group import ChowGroup
763
sage: A = ChowGroup( X_Delta(2) )
764
sage: rel = A._rational_equivalence_relations(A.cover()).basis()
765
sage: matrix(rel).submatrix(col=0, ncols=1).elementary_divisors()
766
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
767
sage: matrix(rel).submatrix(col=1, ncols=8).elementary_divisors()
768
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
769
sage: matrix(rel).submatrix(col=9, ncols=12).elementary_divisors()
770
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0]
771
sage: matrix(rel).submatrix(col=21, ncols=6).elementary_divisors()
772
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
773
"""
774
fan = self._variety.fan()
775
dim = self._variety.dimension()
776
relations = []
777
for rho in self._cones:
778
for u in rho.orthogonal_sublattice().gens():
779
rel = V.zero()
780
for sigma in rho.facet_of():
781
sigma_idx = self._cones.index(sigma)
782
Q = sigma.relative_quotient(rho)
783
for v in [n.lift() for n in Q.gens()]:
784
rel += (u*v) * V.gen(sigma_idx)
785
relations.append(rel)
786
return V.span(relations)
787
788
789
def __div__(self, other):
790
r"""
791
Return the quotient of the Chow group by a subgroup.
792
793
OUTPUT:
794
795
Currently not implemented.
796
797
EXAMPLES::
798
799
sage: A = toric_varieties.dP6().Chow_group()
800
sage: Asub = A.submodule([ A.gen(0), A.gen(3) ])
801
sage: A/Asub
802
Traceback (most recent call last):
803
...
804
NotImplementedError: Quotients of the Chow group are not implemented.
805
"""
806
raise NotImplementedError, 'Quotients of the Chow group are not implemented.'
807
808
809
def _repr_(self):
810
"""
811
Return a string representation.
812
813
EXAMPLES::
814
815
sage: P2=toric_varieties.P2()
816
sage: from sage.schemes.toric.chow_group import ChowGroup
817
sage: ChowGroup(P2,ZZ)._repr_()
818
'Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches'
819
sage: ChowGroup(P2,QQ)._repr_()
820
'QQ-Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches'
821
"""
822
if self.base_ring() == QQ:
823
return "QQ-Chow group of " + str(self._variety)
824
elif self.base_ring() == ZZ:
825
return "Chow group of " + str(self._variety)
826
else:
827
raise(ValueError, 'Base ring must be QQ or ZZ.')
828
829
830
def __eq__(self, other):
831
r"""
832
Comparison of two Chow groups.
833
834
INPUT:
835
836
- ``other`` -- anything.
837
838
OUTPUT:
839
840
``True`` or ``False``.
841
842
EXAMPLES::
843
844
sage: P2 = toric_varieties.P2()
845
sage: P2.Chow_group() == P2.Chow_group()
846
True
847
sage: P2.Chow_group(ZZ) == P2.Chow_group(QQ)
848
False
849
"""
850
return self is other # ChowGroup_class is unique
851
852
853
def _cone_to_V(self, cone):
854
r"""
855
Convert a cone into the corresponding vector in ``self._V``
856
857
INPUT:
858
859
- ``cone`` -- a :class:`sage.geometry.cone.ConvexRationalPolyhedralCone`.
860
861
OUPUT:
862
863
The corresponding element of ``self.V()``.
864
865
EXAMPLES::
866
867
sage: P2 = toric_varieties.P2()
868
sage: A = P2.Chow_group()
869
sage: cone = P2.fan(dim=1)[0]
870
sage: A._cone_to_V(cone)
871
(0, 1, 0, 0, 0, 0, 0)
872
"""
873
assert cone.ambient() is self._variety.fan()
874
x = [0] * len(self._cones)
875
x[self._cones.index(cone)] = 1
876
return self._V(x)
877
878
879
def degree(self, k=None):
880
r"""
881
Return the degree-`k` Chow group.
882
883
INPUT:
884
885
- ``k`` -- an integer or ``None`` (default). The degree of the
886
Chow group.
887
888
OUTPUT:
889
890
- if `k` was specified, the Chow group `A_k` as an Abelian
891
group.
892
893
- if `k` was not specified, a tuple containing the Chow groups
894
in all degrees.
895
896
.. NOTE::
897
898
* For a smooth toric variety, this is the same as the
899
Poincare-dual cohomology group
900
`H^{d-2k}(X,\ZZ)`.
901
902
* For a simplicial toric variety ("orbifold"),
903
`A_k(X)\otimes \QQ = H^{d-2k}(X,\QQ)`.
904
905
EXAMPLES:
906
907
Four exercises from page 65 of [FultonP65]_. First, an example
908
with `A_1(X)=\ZZ\oplus\ZZ/3\ZZ`::
909
910
sage: X = ToricVariety(Fan(cones=[[0,1],[1,2],[2,0]],
911
... rays=[[2,-1],[-1,2],[-1,-1]]))
912
sage: A = X.Chow_group()
913
sage: A.degree(1)
914
C3 x Z
915
916
Second, an example with `A_2(X)=\ZZ^2`::
917
918
sage: points = [[1,0,0],[0,1,0],[0,0,1],[1,-1,1],[-1,0,-1]]
919
sage: l = LatticePolytope(matrix(points).transpose())
920
sage: l.show3d()
921
sage: X = ToricVariety(FaceFan(l))
922
sage: A = X.Chow_group()
923
sage: A.degree(2)
924
Z^2
925
926
Third, an example with `A_2(X)=\ZZ^5`::
927
928
sage: cube = [[ 1,0,0],[0, 1,0],[0,0, 1],[-1, 1, 1],
929
... [-1,0,0],[0,-1,0],[0,0,-1],[ 1,-1,-1]]
930
sage: lat_cube = LatticePolytope(matrix(cube).transpose())
931
sage: X = ToricVariety(FaceFan((LatticePolytope(lat_cube))))
932
sage: X.Chow_group().degree(2)
933
Z^5
934
935
Fourth, a fan that is not the fan over a
936
polytope. Combinatorially, the fan is the same in the third
937
example, only the coordinates of the first point are
938
different. But the resulting fan is not the face fan of a
939
cube, so the variety is "more singular". Its Chow group has
940
torsion, `A_2(X)=\ZZ^5 \oplus \ZZ/2`::
941
942
sage: rays = [[ 1, 2, 3],[ 1,-1, 1],[-1, 1, 1],[-1,-1, 1],
943
... [-1,-1,-1],[-1, 1,-1],[ 1,-1,-1],[ 1, 1,-1]]
944
sage: cones = [[0,1,2,3],[4,5,6,7],[0,1,7,6],
945
... [4,5,3,2],[0,2,5,7],[4,6,1,3]]
946
sage: X = ToricVariety(Fan(cones, rays))
947
sage: X.Chow_group().degree(2) # long time (2s on sage.math, 2011)
948
C2 x Z^5
949
950
Finally, Example 1.3 of [FS]_::
951
952
sage: points_mod = lambda k: matrix([[ 1, 1, 2*k+1],[ 1,-1, 1],
953
... [-1, 1, 1],[-1,-1, 1],[-1,-1,-1],
954
... [-1, 1,-1],[ 1,-1,-1],[ 1, 1,-1]])
955
sage: rays = lambda k: matrix([[1,1,1],[1,-1,1],[-1,1,1]]
956
... ).solve_left(points_mod(k)).rows()
957
sage: cones = [[0,1,2,3],[4,5,6,7],[0,1,7,6],
958
... [4,5,3,2],[0,2,5,7],[4,6,1,3]]
959
sage: X_Delta = lambda k: ToricVariety(Fan(cones=cones, rays=rays(k)))
960
sage: X_Delta(0).Chow_group().degree() # long time (3s on sage.math, 2011)
961
(Z, Z, Z^5, Z)
962
sage: X_Delta(1).Chow_group().degree() # long time (3s on sage.math, 2011)
963
(Z, 0, Z^5, Z)
964
sage: X_Delta(2).Chow_group().degree() # long time (3s on sage.math, 2011)
965
(Z, C2, Z^5, Z)
966
sage: X_Delta(2).Chow_group(base_ring=QQ).degree() # long time (4s on sage.math, 2011)
967
(Q, 0, Q^5, Q)
968
"""
969
if k!=None:
970
return self.degree()[k]
971
972
try:
973
return self._degree
974
except AttributeError:
975
pass
976
977
self._degree = tuple(ChowGroup_degree_class(self,d)
978
for d in range(0,self._variety.dimension()+1))
979
return self._degree
980
981
982
def coordinate_vector(self, chow_cycle, degree=None, reduce=True):
983
r"""
984
Return the coordinate vector of the ``chow_cycle``.
985
986
INPUT:
987
988
- ``chow_cycle`` -- a :class:`ChowCycle`.
989
990
- ``degree`` -- None (default) or an integer.
991
992
- ``reduce`` -- boolean (default: ``True``). Whether to reduce
993
modulo the invariants.
994
995
OUTPUT:
996
997
* If ``degree==None`` (default), the coordinate vector
998
relative to the basis ``self.gens()`` is returned.
999
1000
* If some integer ``degree=d`` is specified, the chow cycle is
1001
projected to the given degree and the coordinate vector
1002
relative to the basis ``self.gens(degree=d)`` is returned.
1003
1004
EXAMPLES::
1005
1006
sage: A = toric_varieties.P2().Chow_group()
1007
sage: a = A.gen(0) + 2*A.gen(1) + 3*A.gen(2)
1008
sage: A.coordinate_vector(a)
1009
(1, 2, 3)
1010
sage: A.coordinate_vector(a, degree=1)
1011
(2)
1012
"""
1013
if degree==None:
1014
return super(ChowGroup_class, self).coordinate_vector(chow_cycle, reduce=reduce)
1015
1016
a = chow_cycle.project_to_degree(degree)
1017
return self.degree(degree).module().coordinate_vector(a, reduce=reduce)
1018
1019
1020
def gens(self, degree=None):
1021
r"""
1022
Return the generators of the Chow group.
1023
1024
INPUT:
1025
1026
- ``degree`` -- integer (optional). The degree of the Chow
1027
group.
1028
1029
OUTPUT:
1030
1031
- if no degree is specified, the generators of the whole Chow
1032
group. The chosen generators may be of mixed degree.
1033
1034
- if ``degree=`` `k` was specified, the generators of the
1035
degree-`k` part `A_k` of the Chow group.
1036
1037
EXAMPLES::
1038
1039
sage: A = toric_varieties.P2().Chow_group()
1040
sage: A.gens()
1041
(( 1 | 0 | 0 ), ( 0 | 1 | 0 ), ( 0 | 0 | 1 ))
1042
sage: A.gens(degree=1)
1043
(( 0 | 1 | 0 ),)
1044
"""
1045
if degree==None:
1046
return super(ChowGroup_class, self).gens()
1047
else:
1048
return self.degree(degree).gens()
1049
1050
1051
def relation_gens(self):
1052
r"""
1053
Return the Chow cycles equivalent to zero.
1054
1055
For each `d-k-1`-dimensional cone `\rho \in \Sigma^{(d-k-1)}`,
1056
the relations in `A_k(X)`, that is the cycles equvalent to
1057
zero, are generated by
1058
1059
.. MATH::
1060
1061
0 \stackrel{!}{=}
1062
\mathop{\mathrm{div}}(u) =
1063
\sum_{\rho < \sigma \in \Sigma^{(n-p)} }
1064
\big< u, n_{\rho,\sigma} \big> V(\sigma)
1065
,\qquad
1066
u \in M(\rho)
1067
1068
where `n_{\rho,\sigma}` is a (randomly chosen) lift of the
1069
generator of `N_\sigma/N_\rho \simeq \ZZ`. See also Exercise
1070
12.5.7 of [CLS]_.
1071
1072
See also :meth:`relations` to obtain the relations as
1073
submodule of the free module generated by the cones. Or use
1074
``self.relations().gens()`` to list the relations in the free
1075
module.
1076
1077
OUTPUT:
1078
1079
A tuple of Chow cycles, each rationally equivalent to zero,
1080
that generates the rational equivalence.
1081
1082
1083
EXAMPLES::
1084
1085
sage: P2 = toric_varieties.P2()
1086
sage: A = P2.Chow_group()
1087
sage: first = A.relation_gens()[0]
1088
sage: first
1089
( 0 | 0 | 0 )
1090
sage: first.is_zero()
1091
True
1092
sage: first.lift()
1093
(0, 1, 0, -1, 0, 0, 0)
1094
"""
1095
gens = self.W().gens()
1096
return tuple( self(gen) for gen in gens )
1097
1098
1099
#*******************************************************************
1100
class ChowGroup_degree_class(SageObject):
1101
r"""
1102
A fixed-degree subgroup of the Chow group of a toric variety.
1103
1104
WARNING ..
1105
1106
Use
1107
:meth:`~sage.schemes.toric.chow_group.ChowGroup_class.degree`
1108
to construct :class:`ChowGroup_degree_class` instances.
1109
1110
EXAMPLES::
1111
1112
sage: P2 = toric_varieties.P2()
1113
sage: A = P2.Chow_group()
1114
sage: A
1115
Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches
1116
sage: A.degree()
1117
(Z, Z, Z)
1118
sage: A.degree(2)
1119
Z
1120
sage: type(_)
1121
<class 'sage.schemes.toric.chow_group.ChowGroup_degree_class'>
1122
"""
1123
1124
def __init__(self, A, d):
1125
r"""
1126
Construct a :class:`ChowGroup_degree_class`.
1127
1128
INPUT:
1129
1130
- ``A`` -- A :class:`ChowGroup_class`.
1131
1132
- ``d`` -- integer. The degree of the Chow group.
1133
1134
EXAMPLES::
1135
1136
sage: P2 = toric_varieties.P2()
1137
sage: A = P2.Chow_group()
1138
sage: from sage.schemes.toric.chow_group import ChowGroup_degree_class
1139
sage: A2 = ChowGroup_degree_class(A,2)
1140
sage: A2
1141
Z
1142
"""
1143
self._Chow_group = A
1144
self._degree = d
1145
1146
toric_variety = A.scheme()
1147
fan = toric_variety.fan()
1148
1149
# Some generators
1150
gens = []
1151
for cone in fan(codim=d):
1152
gen = A._cone_to_V(cone)
1153
gens.append(gen)
1154
1155
# The minimal set of generators
1156
self._module = A.submodule(gens)
1157
self._gens = tuple([ A.element_class(A, a.lift(), False)
1158
for a in self._module.gens() ])
1159
1160
1161
def _repr_(self):
1162
"""
1163
Return a string representation.
1164
1165
OUTPUT:
1166
1167
String.
1168
1169
EXAMPLES::
1170
1171
sage: projective_plane = toric_varieties.P2()
1172
sage: A2 = projective_plane.Chow_group().degree(2)
1173
sage: A2._repr_()
1174
'Z'
1175
sage: A2_QQ = projective_plane.Chow_group(base_ring=QQ).degree(2)
1176
sage: A2_QQ._repr_()
1177
'Q'
1178
"""
1179
invariants = self._module.invariants()
1180
if len(invariants)==0:
1181
return '0'
1182
1183
free = filter(lambda x:x==0, invariants)
1184
tors = filter(lambda x:x> 0, invariants)
1185
1186
if self._Chow_group.base_ring()==ZZ:
1187
ring = 'Z'
1188
elif self._Chow_group.base_ring()==QQ:
1189
ring = 'Q'
1190
else:
1191
raise NotImplementedError, 'Base ring must be ZZ or QQ.'
1192
1193
s = ['C' + str(x) for x in tors]
1194
if len(free)==1:
1195
s.append(ring)
1196
if len(free)>1:
1197
s.append(ring + '^' + str(len(free)))
1198
return ' x '.join(s)
1199
1200
1201
def module(self):
1202
"""
1203
Return the submodule of the toric Chow group generated.
1204
1205
OUTPUT:
1206
1207
A :class:`sage.modules.fg_pid.fgp_module.FGP_Module_class`
1208
1209
EXAMPLES::
1210
1211
sage: projective_plane = toric_varieties.P2()
1212
sage: A2 = projective_plane.Chow_group().degree(2)
1213
sage: A2.module()
1214
Finitely generated module V/W over Integer Ring with invariants (0)
1215
"""
1216
return self._module
1217
1218
1219
def ngens(self):
1220
"""
1221
Return the number of generators.
1222
1223
OUTPUT:
1224
1225
An integer.
1226
1227
EXAMPLES::
1228
1229
sage: projective_plane = toric_varieties.P2()
1230
sage: A2 = projective_plane.Chow_group().degree(2)
1231
sage: A2.ngens()
1232
1
1233
"""
1234
return len(self._gens)
1235
1236
1237
def gen(self, i):
1238
"""
1239
Return the ``i``-th generator of the Chow group of fixed
1240
degree.
1241
1242
INPUT:
1243
1244
- ``i`` -- integer. The index of the generator to be returned.
1245
1246
OUTPUT:
1247
1248
A tuple of Chow cycles of fixed degree generating
1249
:meth:`module`.
1250
1251
EXAMPLES::
1252
1253
sage: projective_plane = toric_varieties.P2()
1254
sage: A2 = projective_plane.Chow_group().degree(2)
1255
sage: A2.gen(0)
1256
( 0 | 0 | 1 )
1257
"""
1258
return self._gens[i]
1259
1260
1261
def gens(self):
1262
"""
1263
Return the generators of the Chow group of fixed degree.
1264
1265
OUTPUT:
1266
1267
A tuple of Chow cycles of fixed degree generating
1268
:meth:`module`.
1269
1270
EXAMPLES::
1271
1272
sage: projective_plane = toric_varieties.P2()
1273
sage: A2 = projective_plane.Chow_group().degree(2)
1274
sage: A2.gens()
1275
(( 0 | 0 | 1 ),)
1276
"""
1277
return self._gens
1278
1279
1280
#*******************************************************************
1281
def is_ChowGroup(x):
1282
r"""
1283
Return whether ``x`` is a :class:`ChowGroup_class`
1284
1285
INPUT:
1286
1287
- ``x`` -- anything.
1288
1289
OUTPUT:
1290
1291
``True`` or ``False``.
1292
1293
EXAMPLES::
1294
1295
sage: P2=toric_varieties.P2()
1296
sage: A = P2.Chow_group()
1297
sage: from sage.schemes.toric.chow_group import is_ChowGroup
1298
sage: is_ChowGroup(A)
1299
True
1300
sage: is_ChowGroup('Victoria')
1301
False
1302
"""
1303
return isinstance(x,ChowGroup_class)
1304
1305
1306
#*******************************************************************
1307
def is_ChowCycle(x):
1308
r"""
1309
Return whether ``x`` is a :class:`ChowGroup_class`
1310
1311
INPUT:
1312
1313
- ``x`` -- anything.
1314
1315
OUTPUT:
1316
1317
``True`` or ``False``.
1318
1319
EXAMPLES::
1320
1321
sage: P2=toric_varieties.P2()
1322
sage: A = P2.Chow_group()
1323
sage: from sage.schemes.toric.chow_group import *
1324
sage: is_ChowCycle(A)
1325
False
1326
sage: is_ChowCycle(A.an_element())
1327
True
1328
sage: is_ChowCycle('Victoria')
1329
False
1330
"""
1331
return isinstance(x,ChowCycle)
1332
1333