<#Include SYSTEM "title.xml">
Introduction
Introduction to the `toric` package

This manual describes the `toric` package for working with toric varieties in &GAP;. Toric varieties can be dealt with more easily than general varieties since often times questions about a toric variety can be reformulated in terms of combinatorial geometry. Some coding theory commands related to toric varieties are contained in the error-correcting codes `GUAVA` package (for example, the command ToricCode). We refer to the `GUAVA` manual and the expository paper for more details.

The `toric` package also contains several commands unrelated to toric varieties (mostly for list manipulations). These will not be described in this documention but they are briefly documented in the lib/util.gd file.

`toric` is implemented in the &GAP; language, and runs on any system supporting &GAP;4.3 and above. The `toric` package is loaded with the command gap> LoadPackage( "toric" );

Please send bug reports, suggestions and other comments about `toric` to support@gap-system.org.
Introduction to constructing toric varieties Rather than sketch the theory of toric varieties, we refer to and for details. However, we briefly describe some terminology and notation. Generalities Let F denote a field and R=F [x_1,...,x_n] be a ring in n variables. A binomial equation in R is one of the form x_1^{k_1}...x_n^{k_n}=x_1^{\ell_1}...x_n^{\ell_n}, where k_i \geq 0,\ \ell_j \geq 0 are integers. A binomial variety is a subvariety of affine n-space A_F^n defined by a finite set of binomial equations (such a variety need not be normal). A typical ``toric variety'' is binomial, though they will be introduced via an a priori independent construction. The basic idea of the construction is to replace each such binomial equation as above by a relation in a semigroup contained in a lattice and replace R by the ``group algebra'' of this semigroup. By the way, a toric variety is always normal (see for example, , page 29). Basic combinatorial geometry constructions Let Q denote the field of rational numbers and Z denote the set of integers. Let n>1 denote an integer.

Let V=Q^n having basis f_1=(1,0,...,0), ..., f_n=(0,...,0,1). Let L_0=Z^n\subset V be the standard lattice in V. We identify V and L_0\otimes_{Z} Q. We use \langle\ ,\ \rangle to denote the (standard) inner product on V. Let L_0^*={\rm Hom}(L_0,Z)=\{ v\in V\ |\ \langle v,w \rangle \in Z, \ \forall w\in L_0\} denote the dual lattice, so (fixing the standard basis e_1^*,...,e_n^* dual to the f_1,...,f_n) L_0^* may be identified with Z^n.

A cone in V is a set \sigma of the form \sigma=\{a_1v_1+...+a_mv_m\ |\ a_i\geq 0\}\subset V, where v_1,...,v_m \in V is a given collection of vectors, called (semigroup) generators of \sigma. A rational cone is one where v_1,...,v_m \in L_0. A strongly convex cone is one which contains no lines through the origin.

By abuse of terminology, from now on a cone of L_0 is a strongly convex rational cone.
cone

A face of a cone \sigma is either \sigma itself or a subset of the form H\cap \sigma, where H is a codimension one subspace of V which intersects the cone non-trivially and such that the cone is contained in exactly one of the two half-spaces determined by H. A ray (or edge) of a cone is a one-dimensional face.
ray
Typically, cones are represented in `toric` by the list of vectors defining their rays. The dimension of a cone is the dimension of the vector space it spans. The `toric` package can test if a given vector is in a given cone (see InsideCone).

If \sigma is a cone then the dual cone is defined by \sigma^* =\{w \in L_0^*\otimes Q \ |\ \langle v,w \rangle \geq 0,\ \forall v\in \sigma\}. The `toric` package can test if a vector is in the dual of a given cone (see InDualCone).
dual cone

Associate to the dual cone \sigma^* is the semigroup S_\sigma =\sigma^*\cap L_0^* =\{w\in L_0^* \ |\ \langle v,w\rangle \geq 0,\ \forall v\in \sigma\}. Though L_0^* has $n$ generators as a lattice, typically S_\sigma will have more than n generators as a semigroup. The `toric` package can compute a minimal list of semigroup generators of S_\sigma (see DualSemigroupGenerators).
semigroup associated to cone

A fan is a collection of cones which ``fit together'' well. A fan in L_0 is a set \Delta=\{\sigma \} of rational strongly convex cones in V= L_0 \otimes Q such that if \sigma \in \Delta and \tau \subset \sigma is a face of \sigma then \tau \in \Delta, if \sigma_1, \sigma_2 \in \Delta then the intersection \sigma_1 \cap \sigma_2 is a face of both \sigma_1 and \sigma_2 (and hence belongs to \Delta). In particular, the face of a cone in a fan is a cone is the fan.

If V is the (set-theoretic) union of the cones in \Delta then we call the fan complete. We shall assume that all fans are finite. A fan is determined by its list of maximal cones.
fan

Notation: A fan \Delta is represented in `toric` as a set of maximal cones. For example, if \Delta is the fan with maximal cones \sigma_1=Q_+\cdot f_1+Q_+\cdot (-f_1+f_2), \sigma_2=Q_+\cdot (-f_1+f_2)+Q_+\cdot (-f_1-f_2), \sigma_3=Q_+\cdot (-f_1-f_2)+Q_+\cdot f_1, then \Delta is represented by [[[1,0],[-1,1]],[[-1,1],[-1,-1]],[[-1,-1],[1,0]]].

The `toric` package can compute all cones in a fan of a given dimension (see ConesOfFan). Moreover, `toric` can compute the set of all normal vectors to the faces (i.e., hyperplanes) of a cone (see Faces).

The star of a cone \sigma in a fan \Delta is the set \Delta_\sigma of cones in \Delta containing \sigma as a face. The `toric` package can compute stars (see ToricStar).
star

Basic affine toric variety constructions Let R_\sigma = F [S_\sigma] denote the ``group algebra'' of this semigroup. It is a finitely generated commutative F-algebra. It is in fact integrally closed (, page 29). We may interprete R_\sigma as a subring of R=F [x_1,...,x_n] as follows: First, identify each e_i^* with the variable x_i. If S_\sigma is generated as a semigroup by vectors of the form \ell_1 e_1^*+...+\ell_n e_n^*, where \ell_i is an integer, then its image in R is generated by monomials of the form x_1^{\ell_1}\dots x_n^{\ell_n}. The `toric` package can compute these generating monomials (see EmbeddingAffineToricVariety). See Lemma 2.14 in for more details. This embedding can also be used to resolve singularities - see section 5 of for more details.

Let U_\sigma={\rm Spec}\ R_\sigma. This defines an affine toric variety (associated to \sigma). It is known that the coordinate ring R_\sigma of the affine toric variety U_\sigma has the form R_\sigma = F[x_1,...,x_n]/J, where J is an ideal. The `toric` package can compute generators of this ideal by using the DualSemigroupGenerators and the EmbeddingAffineToricVariety commands.
affine toric variety

Roughly speaking, the toric variety X(\Delta) associated to the fan \Delta is given by a collection of affine pieces $U_{\sigma_1},U_{\sigma_2},\dots,U_{\sigma_d}$ which ``glue'' together (where \Delta = \{\sigma_i\}). The affine pieces are given by the zero sets of polynomial equations in some affine spaces and the gluings are given by maps \phi_{i,j} : U_{\sigma_i} \rightarrow U_{\sigma_j} which are defined by ratios of polynomials on open subsets of the $U_{\sigma_i}$. The `toric` package does not compute these gluings or work directly with these (non-affine) varieties X(\Delta).

A cone \sigma \subset V is said to be nonsingular if it is generated by part of a basis for the lattice L_0. A fan \Delta of cones is said to be nonsingular if all its cones are nonsingular. It is known that U_\sigma is nonsingular if and only if \sigma is nonsingular (Proposition 2.1 in ).
cone, nonsingular

Example: In three dimensions, consider the cones \sigma_{\epsilon_1,\epsilon_2,\epsilon_3,i,j} generated by (\epsilon_1\cdot 1,\epsilon_2\cdot 1,\epsilon_3\cdot 1) and the standard basis vectors f_i,f_j, where \epsilon_i=\pm 1 and 1\leq i\not= j\leq 3. There are 8 cones per octant, for a total of 64 cones. Let \Delta denote the fan in V=Q^3 determined by these maximal cones. The toric variety X(\Delta) is nonsingular.

Riemann-Roch spaces and related constructions Although the `toric` package does not work directly with the toric varieties X(\Delta), it can compute objects associated with it. For example, it can compute the Euler characteristic (see EulerCharacteristic), Betti numbers (see BettiNumberToric), and the number of GF(q)-rational points (see CardinalityOfToricVariety) of X(\Delta), provided \Delta is nonsingular.

For an algebraic variety X the group of Weil divisors on X is the abelian group Div(X) generated (additively) by the irreducible subvarieties of X of codimension 1. For a toric variety X(\Delta) with dense open torus T, a Weil divisor D is T-invariant if D=T\cdot D. The group of T-invariant Weil divisors is denoted TDiv(X). This is finitely generated by an explicitly given finite set of divisors \{D_1,...,D_r\} which correspond naturally to certain cones in \Delta (see for details). In particular, we may represent such a divisor D in TDiv(X) by an k-tuple (d_1,...,d_k) of integers.
Weil divisors

Let \Delta denote a fan in V=Q^n with rays (or edges) \tau_i, 1\leq i\leq k, and let v_i denote the first lattice point on \tau_i. Associated to the T-invariant Weil divisor D=d_1D_1+...+d_kD_k, is the polytope P_D = \{ x=(x_1,...,x_n)\ |\ \langle x,v_i \rangle \geq -d_i, \ \forall 1 \leq i \leq k\}. The `toric` package can compute P_D (see DivisorPolytope), as well as the set of all lattice points contained in this polytope (see DivisorPolytopeLatticePoints). Also associated to the T-invariant Weil divisor D=d_1D_1+...+d_kD_k, is the Riemann-Roch space, L(D). This is a space of functions on X(\Delta) whose zeros and poles are ``controlled'' by D (for a more precise definition, see ). The `toric` package can compute a basis for L(D) (see RiemannRochBasis), provided \Delta is complete and nonsingular.
polytope associated to divisor
Cones and semigroups
Cones This section introduces the `toric` commands which deal with cones and related combinatorial-geometric objects. Recall, a cone is a strongly convex polyhedral cone (, page 4). This command returns `true` if the vector v belongs to the interior of the (strongly convex polyhedral) cone generated by the vectors in L. This procedure does not check if L generates a strongly convex polyhedral cone.
gap> L:=[[1,0,0],[1,1,0],[1,1,1],[1,0,1]];; v:=[0,0,1];; gap> InsideCone(v,L); false gap> L:=[[1,0],[3,4]];; gap> v:=[1,-7]; InsideCone(v,L); [ 1, -7 ] false gap> v:=[4,-3]; InsideCone(v,L); [ 4, -3 ] false gap> v:=[4,-4]; InsideCone(v,L); [ 4, -4 ] false gap> v:=[4,1]; InsideCone(v,L); [ 4, 1 ] true
This command returns `true` if v belongs to the dual of the cone generated by the vectors in L.
gap> L:=[[1,0,0],[1,1,0],[1,1,1],[1,0,1]];; v:=[0,0,1];; gap> InDualCone(v,L); true gap> L:=[[1,0],[3,4]]; [ [ 1, 0 ], [ 3, 4 ] ] gap> v:=[1,-7]; InDualCone(v,L); [ 1, -7 ] false gap> v:=[4,-3]; InDualCone(v,L); [ 4, -3 ] true gap> v:=[4,-4]; InDualCone(v,L); [ 4, -4 ] false gap> v:=[4,1]; InDualCone(v,L); [ 4, 1 ] true
Input: Perps=[v_1,...,v_k] is the list of ``inward normal" vectors perpendicular to the walls of a polytope P in the vector space L_0^*\otimes Q,
A=[a_1,...,a_k] is a k-tuple of integers, where a_i denotes the amount the i-th ``wall" (defined by the normal v_i) is shifted from the origin (each a_i is assumed non-negative).
For example, the polytope P with faces [x=0, x=a, y=0, y=b] has Perps=[[1,0],[-1,0],[0,1],[0,-1]] and A=[0,a,0,b].
Output: the list of points in P \cap L_0^*.
gap> Perps:=[[1,0],[-1,0],[0,1],[0,-1]]; [ [ 1, 0 ], [ -1, 0 ], [ 0, 1 ], [ 0, -1 ] ] gap> A:=[0,4,0,3]; [ 0, 4, 0, 3 ] gap> PolytopeLatticePoints(A,Perps); [ [ 0, 0 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 1, 0 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ] ] gap> Length(last); 20
Input: Rays is a list of rays for the fan \Delta
Output: All the normals to the faces (hyperplanes of the cone).
gap> Cones1:=[[[2,-1],[-1,2]],[[-1,2],[-1,-1]],[[-1,-1],[2,-1]]];; gap> Faces(Cones1[1]); [ [ 1/2, 1 ], [ 2, 1 ] ] gap> Faces(Cones1[2]); [ [ -2, -1 ], [ -1, 1 ] ] gap> Cones2:=[[[ 2,0,0],[0,2,0],[0,0,2]], [[2,0,0], [0,2,0], [2,-2,1],[1,2,-2]]];; gap> Faces(Cones2[1]); [ [ 0, 0, 1 ], [ 0, 1, 0 ], [ 1, 0, 0 ] ] gap> Faces(Cones2[2]); [ [ 1/3, 5/6, 1 ], [ 1/2, 0, -1 ], [ 2, 0, 1 ] ]
Input: Delta is the fan of cones,
k is the dimension of the cones desired.
Output: The k-dimensional cones in the fan. Input: Delta is the fan of cones in V=Q^n,
k is the dimension of the cones counted.
Output: The number of k-dimensional cones in the fan. Idea: The fan Delta is represented as a set of maximal cones. For each maximal cone, look at the k-dimensional faces obtained by taking n choose k subsets of the rays describing the cone. Certain of these k-subsets yield the desired cones.
gap> Delta0:=[ [ [2,0,0],[0,2,0],[0,0,2] ], [ [2,0,0],[0,2,0],[2,-2,1],[1,2,-2] ] ];; gap> NumberOfConesOfFan(Delta0,2); 6 gap> ConesOfFan(Delta0,2); [ [ [ 0, 0, 2 ], [ 0, 2, 0 ] ], [ [ 0, 0, 2 ], [ 2, 0, 0 ] ], [ [ 0, 2, 0 ], [ 1, 2, -2 ] ], [ [ 0, 2, 0 ], [ 2, -2, 1 ] ], [ [ 0, 2, 0 ], [ 2, 0, 0 ] ], [ [ 1, 2, -2 ], [ 2, -2, 1 ] ] ] gap> ConesOfFan(Delta0,1); [ [ [ 0, 0, 2 ] ], [ [ 0, 2, 0 ] ], [ [ 1, 2, -2 ] ], [ [ 2, -2, 1 ] ], [ [ 2, 0, 0 ] ] ] gap> NumberOfConesOfFan(Delta0,1); 5
Input: sigma is a cone in the fan, represented by its set of maximal (i.e., highest dimensional) cones.
Delta is the fan of cones in V=Q^n.
Output: The star of the cone sigma in Delta, i.e., the cones \tau which have sigma as a face.
gap> MaxCones:=[ [ [2,0,0],[0,2,0],[0,0,2] ], > [ [2,0,0],[0,2,0],[2,-2,1],[1,2,-2] ] ];; gap> #this is the set of maximal cones in the fan Delta gap> ToricStar([[1,0]],MaxCones); [ ] gap> ToricStar([[2,0,0],[0,2,0]],MaxCones); [ [ [ 0, 2, 0 ], [ 2, 0, 0 ] ], [ [ 2, 0, 0 ], [ 0, 2, 0 ], [ 0, 0, 2 ] ], [ [ 2, 0, 0 ], [ 0, 2, 0 ], [ 2, -2, 1 ], [ 1, 2, -2 ] ] ] gap> MaxCones:=[ [ [2,0,0],[0,2,0],[0,0,2] ], [ [2,0,0],[0,2,0],[1,1,-2] ] ];; gap> ToricStar([[2,0,0],[0,2,0]],MaxCones); [ [ [ 0, 2, 0 ], [ 2, 0, 0 ] ], [ [ 2, 0, 0 ], [ 0, 2, 0 ], [ 0, 0, 2 ] ], [ [ 2, 0, 0 ], [ 0, 2, 0 ], [ 1, 1, -2 ] ] ] gap> ToricStar([[1,0]],MaxCones); [ ]
Semigroups Input: L is a list of integral n-vectors generating a cone \sigma.
Output: the generators of S_\sigma,

Idea: let M be the maximum of the absolute values of the coordinates of the L[i]'s, for each vector v in [1..M]^n, test if v is in the dual cone \sigma^*. If so, add v to list of possible generators. Once this for loop is finished, one can check this list for redundant generators. The trick is to simply omit those elements which are of the form d_1+d_2, where d_1 and d_2 are ``small" elements in the integral dual cone.

This program is not very efficient and should not be used in ``large examples'' involving semigroups with ``many'' generators. For example, if you take L:=[[1,2,3,4],[0,1,0,7],[3,1,0,2],[0,0,1,0]]; then DualSemigroupGenerators(L); can exhaust GAP's memory allocation.
gap> L:=[[1,0],[3,4]];; DualSemigroupGenerators([[1,0],[3,4]]); [ [ 0, 0 ], [ 0, 1 ], [ 1, 0 ], [ 2, -1 ], [ 3, -2 ], [ 4, -3 ] ] gap> L:=[[1,0,0],[1,1,0],[1,1,1],[1,0,1]];; gap> DualSemigroupGenerators(L); [ [ 0, 0, 0 ], [ 0, 0, 1 ], [ 0, 1, 0 ], [ 1, -1, 0 ], [ 1, 0, -1 ] ]
Affine toric varieties This chapter concerns `toric` commands which deal with the coordinate rings of affine toric varieties U_\sigma.
Ideals defining affine toric varieties Input: L is a list generating a cone (as in DualSemigroupGenerators).
Output: the toroidal embedding of X=Spec(I), where I is the ideal of the affine toric variety (given as a list of multinomials).
gap> phi:=EmbeddingAffineToricVariety([[1,0],[3,4]]); [ x_2, x_1, x_1^2/x_4, x_1^3/x_4^2, x_1^4/x_4^3 ] gap> L:=[[1,0,0],[1,1,0],[1,1,1],[1,0,1]];; gap> phi:=EmbeddingAffineToricVariety(L); [ x_3, x_2, x_1/x_5, x_1/x_6 ]
Toric varieties X(\Delta) This chapter concerns `toric` commands which deal with certain objects associated to the (non-affine) toric varieties X(\Delta).
Riemann-Roch spaces Let \Delta denote a complete nonsingular fan. Input: Rays is the list of smallest integer vectors in the rays for the fan \Delta which determine the Weil divisors of X(\Delta).
D is the list of coefficients for the a Weil divisor.
Output: the linear expressions in the affine coordinates of the space of the cone which must be positive for a point to be in the desired polytope.
gap> DivisorPolytope([6,6,0],[[2,-1],[-1,2],[-1,-1]]); [ 2*x_1-x_2+6, -x_1+2*x_2+6, -x_1-x_2 ]
See also Example 6.13 in . Input: Delta is the fan
Rays is the ordered list of rays for Delta
D is the list of coefficients for a Weil divisor.
Output: the list of points in P_D \cap L_0^* which parameterize the elements in the Riemann-Roch space L(D), where P_D is the polytope associated to the divisor D (see DivisorPolytope).
gap> Div:=[6,6,0];; Rays:=[[2,-1],[-1,2],[-1,-1]];; gap> Delta0:=[[[2,-1],[-1,2]],[[-1,2],[-1,-1]],[[-1,-1],[2,-1]]];; gap> P_Div:=DivisorPolytopeLatticePoints(Div,Delta0,Rays); [ [ -6, -6 ], [ -5, -5 ], [ -5, -4 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -2, 2 ], [ -1, -3 ], [ -1, -2 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ], [ 0, -3 ], [ 0, -2 ], [ 0, -1 ], [ 0, 0 ], [ 1, -2 ], [ 1, -1 ], [ 2, -2 ] ]
Input: Delta is a complete and nonsingular fan
D is the list of coefficients for the Weil divisor
Rays is a list of rays for the fan used to describe the Weil divisors.
Output: A basis (a list of monomials) for the Riemann-Roch space of the divisor represented by D. For details on how the Weil divisors can be expressed in terms of the rays of the fan, please see section 3.3 in . This procedure does not check if the fan is complete and nonsingular.
gap> Div:=[6,6,0];; Rays:=[[2,-1],[-1,2],[-1,-1]];; gap> Delta0:=[[[2,-1],[-1,2]],[[-1,2],[-1,-1]],[[-1,-1],[2,-1]]];; gap> RiemannRochBasis(Div,Delta0,Rays); [ 1/(x_1^6*x_2^6), 1/(x_1^5*x_2^5), 1/(x_1^5*x_2^4), 1/(x_1^4*x_2^5), 1/(x_1^4*x_2^4), 1/(x_1^4*x_2^3), 1/(x_1^4*x_2^2), 1/(x_1^3*x_2^4), 1/(x_1^3*x_2^3), 1/(x_1^3*x_2^2), 1/(x_1^3*x_2), 1/x_1^3, 1/(x_1^2*x_2^4), 1/(x_1^2*x_2^3), 1/(x_1^2*x_2^2), 1/(x_1^2*x_2), 1/x_1^2, x_2/x_1^2, x_2^2/x_1^2, 1/(x_1*x_2^3), 1/(x_1*x_2^2), 1/(x_1*x_2), 1/x_1, x_2/x_1, 1/x_2^3, 1/x_2^2, 1/x_2, 1, x_1/x_2^2, x_1/x_2, x_1^2/x_2^2 ]
Topological invariants Throughout this section, X(\Delta) must be non-singular. Input: Delta is a nonsingular fan of cones, represented by its list of maximal cones.
Output: the Euler characteristic of the toric variety X(\Delta), where \Delta is a fan determined by Delta.
gap> Cones:=[[[2,-1],[-1,2]],[[-1,2],[-1,-1]],[[-1,-1],[2,-1]]];; gap> EulerCharacteristic(Cones); 3
Note: X(\Delta) must be non-singular here. Input: Delta represents a nonsingular fan \Delta (represented by maximal cones),
k is an integer.
Output: the k-th Betti number of the toric variety X(\Delta). The BettiNumberToric procedure does not check if Delta is nonsingular. It is possible that this procedure outputs nonsense when Delta is not represented by maximal cones or is nonsingular.
gap> Cones:=[[[2,-1],[-1,2]],[[-1,2],[-1,-1]],[[-1,-1],[2,-1]]];; gap> BettiNumberToric(Cones,1); 0 gap> BettiNumberToric(Cones,2); 1 gap> Cones:=[[[2,-1],[-1,1]],[[-1,1],[-1,0]],[[-1,0],[2,-1]]];; gap> BettiNumberToric(Cones,1); 0 gap> BettiNumberToric(Cones,2); 1
Not to be confused with the Betti number of a polycyclically presented torsion free group, already available in &GAP;.
Points over a finite field Input: Cones is the list of maximal cones of a fan \Delta, q is a prime power.
Output: The size of the set of GF(q)-rational points of the toric variety X(\Delta). Note: X(\Delta) must be non-singular here.
gap> Cones:=[[[2,-1],[-1,2]],[[-1,2],[-1,-1]],[[-1,-1],[2,-1]]];; gap> CardinalityOfToricVariety(Cones,3); 13 gap> CardinalityOfToricVariety(Cones,4); 21 gap> CardinalityOfToricVariety(Cones,5); 31 gap> CardinalityOfToricVariety(Cones,7); 57