Author: Martin Bies

In [1]:

```
using Oscar
```

```
----- ----- ----- - -----
| | | | | | | | | |
| | | | | | | |
| | ----- | | | |-----
| | | | |-----| | |
| | | | | | | | | |
----- ----- ----- - - - -
...combining (and extending) ANTIC, GAP, Polymake and Singular
Version 0.12.0-DEV ...
... which comes with absolutely no warranty whatsoever
Type: '?Oscar' for more information
(c) 2019-2023 by The OSCAR Development Team
```

Any geometry course (analytic geometry, algebraic geometry and of course toric geometry too) begins with the study of affine varieties/schemes. So we first recall that affine toric varieties are encoded by rational polyhedral cones.

Specifically, let us state theorem 1.2.18 of the book *Toric Varieties* by David Cox, John Little and Hal Schenck:

Let $\sigma \subseteq N_{\mathbb{R}} \cong \mathbb{R}^n$ be a rational polyhedral cone with semigroup $S_\sigma = \sigma^\vee \cap M$. Then the associated affine toric variety $U_\sigma$ is given by

$$ U_\sigma = \mathrm{Spec} \left(\mathbb{C} \left[ S_\sigma \right]\right) = \mathrm{Spec} \left(\mathbb{C} \left[ \sigma^\vee \cap M \right]\right) \, .$$In particular, it holds

$$\mathrm{dim}( U_\sigma ) = n \, \Leftrightarrow \, \text{the torus of $U_\sigma$ is } T_N = N \otimes_{\mathbb{Z}} \mathbb{C}^\ast \, \Leftrightarrow \, \sigma \text{ is strongly convex.}$$As per usual, we focus on *strongy convex* polyhedral cones $\sigma$, so that $T_N$ is the algebraic torus of $U_\sigma$.

In [2]:

```
C = positive_hull([1 0; 0 1])
```

Out[2]:

Polyhedral cone in ambient dimension 2

In [3]:

```
antv = affine_normal_toric_variety(C)
```

Out[3]:

Normal, affine toric variety

In [4]:

```
is_smooth(antv)
```

Out[4]:

true

In [5]:

```
is_complete(antv)
```

Out[5]:

false

In [6]:

```
is_simplicial(antv)
```

Out[6]:

true

In [7]:

```
toric_ideal(antv)
```

Out[7]:

ideal(0)

This means, that the variety *antv* is nothing but $\mathbb{C}^2$. Here is a more interesting example:

In [8]:

```
C2 = positive_hull([1 1; -1 1])
```

Out[8]:

Polyhedral cone in ambient dimension 2

In [9]:

```
antv2 = affine_normal_toric_variety(C2)
```

Out[9]:

Normal, affine toric variety

In [10]:

```
is_smooth(antv2)
```

Out[10]:

false

In [11]:

```
is_simplicial(antv2)
```

Out[11]:

true

In [12]:

```
toric_ideal(antv2)
```

Out[12]:

ideal(-x1*x2 + x3^2)

More general toric varieties are constructed by providing not only one strongly convex polyhedral cone, but a collection of "compatible" cones. Such a collection is termed a (strongly convex polyhedral) fan.

We give details on how to create fans and the corresponding toric varieties in section 3 of this tutorial. In this section however, we demonstrate the existing functionality in OSCAR by studying the projective space. Specifically, let us focus on the projective space $\mathbb{P}^2$.

We construct the projective space as follows:

In [13]:

```
P2 = projective_space(NormalToricVariety, 2)
```

Out[13]:

Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor

As you can notice, upon creation a lot of information on this space is already known.

Notice that the constructor expects us to state as first argument *NormalToricVariety*. This is to tell OSCAR that we want the projective space as a toric variety.

This is a design decision that was taken after careful consideration. Namely, the projective space could in principle be constructed as a scheme (with an arbitrary coefficient ring) or merely as a space parametrized by homogeneous coordinates. Depending on which of these perspectives is desired, specializes algorithms may be available. As of February 2023, there are many specialized toric algorithms. So in this regard, providing *NormalToricVariety* as the first argument ensures that we can perform a large number of computations.

In [14]:

```
is_affine(P2)
```

Out[14]:

false

In [15]:

```
is_smooth(P2)
```

Out[15]:

true

In [16]:

```
is_projective(P2)
```

Out[16]:

true

In [17]:

```
has_torusfactor(P2)
```

Out[17]:

false

A basic attribute that we would like to access is the dimension of the space:

In [18]:

```
dim(P2)
```

Out[18]:

2

In [19]:

```
torusinvariant_weil_divisor_group(P2)
```

Out[19]:

GrpAb: Z^3

In [20]:

```
torusinvariant_cartier_divisor_group(P2)
```

Out[20]:

GrpAb: Z^3

In [21]:

```
f1 = map_from_torusinvariant_weil_divisor_group_to_class_group(P2)
```

Out[21]:

Map with following data Domain: ======= Abelian group with structure: Z^3 Codomain: ========= Abelian group with structure: Z

To see the mapping prescription, we can access the matrix of this map:

In [22]:

```
matrix(f1)
```

Out[22]:

[1] [1] [1]

This means, that there are 3 torus-invariant Weil divisors $D_1$, $D_2$, $D_3$ for $\mathbb{P}^2$ (each corresponding to a ray in the fan of $\mathbb{P}^2$). The map to the class group assigns to each of the 3 torus-invariant Weil divisors the same divisor class, i.e. $[D_1] = [D_2] = [D_3]$. Or put differently, the Weil divisors $D_1$, $D_2$, $D_3$ are linearly equivalent: $D_1 \sim D_2 \sim D_3$.

Of course, we can also use this information to find the Class group $\mathrm{Cl} ( \mathbb{P}^2 )$:

In [23]:

```
class_group(P2)
```

Out[23]:

GrpAb: Z

In [24]:

```
f2 = map_from_cartier_divisor_group_to_picard_group(P2)
```

Out[24]:

In [25]:

```
matrix(f2)
```

Out[25]:

[1] [1] [1]

In [26]:

```
picard_group(P2)
```

Out[26]:

GrpAb: Z

In [27]:

```
f3 = map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(P2)
```

Out[27]:

Map with following data Domain: ======= Abelian group with structure: Z^3 Codomain: ========= Abelian group with structure: Z^3

In [28]:

```
matrix(f3)
```

Out[28]:

[1 0 0] [0 1 0] [0 0 1]

In [29]:

```
is_surjective(f1)
```

Out[29]:

true

In [30]:

```
[preimage(f1,x) for x in gens(class_group(P2))]
```

Out[30]:

1-element Vector{GrpAbFinGenElem}: Element of GrpAb: Z^3 with components [1 0 0]

Alternatively, we can even find the preinverse of $f_1$ directly:

In [31]:

```
matrix(preinverse(f1))
```

Out[31]:

[1 0 0]

This functionality is particularly useful in the context of line bundles on toric varieties, i.e. the elements of the Picard group $\mathrm{Pic}(\mathbb{P}^2)$. We will study line bundles momentarily.

We complete this section by briefly mentioning the character lattice $N(\mathbb{P}^2)$. Since $\mathbb{P}^2$ has no torus factor, there is a short exact sequence:

$$0 \to N(\mathbb{P}^2) \hookrightarrow \mathrm{Div}_T( \mathbb{P}^2 ) \twoheadrightarrow \mathrm{Cl} ( \mathbb{P}^2 ) \to 0.$$The map $N(\mathbb{P}^2) \hookrightarrow \mathrm{Div}_T( \mathbb{P}^2 )$ can be computed as follows:

In [32]:

```
f4 = map_from_character_lattice_to_torusinvariant_weil_divisor_group(P2)
```

Out[32]:

Map with following data Domain: ======= Abelian group with structure: Z^2 Codomain: ========= Abelian group with structure: Z^3

In [33]:

```
is_injective(f4)
```

Out[33]:

true

In [34]:

```
is_surjective(f4)
```

Out[34]:

false

In [35]:

```
matrix(f4)
```

Out[35]:

[1 0 -1] [0 1 -1]

The columns of this matrix are the ray generators of the fan of the projective space $\mathbb{P}^2$.

Let us now create a torus-invariant Weil divisor on the projective space $\mathbb{P}^2$. From the study of toric divisors above, we recall that the group of torus-invariant Weil divisors has 3 generators $D_1$, $D_2$ and $D_3$. Hence, the most general torus-invariant Weil divisor is of the form $a_1 D_1 + a_2 D_2 + a_3 D_3$ with $a_1, a_2, a_3 \in \mathbb{Z}$. The constructor for toric divisors on $\mathbb{P}^2$ expects the list $[a_1, a_2, a_3]$ as its second argument.

Let us now create the torusinvariant Weil divisor $D = 1 D_1 + 2 D_2 + 3 D_3$:

In [36]:

```
D = toric_divisor(P2,[1,2,3])
```

Out[36]:

Torus-invariant, non-prime divisor on a normal toric variety

We support various properties and attributes for such a divisor:

In [37]:

```
is_ample(D)
```

Out[37]:

true

In [38]:

```
is_very_ample(D)
```

Out[38]:

true

In [39]:

```
is_cartier(D)
```

Out[39]:

true

In [40]:

```
is_principal(D)
```

Out[40]:

false

In [41]:

```
coefficients(D)
```

Out[41]:

3-element Vector{ZZRingElem}: 1 2 3

In particular we can compute the divsior class associated to this divisor:

In [42]:

```
DC = toric_divisor_class(D)
```

Out[42]:

Divisor class on a normal toric variety

In [43]:

```
D2 = toric_divisor(DC)
```

Out[43]:

Torus-invariant, non-prime divisor on a normal toric variety

Note that $D_2$ and $D$ are not identical:

In [44]:

```
D == D2
```

Out[44]:

false

We can see this explicitly, by asking for the coefficients of $D_2$:

In [45]:

```
coefficients(D2)
```

Out[45]:

3-element Vector{ZZRingElem}: 6 0 0

However, $D \sim D_2$. This is the case since $D - D_2$ is a principal divisor:

In [46]:

```
is_principal(D - D2)
```

Out[46]:

true

So, as expected $[D] = [D_2]$.

In [47]:

```
picard_group(P2)
```

Out[47]:

GrpAb: Z

In [48]:

```
L = toric_line_bundle(P2,[1])
```

Out[48]:

Toric line bundle on a normal toric variety

In [49]:

```
is_trivial(L)
```

Out[49]:

false

In [50]:

```
toric_divisor(L)
```

Out[50]:

Torus-invariant, cartier, non-principal, prime divisor on a normal toric variety

In [51]:

```
divisor_class(L)
```

Out[51]:

Element of GrpAb: Z with components [1]

Among others, ampleness of a line bundle is checked by checking it for the underlying divisor:

In [52]:

```
is_ample(L)
```

Out[52]:

true

In [53]:

```
is_very_ample(L)
```

Out[53]:

true

Another example is the degree of the line bundle:

In [54]:

```
degree(L)
```

Out[54]:

1

In [55]:

```
all_cohomologies(L)
```

Out[55]:

3-element Vector{ZZRingElem}: 3 0 0

This means that $h^0( \mathbb{P}^2, \mathcal{L} ) = 3$ and $h^1( \mathbb{P}^2, \mathcal{L} ) = h^2( \mathbb{P}^2, \mathcal{L} ) = 0$. This result is of course well-known to the experts. This functionality works as long as the variety in question is either (smooth and complete) or (simplicial and projective).

Of course, we can also compute just some of the line bundle cohomologies. For instance, the following finds $h^0( \mathbb{P}^2, \mathcal{L} )$:

In [56]:

```
cohomology(L,0)
```

Out[56]:

3

In [57]:

```
cox_ring(P2)
```

Out[57]:

Multivariate Polynomial Ring in x1, x2, x3 over Rational Field graded by x1 -> [1] x2 -> [1] x3 -> [1]

In [58]:

```
basis_of_global_sections_via_homogeneous_component(L)
```

Out[58]:

3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}: x3 x2 x1

In [59]:

```
basis_of_global_sections_via_rational_functions(L)
```

Out[59]:

3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}: x1_ x2*x1_ 1

For convenience, the default is to use the homogeneous components. That is:

In [60]:

```
basis_of_global_sections(L)
```

Out[60]:

3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}: x3 x2 x1

In [61]:

```
fan_of_P2 = fan(P2)
```

Out[61]:

Polyhedral fan in ambient dimension 2

*visualize(f)*. This will (most likely) open a separate window with an illustration of the fan. Alternatively, we can investigate the fan in more details by computing its rays and maximal cones:

In [62]:

```
rays(fan_of_P2)
```

Out[62]:

3-element SubObjectIterator{RayVector{QQFieldElem}}: [1, 0] [0, 1] [-1, -1]

In [63]:

```
maximal_cones(fan_of_P2)
```

Out[63]:

3-element SubObjectIterator{Cone{QQFieldElem}}: Polyhedral cone in ambient dimension 2 Polyhedral cone in ambient dimension 2 Polyhedral cone in ambient dimension 2

In [64]:

```
[rays(c) for c in maximal_cones(fan_of_P2)]
```

Out[64]:

3-element Vector{SubObjectIterator{RayVector{QQFieldElem}}}: [[1, 0], [0, 1]] [[0, 1], [-1, -1]] [[1, 0], [-1, -1]]

Indeed, this is the famous fan of the projective space $\mathbb{P}^2$.

In [65]:

```
ray_generators = [[1, 0], [0, 1], [-1, -1]]
max_cones = [[1, 2], [2, 3], [3, 1]]
X = normal_toric_variety(ray_generators, max_cones)
```

Out[65]:

Normal toric variety

In [66]:

```
is_projective(X)
```

Out[66]:

true

In [67]:

```
is_smooth(X)
```

Out[67]:

true

In [68]:

```
dim(X)
```

Out[68]:

2

In [69]:

```
class_group(X)
```

Out[69]:

GrpAb: Z

In [70]:

```
torusinvariant_weil_divisor_group(X)
```

Out[70]:

GrpAb: Z^3

In [71]:

```
cox_ring(X)
```

Out[71]:

We provide a constructor for del Pezzo surfaces. For instance, we can issue:

In [72]:

```
dP3 = del_pezzo_surface(3)
```

Out[72]:

In [73]:

```
picard_group(dP3)
```

Out[73]:

GrpAb: Z^4

In [74]:

```
L2 = toric_line_bundle(dP3,[3,2,1,0])
```

Out[74]:

Toric line bundle on a normal toric variety

In [75]:

```
all_cohomologies(L2)
```

Out[75]:

3-element Vector{ZZRingElem}: 6 0 0

In [76]:

```
basis_of_global_sections(L2)
```

Out[76]:

6-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}: x2^2*x3*e3^3 x1*x2*x3*e2*e3^2 x1*x2^2*e1*e3^2 x1^2*x3*e2^2*e3 x1^2*x2*e1*e2*e3 x1^3*e1*e2^2

Similarly, we can also construct Hirzebruch surfaces:

In [77]:

```
F2 = hirzebruch_surface(2)
```

Out[77]:

Normal, non-affine, smooth, projective, gorenstein, non-fano, 2-dimensional toric variety without torusfactor

In [78]:

```
P2
```

Out[78]:

In [79]:

```
cox_ring(P2)
```

Out[79]:

Let us now perform a blowup of the locus $V( x_1, x_2 )$. This is done as follows:

In [80]:

```
BP2 = blowup_on_ith_minimal_torus_orbit(P2, 1, "e")
```

Out[80]:

Normal toric variety

In [81]:

```
fan_of_BP2 = fan(BP2)
```

Out[81]:

Polyhedral fan in ambient dimension 2

In [82]:

```
rays(fan_of_BP2)
```

Out[82]:

4-element SubObjectIterator{RayVector{QQFieldElem}}: [0, 1] [-1, -1] [1, 0] [1, 1]

So we notice the new ray $[1,1]$. To find the new cones $C_1$ and $C_2$, we issue the following:

In [83]:

```
[rays(c) for c in maximal_cones(fan_of_BP2)]
```

Out[83]:

4-element Vector{SubObjectIterator{RayVector{QQFieldElem}}}: [[0, 1], [-1, -1]] [[-1, -1], [1, 0]] [[1, 0], [1, 1]] [[0, 1], [1, 1]]

So indeed, the last two cones are the expected new cones. The first two are the cones that exist for the fan of $\mathbb{P}^2$ and were not changed.

The variable $e$ we can see most prominently in the Cox ring:

In [84]:

```
cox_ring(BP2)
```

Out[84]:

Multivariate Polynomial Ring in x2, x3, x1, e over Rational Field graded by x2 -> [1 0] x3 -> [0 1] x1 -> [1 0] e -> [-1 1]

In [85]:

```
stanley_reisner_ideal(BP2)
```

Out[85]:

ideal(x2*x1, x3*e)

This means that $\emptyset = V( x_2, x_1 ) \subseteq B \mathbb{P}^2$ and $\emptyset = V( x_3, e ) \subset B \mathbb{P}^2$.

Along these lines, we can also see that the locus $V(e) \subset B\mathbb{P}^2$ is a $\mathbb{P}^1$. Namely, from the Stanley-Reisner ideal we learn that $x_3$ and $e$ cannot vanish simultaneously. So $x_3 \neq 0$ and we can rescale it to $1$. This rescaling effectively eliminates the 2nd line in the grading of the Cox ring and leaves us with $$\begin{array}{ccc|c} x_1 & x_2 \\ \hline 1 & 1 \end{array}$$ So we notice, that the variables $x_1$ and $x_2$ each enjoy the standard grading $(1,1)$. Also, since $x_1 x_2 \in I_{\text{SR}}( B\mathbb{P}^2 )$, it holds $\emptyset = V( x_2, x_1 ) \subset B \mathbb{P}^2$. This implies $V( e ) \cong \mathbb{P}^1_{[x_1 \colon x_2]}$.

It is also possible to compute Cartesian products of toric varieties. Here is an example:

In [86]:

```
product = P2 * F2
```

Out[86]:

Normal toric variety

In [87]:

```
cox_ring(product)
```

Out[87]:

Multivariate Polynomial Ring in 7 variables xx1, xx2, xx3, yt1, ..., yx2 over Rational Field graded by xx1 -> [1 0 0] xx2 -> [1 0 0] xx3 -> [1 0 0] yt1 -> [0 1 0] yx1 -> [0 0 1] yt2 -> [0 1 0] yx2 -> [0 2 1]

In [88]:

```
P = convex_hull([0 0 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1])
```

Out[88]:

Polyhedron in ambient dimension 3

In [89]:

```
(v1, v2) = normal_toric_varieties_from_star_triangulations(P)
```

Out[89]:

2-element Vector{NormalToricVariety}: Normal toric variety Normal toric variety

*visualize(P)*. The polyhedron $P$ admits exactly two fine, regular, star triangulations. These were used to create the toric varieties $v_1$ and $v_2$. We now study these two varieties:

In [90]:

```
is_smooth(v1)
```

Out[90]:

true

In [91]:

```
is_projective(v1)
```

Out[91]:

false

In [92]:

```
dim(v1)
```

Out[92]:

3

In [93]:

```
is_complete(v1)
```

Out[93]:

false

In [94]:

```
cox_ring(v1)
```

Out[94]:

Multivariate Polynomial Ring in x1, x2, x3, x4 over Rational Field graded by x1 -> [1] x2 -> [-1] x3 -> [1] x4 -> [-1]

In [95]:

```
stanley_reisner_ideal(v1)
```

Out[95]:

ideal(x2*x4)

If we repeat these line with $v_2$, then the only difference is:

In [96]:

```
stanley_reisner_ideal(v2)
```

Out[96]:

ideal(x1*x3)

In [97]:

```
function involved_triangulation()
# (0) Define the polytope
fac1 = convex_hull( [-1 -1 -1; 2 -1 -1; -1 2 -1]);
fac2 = convex_hull( [-1 -1 -1; 2 -1 -1; -1 -1 5]);
fac3 = convex_hull( [-1 -1 -1; -1 2 -1; -1 -1 5]);
fac4 = convex_hull( [2 -1 -1; -1 2 -1; -1 -1 5]);
fac = fac1;
# (1) Set variable names of our choice
vars_dict = Dict();
vars_dict[matrix(ZZ,[-1 -1 -1])] = "x0";
vars_dict[matrix(ZZ,[2 -1 -1])] = "x1";
vars_dict[matrix(ZZ,[-1 2 -1])] = "x2";
vars_dict[matrix(ZZ,[-1 -1 5])] = "x3";
vars_dict[matrix(ZZ,[-1 -1 0])] = "x4";
vars_dict[matrix(ZZ,[-1 -1 1])] = "x5";
vars_dict[matrix(ZZ,[-1 -1 2])] = "x6";
vars_dict[matrix(ZZ,[-1 -1 3])] = "x7";
vars_dict[matrix(ZZ,[-1 -1 4])] = "x8";
vars_dict[matrix(ZZ,[-1 0 -1])] = "x9";
vars_dict[matrix(ZZ,[-1 0 0])] = "x10";
vars_dict[matrix(ZZ,[-1 0 1])] = "x11";
vars_dict[matrix(ZZ,[-1 0 2])] = "x12";
vars_dict[matrix(ZZ,[-1 0 3])] = "x13";
vars_dict[matrix(ZZ,[-1 1 -1])] = "x14";
vars_dict[matrix(ZZ,[-1 1 0])] = "x15";
vars_dict[matrix(ZZ,[-1 1 1])] = "x16";
vars_dict[matrix(ZZ,[0 -1 -1])] = "x17";
vars_dict[matrix(ZZ,[0 -1 0])] = "x18";
vars_dict[matrix(ZZ,[0 -1 1])] = "x19";
vars_dict[matrix(ZZ,[0 -1 2])] = "x20";
vars_dict[matrix(ZZ,[0 -1 3])] = "x21";
vars_dict[matrix(ZZ,[0 0 -1])] = "x22";
vars_dict[matrix(ZZ,[0 0 1])] = "x23";
vars_dict[matrix(ZZ,[0 1 -1])] = "x24";
vars_dict[matrix(ZZ,[1 -1 -1])] = "x25";
vars_dict[matrix(ZZ,[1 -1 0])] = "x26";
vars_dict[matrix(ZZ,[1 -1 1])] = "x27";
vars_dict[matrix(ZZ,[1 0 -1])] = "x28";
#(2) Form point set to be triangulated
points = lattice_points(fac);
d = ambient_dim(fac)
pts = vcat(zero_matrix(ZZ, 1, d), matrix(ZZ, transpose(reduce(hcat,points))));
#(3) Triangulate
trias = star_triangulations(pts; full=true, regular=true);
trias = [[[c[k]-1 for k in 2:length(c)] for c in t] for t in trias];
#(4) Compute rays of all toric varieties
fan_rays = matrix(ZZ, points);
#(5) Construct ring which contains all Stanley-Reisner ideals
max_cones = IncidenceMatrix(vcat(trias[1]));
pmfan = Polymake.fan.PolyhedralFan(RAYS=fan_rays, MAXIMAL_CONES=max_cones);
variety = NormalToricVariety(PolyhedralFan{fmpq}(pmfan));
my_vars = [vars_dict[fan_rays[i,:]] for i in 1:nrows(fan_rays)];
set_coordinate_names(variety, my_vars);
R = cox_ring(variety);
#(6) Compute all ideals
sr_ideals = [];
for n in 1:length(trias)
id = stanley_reisner_ideal(R, SimplicialComplex(trias[n]));
push!(sr_ideals,id);
end;
#(7) Finall intersect all ideals
return common_sr_ideal = reduce(intersect,sr_ideals);
end
```

Out[97]:

involved_triangulation (generic function with 1 method)

In a nutshell, this code computes all fine regular star triangulations of the polyhedron *fac1*, computes the Stanley-Reisner of the associated toric varieties and then intersects these ideals. As such, it finds the intersection theory that is common to this family of toric varieties.

The code for *fac1* and *fac4* will likely execute within a few seconds. For the polyhedrons *fac2* or *fac3*, the task is much more involved and will likely take a few minutes. This is why in the above code, we fixed the choice of polyhedron to *fac1*. Brave users may which to challenge their computer a bit by altering that choice to *fac2* or *fac3*. The computations should still complete on most private computers within a few minutes.

To benchmark the execution time of the function *involved_triangulation*, and thus provide comparision to other computer systems, we can execute the following:

In [98]:

```
using BenchmarkTools
@btime involved_triangulation()
```

267.974 ms (358874 allocations: 13.91 MiB)

Out[98]:

ideal(x24*x1, x17*x1, x2*x1, x0*x1, x2*x28, x9*x28, x14*x25, x0*x25, x17*x24, x9*x2, x0*x2, x0*x14, x9*x14*x1, x0*x24*x28, x14*x17*x28, x9*x24*x25, x2*x17*x25, x22*x25*x28*x1, x14*x22*x28*x1, x9*x22*x25*x1, x22*x24*x25*x28, x17*x22*x25*x28, x14*x22*x24*x28, x0*x17*x22*x28, x2*x22*x24*x25, x9*x17*x22*x25, x14*x2*x22*x24, x9*x14*x22*x24, x0*x9*x22*x24, x14*x2*x17*x22, x9*x14*x17*x22, x0*x9*x17*x22)

You might find it interesting to compare your executation time to the following result:

- Execution time: 267.974ms,
- 358874 allocations (13.91 MiB).

This result was obtained on March 7, 2023 by runnning the OSCAR (see the beginning of this notebook for the version) with Julia 1.7.3 on a TUXEDO InfinityBook Pro 14 v4 with Intel Core i7-Quad-Core, 32GB RAM and operating system Ubuntu 20.04.5 LTS.

OSCAR aims for a broad user audience. As such, input is usually checked for consistency. This comes at the expense of loosing a bit of performance and possibly modifying the input data (if needed), e.g. shuffling it. In the toric settings, such shufflings of e.g. the order of rays can be undesirable.

It is possible to switch off such input checks when creating toric varieties. *However, it must be emphasized that then it is the user's responsibility to provide sane input.*

As an example, the following lines are executed internally to create the del Pezzo surface $dP_3$:

In [99]:

```
fan_rays = [1 0; 0 1; -1 -1; 1 1; 0 -1; -1 0]
cones = IncidenceMatrix([[1, 4], [2, 4], [1, 5], [5, 3], [2, 6], [6, 3]])
variety = normal_toric_variety(PolyhedralFan(fan_rays, cones; non_redundant = true))
```

Out[99]:

Normal toric variety

Notice the *non_redundant = true* entry in the constructor for *NormalToricVariety*. This switches off the input check by informing OSCAR that we (= the users) made sure that there is no redundancy in the input. It is encouraged to use this functionality with care and only after checking the input carefully.

To continue with the above example, we would like to see that this is indeed a del Pezzo surface. This can be seen directly from the fan - the three last rays correspond to the star subdivision of the 3 maximal cones of $\mathbb{P}^2$ - or by studying the properties of the variety in more detail. We opt for the latter and first assign suitable variable names:

In [100]:

```
vars = ["x1", "x2", "x3", "e1", "e2", "e3"]
set_coordinate_names(variety, vars[1:6])
```

In [101]:

```
weights = matrix(ZZ, [1 1 1 0; 1 1 0 1; 1 0 1 1; 0 -1 0 0; 0 0 -1 0; 0 0 0 -1])
set_attribute!(variety, :map_from_torusinvariant_weil_divisor_group_to_class_group, hom(torusinvariant_weil_divisor_group(variety), class_group(variety), weights))
```

When executing *del_pezzo_surface(3)* more properties are set by OSCAR. But that put aside, the above are the internal steps of the constructor.

With that said, the following should identify this space as the del Pezzo surface $dP_3$:

In [102]:

```
cox_ring(variety)
```

Out[102]:

Multivariate Polynomial Ring in 6 variables x1, x2, x3, e1, ..., e3 over Rational Field graded by x1 -> [1 1 1 0] x2 -> [1 1 0 1] x3 -> [1 0 1 1] e1 -> [0 -1 0 0] e2 -> [0 0 -1 0] e3 -> [0 0 0 -1]

In [103]:

```
is_smooth(variety)
```

Out[103]:

true

In [104]:

```
is_projective(variety)
```

Out[104]:

true

In [105]:

```
[betti_number(variety,i) for i in range(0,4)]
```

Out[105]:

5-element Vector{ZZRingElem}: 1 0 4 0 1

In [106]:

```
picard_group(variety)
```

Out[106]:

GrpAb: Z^4

In [107]:

```
torusinvariant_weil_divisor_group(variety)
```

Out[107]:

GrpAb: Z^6

In [108]:

```
character_lattice(variety)
```

Out[108]:

GrpAb: Z^2

For (smooth, complete) and (simplicial, projective) toric varieties, it is possible to find a unified description for all line bundles for which a certain cohomology class vanishes. This set is then referred to as a vanishing set.

The first description of this approach can be found in appendix B of https://arxiv.org/pdf/1802.08860.pdf. The corresponding functionality is available in Oscar.

We begin by demonstrating this for the projective space $\mathbb{P}^2$, for which the vanishing sets are well-known. Namely: \begin{align} V^0( \mathbb{P}^2 ) &= \{ \mathcal{L} \in \mathrm{Pic}(\mathbb{P}^2) | h^0(\mathbb{P}^2, \mathcal{L}) = 0\} = \{ \mathcal{L} \in \mathrm{Pic}(\mathbb{P}^2) | \mathrm{deg}( \mathcal{L} ) < 0 \} \, , \\ V^1( \mathbb{P}^2 ) &= \{ \mathcal{L} \in \mathrm{Pic}(\mathbb{P}^2) | h^1(\mathbb{P}^2, \mathcal{L}) = 0\} = \mathrm{Pic}(\mathbb{P}^2) \, , \\ V^2( \mathbb{P}^2 ) &= \{ \mathcal{L} \in \mathrm{Pic}(\mathbb{P}^2) | h^2(\mathbb{P}^2, \mathcal{L}) = 0\} = \{ \mathcal{L} \in \mathrm{Pic}(\mathbb{P}^2) | \mathrm{deg}( \mathcal{L} ) > -2 \}\, . \end{align} Let us recompute this with OSCAR:

In [109]:

```
vs = vanishing_sets(P2)
```

Out[109]:

3-element Vector{ToricVanishingSet}: Toric vanishing set for cohomology index 0 Toric vanishing set for cohomology index 1 Toric vanishing set for cohomology index 2

In [110]:

```
polyhedra(vs[1])
```

Out[110]:

1-element Vector{Polyhedron{QQFieldElem}}: Polyhedron in ambient dimension 1

In [111]:

```
p0 = polyhedra(vs[1])[1]
```

Out[111]:

Polyhedron in ambient dimension 1

In [112]:

```
vertices(p0)
```

Out[112]:

1-element SubObjectIterator{PointVector{QQFieldElem}}: [0]

In [113]:

```
rays(p0)
```

Out[113]:

1-element SubObjectIterator{RayVector{QQFieldElem}}: [1]

We are thus looking at $C = \mathrm{Span}_{\mathbb{Z}_{\geq 0}}(1) \}$. This cone is a subset of $\mathrm{Pic}( \mathbb{P}^2)$ and the vanishing set is its complement, that is: $$V^0( \mathbb{P}^2 ) = \{ \mathcal{L} \in \mathrm{Pic}(\mathbb{P}^2) | h^0(\mathbb{P}^2, \mathcal{L}) = 0\} = \{ \mathcal{L} \in \mathrm{Pic}(\mathbb{P}^2) | \mathcal{L} ) \notin C \} \, .$$ It is readily verified that this indeed matches the above expectation.

Recall that $V^1( \mathbb{P}^2 ) = \mathrm{Pic}(\mathbb{P}^2)$. This we can see quickly:

In [114]:

```
polyhedra(vs[2])
```

Out[114]:

Polyhedron{QQFieldElem}[]

This list of polyhedra is empty. In other words, the vanishing set is the complement of the empty set in $\mathrm{Pic}( \mathbb{P}^2 )$, which is nothing but the entire Picard group.

Let us now look at the vanishing set for $h^2$:

In [115]:

```
polyhedra(vs[3])
```

Out[115]:

1-element Vector{Polyhedron{QQFieldElem}}: Polyhedron in ambient dimension 1

In [116]:

```
p3 = polyhedra(vs[3])[1]
```

Out[116]:

Polyhedron in ambient dimension 1

In [117]:

```
vertices(p3)
```

Out[117]:

1-element SubObjectIterator{PointVector{QQFieldElem}}: [-3]

In [118]:

```
rays(p3)
```

Out[118]:

1-element SubObjectIterator{RayVector{QQFieldElem}}: [-1]

We are thus looking at $P_3 = \{-3\} + \mathrm{Span}_{\mathbb{Z}_{\geq 0}} \{-1\}$. Its complement is $V^2( \mathbb{P}^2 )$, which matches our expectation.

Recall that we constructed a line bundle $\mathcal{L}$ on $\mathbb{P}^2$ above:

In [119]:

```
L = toric_line_bundle(P2, [1])
```

Out[119]:

Toric line bundle on a normal toric variety

Its cohomologies are:

In [120]:

```
all_cohomologies(L)
```

Out[120]:

3-element Vector{ZZRingElem}: 3 0 0

So $L$ is not $V^0( \mathbb{P}^2 )$ but in $V^1( \mathbb{P}^2 )$ and $V^2( \mathbb{P}^2 )$:

In [121]:

```
contains(vs[1],L)
```

Out[121]:

false

In [122]:

```
contains(vs[2],L)
```

Out[122]:

true

In [123]:

```
contains(vs[3],L)
```

Out[123]:

true

In [124]:

```
dP2 = del_pezzo_surface(2)
```

Out[124]:

In [125]:

```
S = cox_ring(dP2)
```

Out[125]:

Multivariate Polynomial Ring in x1, x2, x3, e1, e2 over Rational Field graded by x1 -> [1 1 1] x2 -> [1 1 0] x3 -> [1 0 1] e1 -> [0 -1 0] e2 -> [0 0 -1]

We now recall the toric ideal-variety correspondence from proposition 5.2.7 in the book "Toric Varieties" by David Cox, Hal Schenk and John Little:

Let $X_\Sigma$ be a simplicial toric variety. Then there is a bijective correspondence $$ \{ \text{ closed subvarieties of $X_\Sigma$ } \} \leftrightarrow \{ \text{ radical homogeneous ideals $I \subseteq B(\Sigma) \subseteq S$} \} \, .$$ In this expression $B(\Sigma)$ is the irrelevant ideal. For instance, for $\mathrm{dP}_2$ we have:

In [126]:

```
irrelevant_ideal(dP2)
```

Out[126]:

ideal(x2*x3*e2, x1*x3*e2, x2*x3*e1, x1*x2*e1, x1*e1*e2)

Consequently, for every radical homogeneous ideal $I \subseteq B(\Sigma) \subseteq S$, we find a closed subvariety $V( I ) \subseteq X_\Sigma$ and every closed subvariety of a simplicial toric variety $X_\Sigma$ arises in this way.

An algebraic cycle is a formal linear sum of such closed subvarieties. Modulo rational equivalence, the algebraic cycles furnish the Chow ring. We can compute this ring as follows in OSCAR:

In [127]:

```
chow_ring(dP2)
```

Out[127]:

Quotient of Multivariate Polynomial Ring in x1, x2, x3, e1, e2 over Rational Field by ideal(x1 - x3 + e1, x2 - x3 + e1 - e2, x1*x2, x1*x3, e1*e2, x2*e2, x3*e1)

In [128]:

```
d = toric_divisor(dP2, [1, 2, 3, 4, 5]);
ac = rational_equivalence_class(d)
```

Out[128]:

Rational equivalence class on a normal toric variety represented by 6V(x3)+V(e1)+7V(e2)

So $ac$ is represented by an algebraic cycle which in turn is given by a formal linear sum of the closed subvarieties $V(x_3)$, $V(e_1)$ and $V(e_2)$, namely $6 V(x_3) + 1 V( e_1 ) + 7 V( e_2 )$.

Intersections of rational equivalence classes can be computed in OSCAR:

In [129]:

```
ac * ac
```

Out[129]:

Rational equivalence class on a normal toric variety represented by 34V(x2,x3)

If we only care about topological intersection numbers, then the intersection form suffices:

In [130]:

```
intersection_form(dP2)
```

Out[130]:

Dict{MPolyRingElem, QQFieldElem} with 15 entries: x1*x3 => 0 x3*e2 => 1 x1^2 => -1 x1*e1 => 1 e2^2 => -1 x3^2 => 0 x2*x3 => 1 e1*e2 => 0 x2*e1 => 1 x1*e2 => 1 x2^2 => 0 e1^2 => -1 x3*e1 => 0 x1*x2 => 0 x2*e2 => 0

Note that this is obtained upon normalization with the volume form:

In [131]:

```
volume_form(dP2)
```

Out[131]:

Cohomology class on a normal toric variety given by -e2^2

In [ ]:

```
```