This module provides support for (normal) toric varieties, corresponding to rational polyhedral fans. See also 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!
The interface to this module is provided through functions AffineToricVariety() and ToricVariety(), although you may also be interested in normalize_names().
Note
We do NOT build “general toric varieties” from affine toric varieties. Instead, we are using the quotient representation of toric varieties with the homogeneous coordinate ring (a.k.a. Cox’s ring or the total coordinate ring). This description works best for simplicial fans of the full dimension.
REFERENCES:
[CLS] | David A. Cox, John B. Little, Hal Schenck, “Toric Varieties”, Graduate Studies in Mathematics, Amer. Math. Soc., Providence, RI, to appear. |
AUTHORS:
EXAMPLES:
We start with constructing the affine plane as an affine toric variety. First, we need to have a corresponding cone:
sage: quadrant = Cone([(1,0), (0,1)])
If you don’t care about variable names and the base field, that’s all we need for now:
sage: A2 = AffineToricVariety(quadrant)
sage: A2
2-d affine toric variety
sage: origin = A2(0,0)
sage: origin
[0 : 0]
Only affine toric varieties have points whose (homogeneous) coordinates are all zero.
sage: parent(origin)
Set of Rational Points of 2-d affine toric variety
As you can see, by default toric varieties live over the field of rational numbers:
sage: A2.base_ring()
Rational Field
While usually toric varieties are considered over the field of complex numbers, for computational purposes it is more convenient to work with fields that have exact representation on computers. You can also always do
sage: C2 = AffineToricVariety(quadrant, base_field=CC)
sage: C2.base_ring()
Complex Field with 53 bits of precision
sage: C2(1,2+i)
[1.00000000000000 : 2.00000000000000 + 1.00000000000000*I]
or even
sage: F = CC["a, b"].fraction_field()
sage: F.inject_variables()
Defining a, b
sage: A2 = AffineToricVariety(quadrant, base_field=F)
sage: A2(a,b)
[a : b]
OK, if you need to work only with affine spaces, AffineSpace() may be a better way to construct them. Our next example is the product of two projective lines realized as the toric variety associated to the face fan of the “diamond”:
sage: diamond = lattice_polytope.octahedron(2)
sage: diamond.vertices()
[ 1 0 -1 0]
[ 0 1 0 -1]
sage: fan = FaceFan(diamond)
sage: P1xP1 = ToricVariety(fan)
sage: P1xP1
2-d toric variety covered by 4 affine patches
sage: P1xP1.fan().ray_matrix()
[ 1 0 -1 0]
[ 0 1 0 -1]
sage: P1xP1.gens()
(z0, z1, z2, z3)
We got four coordinates - two for each of the projective lines, but their
names are perhaps not very well chosen. Let’s make to be coordinates
on the first line and
on the second one:
sage: P1xP1 = ToricVariety(fan, coordinate_names="x s y t")
sage: P1xP1.gens()
(x, s, y, t)
Now, if we want to define subschemes of this variety, the defining polynomials must be homogeneous in each of these pairs:
sage: P1xP1.inject_variables()
Defining x, s, y, t
sage: P1xP1.subscheme(x)
Closed subscheme of 2-d toric variety
covered by 4 affine patches defined by:
x
sage: P1xP1.subscheme(x^2 + y^2)
Closed subscheme of 2-d toric variety
covered by 4 affine patches defined by:
x^2 + y^2
sage: P1xP1.subscheme(x^2 + s^2)
Traceback (most recent call last):
...
ValueError: x^2 + s^2 is not homogeneous
on 2-d toric variety covered by 4 affine patches!
sage: P1xP1.subscheme([x^2*s^2 + x*y*t^2 +y^2*t^2, s^3 + t^3])
Closed subscheme of 2-d toric variety
covered by 4 affine patches defined by:
x^2*s^2 + x*y*t^2 + y^2*t^2,
s^3 + t^3
While we don’t build toric varieties from affine toric varieties, we still can access the “building pieces”:
sage: patch = P1xP1.affine_patch(2)
sage: patch
2-d affine toric variety
sage: patch.fan().ray_matrix()
[1 0]
[0 1]
sage: patch.embedding_morphism()
Scheme morphism:
From: 2-d affine toric variety
To: 2-d toric variety covered by 4 affine patches
Defn: Defined on coordinates by sending [x : s] to
[x : s : 1 : 1]
The patch above was specifically chosen to coincide with our representation of the affine plane before, but you can get the other three patches as well. (While any cone of a fan will correspond to an affine toric variety, the main interest is usually in the generating fans as “the biggest” affine subvarieties, and these are precisely the patches that you can get from affine_patch().)
All two-dimensional toric varieties are “quite nice” because any two-dimensional cone is generated by exactly two rays. From the point of view of the corresponding toric varieties, this means that they have at worst quotient singularities:
sage: P1xP1.is_orbifold()
True
sage: P1xP1.is_smooth()
True
sage: TV = ToricVariety(NormalFan(diamond))
sage: TV.fan().ray_matrix()
[-1 1 -1 1]
[ 1 1 -1 -1]
sage: TV.is_orbifold()
True
sage: TV.is_smooth()
False
In higher dimensions worse things can happen:
sage: TV3 = ToricVariety(NormalFan(lattice_polytope.octahedron(3)))
sage: TV3.fan().ray_matrix()
[-1 1 -1 1 -1 1 -1 1]
[-1 -1 1 1 -1 -1 1 1]
[ 1 1 1 1 -1 -1 -1 -1]
sage: TV3.is_orbifold()
False
Fortunately, we can perform a (partial) resolution:
sage: TV3_res = TV3.resolve_to_orbifold()
sage: TV3_res.is_orbifold()
True
sage: TV3_res.fan().ngenerating_cones()
12
sage: TV3.fan().ngenerating_cones()
6
In this example we had to double the number of affine patches. The result is still singular:
sage: TV3_res.is_smooth()
False
You can resolve it further using resolve() method, but (at least for now) you will have to specify which rays should be inserted into the fan. See also CPRFanoToricVariety(), which can construct some other “nice partial resolutions.”
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 development and hopefully will improve in future releases of Sage. If there are some particular features that you would like to see implemented ASAP, please consider reporting them to the Sage Development Team or even implementing them on your own as a patch for inclusion!
Construct an affine toric variety.
INPUT:
This cone will be used to construct a rational polyhedral fan, which will be passed to ToricVariety() with the rest of positional and keyword arguments.
OUTPUT:
Note
The generating rays of the fan of this variety are guaranteed to be listed in the same order as the rays of the original cone.
EXAMPLES:
We will create the affine plane as an affine toric variety:
sage: quadrant = Cone([(1,0), (0,1)])
sage: A2 = AffineToricVariety(quadrant)
sage: origin = A2(0,0)
sage: origin
[0 : 0]
sage: parent(origin)
Set of Rational Points of 2-d affine toric variety
Only affine toric varieties have points whose (homogeneous) coordinates are all zero.
Bases: sage.rings.quotient_ring_element.QuotientRingElement
An element of the CohomologyRing.
Warning
You should not create instances of this class manually. The generators of the cohomology ring as well as the cohomology classes associated to cones of the fan can be obtained from ToricVariety_field.cohomology_ring().
EXAMPLES:
sage: P2 = toric_varieties.P2()
sage: P2.cohomology_ring().gen(0)
[z]
sage: HH = P2.cohomology_ring()
sage: HH.gen(0)
[z]
sage: cone = P2.fan(1)[0]; HH(cone)
[z]
The degree of the cohomology class.
OUTPUT:
An integer such that the cohomology class is in degree
. If the cohomology class is of mixed degree, the highest
degree is returned.
EXAMPLES:
sage: P2 = toric_varieties.P2()
sage: P2.cohomology_ring().gen(0).deg()
1
sage: P2.cohomology_ring().zero().deg()
-1
Exponentiate self.
Note
The exponential of a rational number
is
usually not rational. Therefore, the cohomology class must
not have a constant (degree zero) part. The coefficients
in the Taylor series of
are rational, so any
cohomology class without constant term can be
exponentiated.
OUTPUT
The cohomology class self
if the constant part
vanishes, otherwise a ValueError is raised.
EXAMPLES:
sage: P2 = toric_varieties.P2()
sage: H_class = P2.cohomology_ring().gen(0)
sage: H_class
[z]
sage: H_class.exp()
[1/2*z^2 + z + 1]
Project the (mixed-degree) cohomology class to the given degree.
INPUT:
OUTPUT:
EXAMPLES:
sage: P1xP1 = toric_varieties.P1xP1()
sage: t = P1xP1.cohomology_ring().gen(0)
sage: y = P1xP1.cohomology_ring().gen(2)
sage: 3*t+4*t^2*y+y+t*y+t+1
[t*y + 4*t + y + 1]
sage: (3*t+4*t^2*y+y+t*y+t+1).part_of_degree(1)
[4*t + y]
Bases: sage.rings.quotient_ring.QuotientRing_generic, sage.structure.unique_representation.UniqueRepresentation
The (even) cohomology ring of a toric variety.
Irregardles of the variety’s base ring, we always work with the
variety over and its topology.
The cohomology is always the singular cohomology with
-coefficients. Note, however, that the cohomology of smooth
toric varieties is torsion-free, so there is no loss of
information in that case.
Currently, the toric variety must not be “too singular”. See ToricVariety_field.cohomology_ring() for a detailed description of which toric varieties are admissible. For such varieties the odd-dimensional cohomology groups vanish.
Warning
You should not create instances of this class manually. Use ToricVariety_field.cohomology_ring() to generate the cohomology ring.
INPUT:
EXAMPLES:
sage: P2 = toric_varieties.P2()
sage: P2.cohomology_ring()
Rational cohomology ring of a 2-d CPR-Fano toric variety covered by 3 affine patches
This is equivalent to:
sage: from sage.schemes.generic.toric_variety import CohomologyRing
sage: CohomologyRing(P2)
Rational cohomology ring of a 2-d CPR-Fano toric variety covered by 3 affine patches
Return the generators of the cohomology ring.
INPUT:
OUTPUT:
The i-th generator of the cohomology ring. If we denote the toric variety by X, then this generator is associated to the ray X.fan().ray(i), which spans the one-cone X.fan(1)[i]
EXAMPLES:
sage: P2 = toric_varieties.P2()
sage: P2.cohomology_ring().gen(2)
[z]
Return the generators of the cohomology ring.
OUTPUT:
A tuple of generators, one for each toric divisor of the toric variety X. The order is the same as the ordering of the rays of the fan X.fan().rays(), which is also the same as the ordering of the one-cones in X.fan(1)
EXAMPLES:
sage: P2 = toric_varieties.P2()
sage: P2.cohomology_ring().gens()
([z], [z], [z])
Construct a toric variety.
INPUT:
OUTPUT:
EXAMPLES:
We will create the product of two projective lines:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: fan.ray_matrix()
[ 1 0 -1 0]
[ 0 1 0 -1]
sage: P1xP1 = ToricVariety(fan)
sage: P1xP1.gens()
(z0, z1, z2, z3)
Let’s create some points:
sage: P1xP1(1,1,1,1)
[1 : 1 : 1 : 1]
sage: P1xP1(0,1,1,1)
[0 : 1 : 1 : 1]
sage: P1xP1(0,1,0,1)
Traceback (most recent call last):
...
TypeError: coordinates (0, 1, 0, 1)
are in the exceptional set!
We cannot set to zero both coordinates of the same projective line!
Let’s change the names of the variables. We have to re-create our toric variety:
sage: P1xP1 = ToricVariety(fan, "x s y t")
sage: P1xP1.gens()
(x, s, y, t)
Now correspond to one line and
to the other one.
sage: P1xP1.inject_variables()
Defining x, s, y, t
sage: P1xP1.subscheme(x*s-y*t)
Closed subscheme of 2-d toric variety
covered by 4 affine patches defined by:
x*s - y*t
Bases: sage.schemes.generic.ambient_space.AmbientSpace
Construct a toric variety associated to a rational polyhedral fan.
Warning
This class does not perform any checks of correctness of input. Use ToricVariety() and AffineToricVariety() to construct toric varieties.
INPUT:
OUTPUT:
TESTS:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan)
Return the Chern character (of the tangent bundle) of the toric variety.
INPUT:
OUTPUT:
REFERENCES:
EXAMPLES:
sage: dP6 = toric_varieties.dP6()
sage: dP6.Chern_character()
[3*w^2 + y + 2*v + 2*z + w + 2]
sage: dP6.ch()
[3*w^2 + y + 2*v + 2*z + w + 2]
sage: dP6.ch(1) == dP6.c(1)
True
Return Chern classes of the (tangent bundle of the) toric variety.
INPUT:
OUTPUT:
REFERENCES:
EXAMPLES:
sage: X = toric_varieties.dP6()
sage: X.Chern_class()
[-6*w^2 + y + 2*v + 2*z + w + 1]
sage: X.c()
[-6*w^2 + y + 2*v + 2*z + w + 1]
sage: X.c(1)
[y + 2*v + 2*z + w]
sage: X.c(2)
[-6*w^2]
sage: X.integrate( X.c(2) )
6
sage: X.integrate( X.c(2) ) == X.Euler_number()
True
Return the toric Chow group.
INPUT:
OUTPUT:
A sage.schemes.generic.toric_chow_group.ChowGroup_class
EXAMPLES:
sage: A = toric_varieties.P2().Chow_group(); A
Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches
sage: A.gens()
(( 1 | 0 | 0 ), ( 0 | 1 | 0 ), ( 0 | 0 | 1 ))
Return the topological Euler number of the toric variety.
Sometimes, this is also called the Euler characteristic. chi() is a synonym for Euler_number().
REFERENCES:
EXAMPLES:
sage: P1xP1 = toric_varieties.P1xP1()
sage: P1xP1.Euler_number()
4
sage: P1xP1.chi()
4
Returns the canonical divisor of the toric variety.
EXAMPLES:
Lets test that the del Pezzo surface has degree 6, as its name implies:
sage: dP6 = toric_varieties.dP6()
sage: HH = dP6.cohomology_ring()
sage: dP6.K()
-V(x) - V(u) - V(y) - V(v) - V(z) - V(w)
sage: dP6.integrate( HH(dP6.K())^2 )
6
Return the closure of the Kähler cone of self.
OUTPUT:
Note
This cone sits in the rational divisor class group of self and the choice of coordinates agrees with rational_class_group().
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan)
sage: Kc = P1xP1.Kaehler_cone()
sage: Kc
2-d cone in 2-d lattice
sage: Kc.rays()
(Divisor class [0, 1], Divisor class [1, 0])
sage: [ divisor_class.lift() for divisor_class in Kc.rays() ]
[V(z1), V(z0)]
sage: Kc.lattice()
The toric rational divisor class group
of a 2-d toric variety covered by 4 affine patches
Returns the Mori cone of self.
OUTPUT:
Note
EXAMPLES:
sage: P4_11169 = toric_varieties.P4_11169_resolved()
sage: P4_11169.Mori_cone()
2-d cone in 7-d lattice
sage: P4_11169.Mori_cone().rays()
((3, 2, 0, 0, 0, 1, -6), (0, 0, 1, 1, 1, -3, 0))
Return the Stanley-Reisner ideal.
OUTPUT:
EXAMPLES:
sage: fan = Fan([[0,1,3],[3,4],[2,0],[1,2,4]], [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)])
sage: X = ToricVariety(fan, coordinate_names='A B C D E', base_field=GF(5))
sage: SR = X.Stanley_Reisner_ideal(); SR
Ideal (A*E, C*D, A*B*C, B*D*E) of Multivariate Polynomial Ring in A, B, C, D, E over Rational Field
Return the Todd class (of the tangent bundle) of the toric variety.
INPUT:
OUTPUT:
REFERENCES:
EXAMPLES:
sage: dP6 = toric_varieties.dP6()
sage: dP6.Todd_class()
[-w^2 + 1/2*y + v + z + 1/2*w + 1]
sage: dP6.Td()
[-w^2 + 1/2*y + v + z + 1/2*w + 1]
sage: dP6.integrate( dP6.Td() )
1
Return the Todd class (of the tangent bundle) of the toric variety.
INPUT:
OUTPUT:
REFERENCES:
EXAMPLES:
sage: dP6 = toric_varieties.dP6()
sage: dP6.Todd_class()
[-w^2 + 1/2*y + v + z + 1/2*w + 1]
sage: dP6.Td()
[-w^2 + 1/2*y + v + z + 1/2*w + 1]
sage: dP6.integrate( dP6.Td() )
1
Return the i-th affine patch of self.
INPUT:
OUTPUT:
The result is cached, so the i-th patch is always the same object in memory.
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan, "x s y t")
sage: patch0 = P1xP1.affine_patch(0)
sage: patch0
2-d affine toric variety
sage: patch0.embedding_morphism()
Scheme morphism:
From: 2-d affine toric variety
To: 2-d toric variety covered by 4 affine patches
Defn: Defined on coordinates by sending [x : t] to
[x : 1 : 1 : t]
sage: patch1 = P1xP1.affine_patch(1)
sage: patch1.embedding_morphism()
Scheme morphism:
From: 2-d affine toric variety
To: 2-d toric variety covered by 4 affine patches
Defn: Defined on coordinates by sending [y : t] to
[1 : 1 : y : t]
sage: patch1 is P1xP1.affine_patch(1)
True
Return Chern classes of the (tangent bundle of the) toric variety.
INPUT:
OUTPUT:
REFERENCES:
EXAMPLES:
sage: X = toric_varieties.dP6()
sage: X.Chern_class()
[-6*w^2 + y + 2*v + 2*z + w + 1]
sage: X.c()
[-6*w^2 + y + 2*v + 2*z + w + 1]
sage: X.c(1)
[y + 2*v + 2*z + w]
sage: X.c(2)
[-6*w^2]
sage: X.integrate( X.c(2) )
6
sage: X.integrate( X.c(2) ) == X.Euler_number()
True
Return the Cartesian product of self with other.
INPUT:
OUTPUT:
– a toric variety.
EXAMPLES:
sage: P1 = ToricVariety(Fan([Cone([(1,)]), Cone([(-1,)])]))
sage: P1xP1 = P1.cartesian_product(P1); P1xP1
2-d toric variety covered by 4 affine patches
sage: P1xP1.fan().rays()
(N+N(-1, 0), N+N(1, 0), N+N(0, -1), N+N(0, 1))
Return the Chern character (of the tangent bundle) of the toric variety.
INPUT:
OUTPUT:
REFERENCES:
EXAMPLES:
sage: dP6 = toric_varieties.dP6()
sage: dP6.Chern_character()
[3*w^2 + y + 2*v + 2*z + w + 2]
sage: dP6.ch()
[3*w^2 + y + 2*v + 2*z + w + 2]
sage: dP6.ch(1) == dP6.c(1)
True
Return a toric variety over F and otherwise the same as self.
INPUT:
OUTPUT:
Note
There is no need to have any relation between F and the base field of self. If you do want to have such a relation, use base_extend() instead.
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan)
sage: P1xP1.base_ring()
Rational Field
sage: P1xP1_RR = P1xP1.change_ring(RR)
sage: P1xP1_RR.base_ring()
Real Field with 53 bits of precision
sage: P1xP1_QQ = P1xP1_RR.change_ring(QQ)
sage: P1xP1_QQ.base_ring()
Rational Field
sage: P1xP1_RR.base_extend(QQ)
Traceback (most recent call last):
...
ValueError: no natural map from the base ring
(=Real Field with 53 bits of precision)
to R (=Rational Field)!
Return the topological Euler number of the toric variety.
Sometimes, this is also called the Euler characteristic. chi() is a synonym for Euler_number().
REFERENCES:
EXAMPLES:
sage: P1xP1 = toric_varieties.P1xP1()
sage: P1xP1.Euler_number()
4
sage: P1xP1.chi()
4
Return a basis for the cohomology of the toric variety.
INPUT:
OUTPUT:
EXAMPLES:
sage: X = toric_varieties.dP8()
sage: X.cohomology_basis()
(([1],), ([z], [y]), ([y*z],))
sage: X.cohomology_basis(1)
([z], [y])
sage: X.cohomology_basis(dimension(X))[0] == X.volume_class()
True
Return the cohomology ring of the toric variety.
OUTPUT:
Note
EXAMPLES:
sage: X = toric_varieties.dP6()
sage: X.cohomology_ring()
Rational cohomology ring of a 2-d CPR-Fano toric variety covered by 6 affine patches
sage: X.cohomology_ring().defining_ideal()
Ideal (-u - y + z + w, x - y - v + w, x*y, x*v, x*z, u*v, u*z, u*w, y*z, y*w, v*w) of Multivariate Polynomial Ring in x, u, y, v, z, w over Rational Field
sage: X.cohomology_ring().defining_ideal().ring()
Multivariate Polynomial Ring in x, u, y, v, z, w over Rational Field
sage: X.variable_names()
('x', 'u', 'y', 'v', 'z', 'w')
sage: X.cohomology_ring().gens()
([y + v - w], [-y + z + w], [y], [v], [z], [w])
Return the coordinate ring of self.
For toric varieties this is the homogeneous coordinate ring (a.k.a. Cox’s ring and total ring).
OUTPUT:
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan)
sage: P1xP1.coordinate_ring()
Multivariate Polynomial Ring in z0, z1, z2, z3
over Rational Field
Return a divisor.
INPUT:
The arguments are the same as in sage.schemes.generic.toric_divisor.ToricDivisor().
OUTPUT:
EXAMPLES:
sage: dP6 = toric_varieties.dP6()
sage: dP6.coordinate_ring()
Multivariate Polynomial Ring in x, u, y, v, z, w over Rational Field
sage: dP6.divisor(0)
V(x)
sage: for i in range(0,dP6.fan().nrays()): print dP6.divisor(i), ': generated by ray', dP6.fan().ray(i)
...
V(x) : generated by ray N(0, 1)
V(u) : generated by ray N(-1, 0)
V(y) : generated by ray N(-1, -1)
V(v) : generated by ray N(0, -1)
V(z) : generated by ray N(1, 0)
V(w) : generated by ray N(1, 1)
Return the group of Weil divisors.
INPUT:
OUTPUT:
The (free abelian) group of Cartier divisors, that is, formal linear combinations of polynomial equations over the coefficient ring base_ring.
These need not be toric (=defined by monomials), but allow general polynomials. The output will be an instance of sage.schemes.generic.divisor_group.DivisorGroup_generic.
Warning
You almost certainly want the group of toric divisors, see toric_divisor_group(). The toric divisor group is generated by the rays of the fan. The general divisor group has no toric functionality implemented.
EXAMPLES:
sage: dP6 = toric_varieties.dP6()
sage: Div = dP6.divisor_group(); Div
Group of ZZ-Divisors on 2-d CPR-Fano toric variety
covered by 6 affine patches
sage: Div(x)
V(x)
Return the default embedding morphism of self.
Such a morphism is always defined for an affine patch of a toric variety (which is also a toric varieties itself).
OUTPUT:
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan, "x s y t")
sage: P1xP1.embedding_morphism()
Traceback (most recent call last):
...
ValueError: no default embedding was
defined for this toric variety!
sage: patch = P1xP1.affine_patch(0)
sage: patch
2-d affine toric variety
sage: patch.embedding_morphism()
Scheme morphism:
From: 2-d affine toric variety
To: 2-d toric variety covered by 4 affine patches
Defn: Defined on coordinates by sending [x : t] to
[x : 1 : 1 : t]
Return the underlying fan of self or its cones.
INPUT:
OUTPUT:
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan)
sage: P1xP1.fan()
Rational polyhedral fan in 2-d lattice N
sage: P1xP1.fan() is fan
True
sage: P1xP1.fan(1)[0]
1-d cone of Rational polyhedral fan in 2-d lattice N
Inject generators of the base field of self into scope.
This function is useful if the base field is the field of rational functions.
INPUT:
OUTPUT:
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: F = QQ["a, b"].fraction_field()
sage: P1xP1 = ToricVariety(fan, base_field=F)
sage: P1xP1.inject_coefficients()
Defining a, b
We check that we can use names a and b, Trac #10498 is fixed:
sage: a + b
a + b
sage: a + b in P1xP1.coordinate_ring()
True
Integrate a cohomology class over the toric variety.
INPUT:
OUTPUT:
The integral of the cohomology class over the variety. The volume normalization is given by volume_class(), that is, self.integrate(self.volume_class()) is always one (if the volume class exists).
EXAMPLES:
sage: dP6 = toric_varieties.dP6()
sage: HH = dP6.cohomology_ring()
sage: D = [ HH(c) for c in dP6.fan(dim=1) ]
sage: matrix([ [ D[i]*D[j] for i in range(0,6) ] for j in range(0,6) ])
[ [w^2] [-w^2] [0] [0] [0] [-w^2]]
[[-w^2] [w^2] [-w^2] [0] [0] [0]]
[ [0] [-w^2] [w^2] [-w^2] [0] [0]]
[ [0] [0] [-w^2] [w^2] [-w^2] [0]]
[ [0] [0] [0] [-w^2] [w^2] [-w^2]]
[[-w^2] [0] [0] [0] [-w^2] [w^2]]
sage: matrix([ [ dP6.integrate(D[i]*D[j]) for i in range(0,6) ] for j in range(0,6) ])
[-1 1 0 0 0 1]
[ 1 -1 1 0 0 0]
[ 0 1 -1 1 0 0]
[ 0 0 1 -1 1 0]
[ 0 0 0 1 -1 1]
[ 1 0 0 0 1 -1]
Check if self is complete.
OUTPUT:
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan)
sage: P1xP1.is_complete()
True
sage: P1xP1.affine_patch(0).is_complete()
False
Check if polynomial is homogeneous.
The coordinate ring of a toric variety is multigraded by relations between generating rays of the underlying fan.
INPUT:
OUTPUT:
EXAMPLES:
We will use the product of two projective lines with coordinates
for one and
for the other:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: fan.ray_matrix()
[ 1 0 -1 0]
[ 0 1 0 -1]
sage: P1xP1 = ToricVariety(fan, "x s y t")
sage: P1xP1.inject_variables()
Defining x, s, y, t
sage: P1xP1.is_homogeneous(x - y)
True
sage: P1xP1.is_homogeneous(x*s + y*t)
True
sage: P1xP1.is_homogeneous(x - t)
False
sage: P1xP1.is_homogeneous(1)
True
Check if self is isomorphic to another.
INPUT:
OUTPUT:
EXAMPLES:
sage: fan1 = FaceFan(lattice_polytope.octahedron(2))
sage: TV1 = ToricVariety(fan1)
sage: fan2 = NormalFan(lattice_polytope.octahedron(2))
sage: TV2 = ToricVariety(fan2)
Only the most trivial case is implemented so far:
sage: TV1.is_isomorphic(TV1)
True
sage: TV1.is_isomorphic(TV2)
Traceback (most recent call last):
...
NotImplementedError:
isomorphism check is not yet implemented!
Check if self has only quotient singularities.
OUTPUT:
EXAMPLES:
sage: fan1 = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan1)
sage: P1xP1.is_orbifold()
True
sage: fan2 = NormalFan(lattice_polytope.octahedron(3))
sage: TV = ToricVariety(fan2)
sage: TV.is_orbifold()
False
Check if self is smooth.
OUTPUT:
EXAMPLES:
sage: diamond = lattice_polytope.octahedron(2)
sage: fan1 = FaceFan(diamond)
sage: P1xP1 = ToricVariety(fan1)
sage: P1xP1.is_smooth()
True
sage: fan2 = NormalFan(lattice_polytope.octahedron(2))
sage: TV = ToricVariety(fan2)
sage: TV.is_smooth()
False
Return the ideal generated by linear relations
OUTPUT:
EXAMPLES:
sage: fan = Fan([[0,1,3],[3,4],[2,0],[1,2,4]], [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)])
sage: X = ToricVariety(fan, coordinate_names='A B C D E', base_field=GF(5))
sage: lin = X.linear_equivalence_ideal(); lin
Ideal (-3*A + 3*C - D + E, -2*A - 2*C - D - E, A + B + C + D + E) of Multivariate Polynomial Ring in A, B, C, D, E over Rational Field
Plot self, i.e. the corresponding fan.
INPUT:
OUTPUT:
Note
The difference between X.plot() and X.fan().plot() is that in the first case default ray labels correspond to variables of X.
EXAMPLES:
sage: X = toric_varieties.Cube_deformation(4)
sage: X.plot()
Return the rational divisor class group of self.
Let be a toric variety.
The Weil divisor class group is a finitely
generated abelian group and can contain torsion. Its rank equals the
number of rays in the fan of
minus the dimension of
.
The rational divisor class group is
and never includes torsion. If
is
smooth, this equals the Picard group of
, whose elements are
the isomorphism classes of line bundles on
. The group law (which
we write as addition) is the tensor product of the line bundles. The
Picard group of a toric variety is always torsion-free.
OUTPUT:
Note
EXAMPLES:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P1xP1 = ToricVariety(fan)
sage: P1xP1.rational_class_group()
The toric rational divisor class group
of a 2-d toric variety covered by 4 affine patches
Construct a toric variety whose fan subdivides the fan of self.
The name of this function reflects the fact that usually such subdivisions are done for resolving singularities of the original variety.
INPUT:
This function accepts only keyword arguments, none of which are mandatory.
OUTPUT:
EXAMPLES:
First we will “manually” resolve a simple orbifold singularity:
sage: cone = Cone([(1,1), (-1,1)])
sage: fan = Fan([cone])
sage: TV = ToricVariety(fan)
sage: TV.is_smooth()
False
sage: TV_res = TV.resolve(new_rays=[(0,1)])
sage: TV_res.is_smooth()
True
sage: TV_res.fan().ray_matrix()
[ 1 -1 0]
[ 1 1 1]
sage: [cone.ambient_ray_indices() for cone in TV_res.fan()]
[(0, 2), (1, 2)]
Now let’s “automatically” partially resolve a more complicated fan:
sage: fan = NormalFan(lattice_polytope.octahedron(3))
sage: TV = ToricVariety(fan)
sage: TV.is_smooth()
False
sage: TV.is_orbifold()
False
sage: TV.fan().nrays()
8
sage: TV.fan().ngenerating_cones()
6
sage: TV_res = TV.resolve(make_simplicial=True)
sage: TV_res.is_smooth()
False
sage: TV_res.is_orbifold()
True
sage: TV_res.fan().nrays()
8
sage: TV_res.fan().ngenerating_cones()
12
sage: TV.gens()
(z0, z1, z2, z3, z4, z5, z6, z7)
sage: TV_res.gens()
(z0, z1, z2, z3, z4, z5, z6, z7)
sage: TV_res = TV.resolve(coordinate_names="x+",
... make_simplicial=True)
sage: TV_res.gens()
(x0, x1, x2, x3, x4, x5, x6, x7)
Construct an orbifold whose fan subdivides the fan of self.
It is a synonym for resolve() with make_simplicial=True option.
INPUT:
OUTPUT:
EXAMPLES:
sage: fan = NormalFan(lattice_polytope.octahedron(3))
sage: TV = ToricVariety(fan)
sage: TV.is_orbifold()
False
sage: TV.fan().nrays()
8
sage: TV.fan().ngenerating_cones()
6
sage: TV_res = TV.resolve_to_orbifold()
sage: TV_res.is_orbifold()
True
sage: TV_res.fan().nrays()
8
sage: TV_res.fan().ngenerating_cones()
12
Return the subscheme of self defined by polynomials.
INPUT:
OUTPUT:
EXAMPLES:
We will construct a subscheme of the product of two projective lines
with coordinates for one and
for the other:
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: fan.ray_matrix()
[ 1 0 -1 0]
[ 0 1 0 -1]
sage: P1xP1 = ToricVariety(fan, "x s y t")
sage: P1xP1.inject_variables()
Defining x, s, y, t
sage: X = P1xP1.subscheme([x*s + y*t, x^3+y^3])
sage: X
Closed subscheme of 2-d toric variety
covered by 4 affine patches defined by:
x*s + y*t,
x^3 + y^3
sage: X.defining_polynomials()
(x*s + y*t, x^3 + y^3)
sage: X.defining_ideal()
Ideal (x*s + y*t, x^3 + y^3)
of Multivariate Polynomial Ring in x, s, y, t
over Rational Field
sage: X.base_ring()
Rational Field
sage: X.base_scheme()
Spectrum of Rational Field
sage: X.structure_morphism()
Scheme morphism:
From: Closed subscheme of
2-d toric variety covered by 4 affine patches defined by:
x*s + y*t,
x^3 + y^3
To: Spectrum of Rational Field
Defn: Structure map
Return the group of toric (T-Weil) divisors.
INPUT:
OUTPUT:
The free Abelian agroup of toric Weil divisors, that is, formal base_ring-linear combinations of codimension-one toric subvarieties. The output will be an instance of sage.schemes.generic.toric_divisor.ToricDivisorGroup.
The -th generator of the divisor group is the divisor where
the
-th homogeneous coordinate vanishes,
.
EXAMPLES:
sage: dP6 = toric_varieties.dP6()
sage: TDiv = dP6.toric_divisor_group(); TDiv
Group of toric ZZ-Weil divisors on 2-d CPR-Fano toric variety
covered by 6 affine patches
sage: TDiv == dP6.toric_divisor_group()
True
sage: TDiv.gens()
(V(x), V(u), V(y), V(v), V(z), V(w))
sage: dP6.coordinate_ring()
Multivariate Polynomial Ring in x, u, y, v, z, w over Rational Field
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
varieties the volume form does not define a cohomology class.
OUTPUT:
A CohomologyClass. If it exists, it is the class of 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.
Make sure that names are valid in Python.
INPUT:
OUTPUT:
Each name must satisfy the following requirements:
In addition, all names must be distinct.
EXAMPLES:
sage: from sage.schemes.generic.toric_variety import certify_names
sage: certify_names([])
sage: certify_names(["a", "x0", "x_45"])
sage: certify_names(["", "x0", "x_45"])
Traceback (most recent call last):
...
ValueError: name must be nonempty!
sage: certify_names(["a", "0", "x_45"])
Traceback (most recent call last):
...
ValueError: name must start with a letter! Got 0
sage: certify_names(["a", "x0", "@_45"])
Traceback (most recent call last):
...
ValueError: name must be alphanumeric! Got @_45
sage: certify_names(["a", "x0", "x0"])
Traceback (most recent call last):
...
ValueError: names must be distinct! Got: ['a', 'x0', 'x0']
Check whether x is a cohomology class of a toric variety.
INPUT:
OUTPUT:
True or False depending on whether x is an instance of CohomologyClass
EXAMPLES:
sage: P2 = toric_varieties.P2()
sage: HH = P2.cohomology_ring()
sage: from sage.schemes.generic.toric_variety import is_CohomologyClass
sage: is_CohomologyClass( HH.one() )
True
sage: is_CohomologyClass( HH(P2.fan(1)[0]) )
True
sage: is_CohomologyClass('z')
False
Check if x is a toric variety.
INPUT:
OUTPUT:
Note
While projective spaces are toric varieties mathematically, they are not toric varieties in Sage due to efficiency considerations, so this function will return False.
EXAMPLES:
sage: from sage.schemes.generic.toric_variety import is_ToricVariety
sage: is_ToricVariety(1)
False
sage: fan = FaceFan(lattice_polytope.octahedron(2))
sage: P = ToricVariety(fan)
sage: P
2-d toric variety covered by 4 affine patches
sage: is_ToricVariety(P)
True
sage: is_ToricVariety(ProjectiveSpace(2))
False
Return a list of names in the standard form.
INPUT:
All input parameters are optional.
OUTPUT:
These names are constructed in the following way:
EXAMPLES:
As promised, all parameters are optional:
sage: from sage.schemes.generic.toric_variety import normalize_names
sage: normalize_names()
[]
One of the most common uses is probably this one:
sage: normalize_names("x+", 4)
['x0', 'x1', 'x2', 'x3']
Now suppose that you want to enumerate your variables starting with one instead of zero:
sage: normalize_names("x+", 4, indices=range(1,5))
['x1', 'x2', 'x3', 'x4']
You may actually have an arbitrary enumeration scheme:
sage: normalize_names("x+", 4, indices=[1, 10, 100, 1000])
['x1', 'x10', 'x100', 'x1000']
Now let’s add some “explicit” names:
sage: normalize_names("x y z t+", 4)
['x', 'y', 'z', 't3']
Note that the “automatic” name is t3 instead of t0. This may seem weird, but the reason for this behaviour is that the fourth name in this list will be the same no matter how many explicit names were given:
sage: normalize_names("x y t+", 4)
['x', 'y', 't2', 't3']
This is especially useful if you get names from a user but want to specify all default names:
sage: normalize_names("x, y", 4, prefix="t")
['x', 'y', 't2', 't3']
In this format, the user can easily override your choice for automatic names:
sage: normalize_names("x y s+", 4, prefix="t")
['x', 'y', 's2', 's3']
Let’s now use all parameters at once:
sage: normalize_names("x, y, s+", 4, prefix="t",
... indices=range(1,5), return_prefix=True)
['x', 'y', 's3', 's4', 's']
Note that you still need to give indices for all names, even if some of the first ones will be “wasted” because of the explicit names. The reason is the same as before - this ensures consistency of automatically generated names, no matter how many explicit names were given.
The prefix is discarded if ngens was not given:
sage: normalize_names("alpha, beta, gamma, zeta+")
['alpha', 'beta', 'gamma']
Finally, let’s take a look at some possible mistakes:
sage: normalize_names("123")
Traceback (most recent call last):
...
ValueError: name must start with a letter! Got 123
A more subtle one:
sage: normalize_names("x1", 4, prefix="x")
Traceback (most recent call last):
...
ValueError: names must be distinct! Got: ['x1', 'x1', 'x2', 'x3']