# Ticket #12361: trac_12361_fix_toric_cohomology_ring.patch

File trac_12361_fix_toric_cohomology_ring.patch, 21.1 KB (added by Volker Braun, 11 years ago)

Updated patch

• ## sage/schemes/generic/toric_chow_group.py

# HG changeset patch
# User Volker Braun <vbraun@stp.dias.ie>
# Date 1333102321 -3600
# Node ID abd365b60984ecf86c73f232971408f0e4f37ecc
# Parent  295777678afafeb5341221b15043f5e608766937
Trac #12361: Fix normalizations for cohomology classes

diff --git a/sage/schemes/generic/toric_chow_group.py b/sage/schemes/generic/toric_chow_group.py
 a 5 In the case of a smooth complete toric variety, the Chow (homology) groups are Poincare dual to the cohomology groups. Then the number of points equals the integral of the dual cohomology class. But in general there is no Poincare duality. Here is a smooth example:: (homology) groups are Poincare dual to the integral cohomology groups. Here is such a smooth example:: sage: D = P2.divisor(1) sage: a = D.Chow_cycle() 1 sage: P2.integrate( aD.cohomology_class() ) 1 For toric varieties with at most orbifold singularities, the isomorphism only holds over \QQ. But the normalization of the integral is still chosen such that the intersection numbers (which are potentially rational) computed both ways agree:: sage: P1xP1_Z2 = toric_varieties.P1xP1_Z2() sage: Dt = P1xP1_Z2.divisor(1);  Dt V(t) sage: Dy = P1xP1_Z2.divisor(3);  Dy V(y) sage: Dt.Chow_cycle(QQ).intersection_with_divisor(Dy).count_points() 1/2 sage: P1xP1_Z2.integrate( Dt.cohomology_class() * Dy.cohomology_class() ) 1/2 """ c0 = self.project_to_degree(0).lift() return sum(c0) cohomology classes perform intersection computations. If the toric variety is compact and has at most orbifold singularities, Poincare duality holds for rational cohomology only. In this case, the associated cohomology class is rationally Poincare-dual to the Chow cycle. However, the normalization of integrals over the associated cohomology classes will not always match the (integral) intersection numbers of the torus orbits. singularities, the torsion parts in cohomology and the Chow group can differ. But they are still isomorphic as rings over the rationals. Moreover, the normalization of integration (:meth:volume_class ) and :meth:count_points are chosen to agree. OUTPUT: The :class:~sage.schemes.generic.toric_variety.CohomologyClass which is associated to the Chow cycle. [-w^2] Here is an example of a toric variety with orbifold singularities, where Poincare duality holds only rationally:: singularities, where we can also use the isomorphism with the rational cohomology ring:: sage: WP4 = toric_varieties.P4_11169() sage: A = WP4.Chow_group() sage: HH = WP4.cohomology_ring() sage: cone3d = Cone([(0,0,1,0), (0,0,0,1), (-9,-6,-1,-1)]) sage: A(cone3d) ( 0 | 1 | 0 | 0 | 0 ) sage: HH(cone3d) [3*z4^3] sage: D = -WP4.K()  # the anticanonical divisor sage: A(D) ( 0 | 0 | 0 | 18 | 0 ) sage: HH(D) [18*z4] sage: WP4.integrate( A(cone3d).cohomology_class() * D.cohomology_class() ) 1/3 1 sage: WP4.integrate( HH(cone3d) * D.cohomology_class() ) 1/3 The last two lines are the same integral. In either case, the integrand is the product of the cohomology class associated to the 3-dimensional cone times the cohomology class associated to the divisor D. But the intersection number of the (real) 6-dimensional torus orbit corresponding to the 3-d cone with the divisor is of course not \frac{1}{3}. The actual intersection number is:: 1 sage: A(cone3d).intersection_with_divisor(D).count_points() 1 """
• ## sage/schemes/generic/toric_variety.py

diff --git a/sage/schemes/generic/toric_variety.py b/sage/schemes/generic/toric_variety.py
 a See also :mod:~sage.schemes.generic.fano_toric_variety for a more restrictive class of (weak) Fano toric varieties. An **excellent reference on toric varieties** is the book "Toric Varieties" by David A. Cox, John B. Little, and Hal Schenck [CLS]_. Its draft **is freely available** at http://www.cs.amherst.edu/~dac/toric.html **but will be removed** from this site once it is published, so hurry up! An **excellent reference on toric varieties** is the book "Toric Varieties" by David A. Cox, John B. Little, and Hal Schenck [CLS]_. The interface to this module is provided through functions :func:AffineToricVariety and :func:ToricVariety, although you may also be interested in :func:normalize_names. :func:AffineToricVariety and :func:ToricVariety, although you may also be interested in :func:normalize_names. .. NOTE:: ..  [CLS] David A. Cox, John B. Little,  Hal Schenck, "Toric Varieties", Graduate Studies in Mathematics, Amer. Math. Soc., Providence, RI, to appear. Amer. Math. Soc., Providence, RI, 2011 AUTHORS: :func:~sage.schemes.generic.fano_toric_variety.CPRFanoToricVariety, which can construct some other "nice partial resolutions." The intersection theory on toric varieties is very well understood, and there are explicit algorithms to compute many quantities of interest. The most important tools are the :class:cohomology ring  and the :mod:Chow group . For d-dimensional compact toric varieties with at most orbifold singularities, the rational cohomology ring H^*(X,\QQ) and the rational Chow ring A^*(X,\QQ) = A_{d-*}(X)\otimes \QQ are isomorphic except for a doubling in degree. More precisely, the Chow group has the same rank .. math:: A_{d-k}(X) \otimes \QQ \simeq H^{2k}(X,\QQ) and the intersection in of Chow cycles matches the cup product in cohomology. In this case, you should work with the cohomology ring description because it is much faster. For example, here is a weighted projective space with a curve of \ZZ_3-orbifold singularities:: sage: P4_11133 = toric_varieties.P4_11133() sage: P4_11133.is_smooth(), P4_11133.is_orbifold() (False, True) sage: cone = P4_11133.fan(3)[8] sage: cone.is_smooth(), cone.is_simplicial() (False, True) sage: HH = P4_11133.cohomology_ring();  HH Rational cohomology ring of a 4-d CPR-Fano toric variety covered by 5 affine patches sage: P4_11133.cohomology_basis() (([1],), ([z4],), ([z4^2],), ([z4^3],), ([z4^4],)) Every cone defines a torus orbit closure, and hence a (co)homology class:: sage: HH.gens() ([3*z4], [3*z4], [z4], [z4], [z4]) sage: map(HH, P4_11133.fan(1)) [[3*z4], [3*z4], [z4], [z4], [z4]] sage: map(HH, P4_11133.fan(4) ) [[9*z4^4], [9*z4^4], [9*z4^4], [9*z4^4], [9*z4^4]] sage: HH(cone) [3*z4^3] We can compute intersection numbers by integrating top-dimensional cohomology classes:: sage: D = P4_11133.divisor(0) sage: HH(D) [3*z4] sage: P4_11133.integrate( HH(D)^4 ) 9 sage: P4_11133.integrate( HH(D) * HH(cone) ) 1 Although computationally less efficient, we can do the same computations with the rational Chow group:: sage: AA = P4_11133.Chow_group(QQ) sage: map(AA, P4_11133.fan(1)) [( 0 | 0 | 0 | 3 | 0 ), ( 0 | 0 | 0 | 3 | 0 ), ( 0 | 0 | 0 | 1 | 0 ), ( 0 | 0 | 0 | 1 | 0 ), ( 0 | 0 | 0 | 1 | 0 )] sage: map(AA, P4_11133.fan(4)) [( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 ), ( 1 | 0 | 0 | 0 | 0 )] sage: AA(cone).intersection_with_divisor(D) ( 1 | 0 | 0 | 0 | 0 ) sage: AA(cone).intersection_with_divisor(D).count_points() 1 The real advantage of the Chow group is that * it works just as well over \ZZ, so torsion information is also easily available, and * its combinatorial description also works over worse-than-orbifold singularities. By contrast, the cohomology groups can become very complicated to compute in this case, and one usually only has a spectral sequence but no toric algorithm. Below you will find detailed descriptions of available functions. If you are familiar with toric geometry, you will likely see that many important objects and operations are unavailable. However, this module is under active r""" Check if self has only quotient singularities. A toric variety with at most orbifold singularities (in this sense) is often called a simplicial toric variety. In this package, we generally try to avoid this term since it mixes up differential geometry and cone terminology. OUTPUT: - True if self has at most quotient singularities by torsion-free, so in this case there is no loss of information when going to rational coefficients. - self.cohomology_ring().gen(i) is the divisor class generated by - self.cohomology_ring().gen(i) is the divisor class corresponding to the i-th ray of the fan. EXAMPLES:: return self._cohomology_basis def volume_class(self): """ r""" Return the cohomology class of the volume form on the toric variety. If the variety is non-compact: Note that we are using cohomology with compact supports. This is dual to homology without any support condition. In particular, for non-compact Note that we are using cohomology with compact supports. If the variety is non-compact this is dual to homology without any support condition. In particular, for non-compact varieties the volume form \mathrm{dVol}=\wedge_i(dx_i \wedge dy_i) does not define a cohomology class. dy_i) does not define a (non-zero) cohomology class. OUTPUT: the (properly normalized) volume form, that is, it is the Poincare dual of a single point. If it does not exist, a ValueError is raised. EXAMPLES:: sage: P2 = toric_varieties.P2() sage: P2.volume_class() [z^2] sage: A2_Z2 = toric_varieties.A2_Z2() sage: A2_Z2.volume_class() Traceback (most recent call last): ... ValueError: Volume class does not exist. If none of the maximal cones is smooth things get more tricky. In this case no torus-fixed point is smooth. If we want to count an ordinary point as 1, then a G-orbifold point needs to count as \frac{1}{|G|}. For example, take \mathbb{P}^1\times\mathbb{P}^1 with inhomogeneous coordinates (t,y). Take the quotient by the action (t,y)\mapsto (-t,-y). The \ZZ_2-invariant Weil divisors \{t=0\} and \{y=0\} intersect in a \ZZ_2-fixed point, so they ought to have intersection number \frac{1}{2}. This means that the cohomology class [t] \cap [y] should be \frac{1}{2} times the volume class. Note that this is different from the volume normalization chosen in [Schubert]_:: sage: P1xP1_Z2 = toric_varieties.P1xP1_Z2() sage: Dt = P1xP1_Z2.divisor(1);  Dt V(t) sage: Dy = P1xP1_Z2.divisor(3);  Dy V(y) sage: P1xP1_Z2.volume_class() [2*t*y] sage: HH = P1xP1_Z2.cohomology_ring() sage: HH(Dt) * HH(Dy) == 1/2 * P1xP1_Z2.volume_class() True The fractional coefficients are also necessary to match the normalization in the rational Chow group for simplicial toric varieties:: sage: A = P1xP1_Z2.Chow_group(QQ) sage: A(Dt).intersection_with_divisor(Dy).count_points() 1/2 REFERENCES: ..  [Schubert] Sheldon Katz and Stein Arild Stromme, A Maple package for intersection theory and enumerative geometry. """ if "_volume_class" not in self.__dict__: if not self.is_orbifold(): raise NotImplementedError('Cohomology computations are only ' 'implemented for orbifolds.') def V(cone): return abs(cone.ray_matrix().determinant()) min_cone = min( self._fan.generating_cones(), key=V) self._volume_class = self.cohomology_ring()(min_cone) / V(min_cone) HH = self.cohomology_ring() dim = self.dimension_relative() self._volume_class = HH(self.fan().generating_cone(0)).part_of_degree(dim) if self._volume_class.is_zero(): raise ValueError, 'Volume class does not exist.' return self._volume_class [ 0  0  1 -1  1  0] [ 0  0  0  1 -1  1] [ 1  0  0  0  1 -1] If the toric variety is an orbifold, the intersection numbers are usually fractional:: sage: P2_123 = toric_varieties.P2_123() sage: HH = P2_123.cohomology_ring() sage: D = [ HH(c) for c in P2_123.fan(dim=1) ] sage: matrix([ [ P2_123.integrate(D[i]*D[j]) for i in range(0,3) ] for j in range(0,3) ]) [2/3   1 1/3] [  1 3/2 1/2] [1/3 1/2 1/6] sage: A = P2_123.Chow_group(QQ) sage: matrix([ [ A(P2_123.divisor(i)) ...              .intersection_with_divisor(P2_123.divisor(j)) ...              .count_points() for i in range(0,3) ] for j in range(0,3) ]) [2/3   1 1/3] [  1 3/2 1/2] [1/3 1/2 1/6] """ assert self.is_complete(), "Can only integrate over compact varieties." top_form = cohomology_class.part_of_degree(self.dimension()) be converted into a polynomial in the homogeneous coordinates. OUTPUT: The :class:CohomologyClass defined by x. EXAMPLES:: sage: dP6 = toric_varieties.dP6() sage: H( dP6.fan(0)[0] )   # trivial cone [1] Non-smooth cones are a bit tricky. For such a cone, the intersection of the divisors corresponding to the rays is still proportional to the product of the variables, but the coefficient is a multiple depending on the orbifold singularity. See also [CLS]_, Lemma 12.5.2:: sage: P2_123 = toric_varieties.P2_123() sage: HH = P2_123.cohomology_ring() sage: HH(Cone([(1,0)])) * HH(Cone([(-2,-3)])) [2*z2^2] sage: HH(Cone([(1,0), (-2,-3)])) [6*z2^2] sage: [ HH(c) for c in P2_123.fan().generating_cones() ] [[6*z2^2], [6*z2^2], [6*z2^2]] sage: P2_123.volume_class() [6*z2^2] sage: [ HH(c.facets()[0]) * HH(c.facets()[1]) for c in P2_123.fan().generating_cones() ] [[6*z2^2], [3*z2^2], [2*z2^2]] Numbers will be converted into the ring:: elif is_Cone(x): cone = fan.embed(x) assert cone.ambient() is fan mult = cone.ray_matrix().index_in_saturation() x = prod((self.cover_ring().gen(i) for i in cone.ambient_ray_indices()), z=self.cover_ring().one()) z=self.cover_ring().one()) * mult else: try: # divisor, for example, know how to compute their own cohomology class
• ## sage/schemes/generic/toric_variety_library.py

diff --git a/sage/schemes/generic/toric_variety_library.py b/sage/schemes/generic/toric_variety_library.py
 a 'P1xP1':[ [(1, 0), (-1, 0), (0, 1), (0, -1)], [[0,2],[2,1],[1,3],[3,0]] ], 'P1xP1_Z2':[ [(1, 1), (-1, -1), (-1, 1), (1, -1)], [[0,2],[2,1],[1,3],[3,0]] ], 'P1':[ [(1,), (-1,)], [[0],[1]] ], 'P4_11169_resolved':[ [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1), (-9, -6, -1, -1), (-3, -2, 0, 0)], [[0, 1, 2, 3], [0, 1, 3, 4], [0, 1, 2, 4], [1, 3, 4, 5], [0, 3, 4, 5], [1, 2, 4, 5], [0, 2, 4, 5], [1, 2, 3, 5], [0, 2, 3, 5]] ], 'P4_11133':[ [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1), (-3, -3, -1, -1)], [[0,1,2,3],[0,1,2,4],[0,1,3,4],[0,2,3,4],[1,2,3,4]] ], 'P4_11133_resolved':[ [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1), (-3, -3, -1, -1), (-1, -1, 0, 0)], [[0, 1, 2, 3], [0, 1, 3, 4], [0, 1, 2, 4], [1, 3, 4, 5], [0, 3, 4, 5], [1, 2, 4, 5], [0, 2, 4, 5], [1, 2, 3, 5], [0, 2, 3, 5]] ] } """ return self._make_CPRFanoToricVariety('P1xP1', names) def P1xP1_Z2(self, names='s t x y'): r""" Construct the toric \mathbb{Z}_2-orbifold of the del Pezzo surface \mathbb{P}^1 \times \mathbb{P}^1 as a toric variety. INPUT: - names -- string. Names for the homogeneous coordinates. See :func:~sage.schemes.generic.toric_variety.normalize_names for acceptable formats. OUTPUT: A :class:CPR-Fano toric variety . EXAMPLES:: sage: P1xP1_Z2 = toric_varieties.P1xP1_Z2() sage: P1xP1_Z2 2-d CPR-Fano toric variety covered by 4 affine patches sage: P1xP1_Z2.fan().ray_matrix() [ 1 -1 -1  1] [ 1 -1  1 -1] sage: P1xP1_Z2.gens() (s, t, x, y) sage: P1xP1_Z2.Chow_group().degree(1) C2 x Z^2 """ return self._make_CPRFanoToricVariety('P1xP1_Z2', names) def P1(self, names='s t'): r""" Construct the projective line \mathbb{P}^1 as a toric """ return self._make_CPRFanoToricVariety('P4_11169_resolved', names) def P4_11133(self, names='z+'): """ Construct the weighted projective space \mathbb{P}^4(1,1,1,3,3). INPUT: - names -- string. Names for the homogeneous coordinates. See :func:~sage.schemes.generic.toric_variety.normalize_names for acceptable formats. OUTPUT: A :class:CPR-Fano toric variety . EXAMPLES:: sage: P4_11133 = toric_varieties.P4_11133() sage: P4_11133 4-d CPR-Fano toric variety covered by 5 affine patches sage: P4_11133.fan().ray_matrix() [ 1  0  0  0 -3] [ 0  1  0  0 -3] [ 0  0  1  0 -1] [ 0  0  0  1 -1] sage: P4_11133.gens() (z0, z1, z2, z3, z4) """ return self._make_CPRFanoToricVariety('P4_11133', names) def P4_11133_resolved(self, names='z+'): """ Construct the weighted projective space \mathbb{P}^4(1,1,1,3,3). INPUT: - names -- string. Names for the homogeneous coordinates. See :func:~sage.schemes.generic.toric_variety.normalize_names for acceptable formats. OUTPUT: A :class:CPR-Fano toric variety `. EXAMPLES:: sage: P4_11133_resolved = toric_varieties.P4_11133_resolved() sage: P4_11133_resolved 4-d CPR-Fano toric variety covered by 9 affine patches sage: P4_11133_resolved.fan().ray_matrix() [ 1  0  0  0 -3 -1] [ 0  1  0  0 -3 -1] [ 0  0  1  0 -1  0] [ 0  0  0  1 -1  0] sage: P4_11133_resolved.gens() (z0, z1, z2, z3, z4, z5) """ return self._make_CPRFanoToricVariety('P4_11133_resolved', names) toric_varieties = ToricVarietyFactory()