We discuss the implementation of an algorithm to compute the GIT-fan for torus actions on affine varieties with symmetries, based on OSCAR. The algorithm combines computational techniques from commutative algebra, convex geometry and group theory. Applications of the algorithm (using the original implemenation in Singular) include the computation of the Mori chamber decomposition of the moving cone of $\overline{M}_{0,6}$.

In the following, we discuss Example 5.2 in the paper:

In [1]:
using Oscar
using GITFans

 -----    -----    -----      -      -----
|     |  |     |  |     |    | |    |     |
|     |  |        |         |   |   |     |
|     |   -----   |        |     |  |-----
|     |        |  |        |-----|  |   |
|     |  |     |  |     |  |     |  |    |
-----    -----    -----   -     -  -     -

...combining (and extending) ANTIC, GAP, Polymake and Singular
Version 0.6.0 ...
... which comes with absolutely no warranty whatsoever
(c) 2019-2021 by The Oscar Development Team


Let $K$ be an algebraically closed field of characteristic zero. The Cox ring of $M_{0,5}$ is isomorphic to the coordinate ring $R = K[T_1, \ldots , T_{10}]/a$ of the affine cone over the Grassmannian $\mathbb{G}(2, 5)$ where the ideal $a$ is generated by the Plücker relations and the $i$-th row of the matrix $Q$ is the degree $\operatorname{deg}(T_i)\in \mathbb{Z}^5$; this determines the $\mathbb{Z}^5$- grading of $R$.

In [2]:
# grading matrix
Q = [
1  1   0   0   0 ;
1  0   1   1   0 ;
1  0   1   0   1 ;
1  0   0   1   1 ;
0  1   0   0  -1 ;
0  1   0  -1   0 ;
0  1  -1   0   0 ;
0  0   1   0   0 ;
0  0   0   1   0 ;
0  0   0   0   1 ];

# polynomial ring
n = size(Q, 1)
Qt, T = PolynomialRing(QQ, :T => 1:n)
D = free_abelian_group(size(Q,2))
w = [D(Q[i, :]) for i = 1:n]
R = grade(Qt, w)

# generators for the ideal
a = ideal([
T[5]*T[10] - T[6]*T[9] + T[7]*T[8],
T[1]*T[9]  - T[2]*T[7] + T[4]*T[5],
T[1]*T[8]  - T[2]*T[6] + T[3]*T[5],
T[1]*T[10] - T[3]*T[7] + T[4]*T[6],
T[2]*T[10] - T[3]*T[9] + T[4]*T[8],
]);


We observe that there is an $S_5$-symmetry for the $H\cong (K^*)^5$-action on $V(a)$ where the symmetry group $S_5\cong G\subseteq S_{10}$ is generated by (2,3)(5,6)(9,10), (1,5,9,10,3)(2,7,8,4,6).

In [3]:
perms_list = [ [1,3,2,4,6,5,7,8,10,9], [5,7,1,6,9,2,8,4,10,3] ];
sym10 = symmetric_group(n);
G, emb = sub([sym10(x) for x in perms_list]...);
G

Out[3]:
Group([ (2,3)(5,6)(9,10), (1,5,9,10,3)(2,7,8,4,6) ])

We now compute the GIT-fan, represented as a fan in polymake, using Gröbner bases from Singular:

In [4]:
fanobj = GITFans.git_fan(a, Q, G)

Out[4]:
type
PolyhedralFan
GROUP
type: Group as PolyhedralFan::GROUP
RAYS
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
0 1 -1 0 0
0 1 0 -1 0
0 1 0 0 -1
0 1 0 0 0
1 0 0 1 1
1 0 1 0 1
1 0 1 1 0
1 0 1 1 1
1 1/2 1/2 1/2 1/2
1 1 0 0 0
1 1 0 0 1
1 1 0 1 0
1 1 0 1 1
1 1 1 0 0
1 1 1 0 1
1 1 1 1 0
1 2 0 0 0

We ask polymake to compute its F-vector:

In [5]:
fanobj.F_VECTOR

Out[5]:
pm::Vector<pm::Integer>
20 110 240 225 76

We now go into more details on the computation.

We compute the orbit cones as projections of a-faces and partition the set of orbit cones into orbits under the symmetry group action. We also return the action on the orbit cones in terms of GAP homomorphisms.

In [6]:
oc = GITFans.orbit_cone_orbits_and_action(a, Q, G);


Lengths of the orbit cone orbits:

In [7]:
map(length, oc[:orbit_list])

Out[7]:
4-element Vector{Int64}:
10
15
10
1

Action of the symmetry group permuting the elements of the first orbit cone orbit:

In [8]:
oc[:homs][1]

Out[8]:
$\text{Map from }G\to$Group([ (2,3)(4,6)(5,7), (1,2,4,6,7)(3,5,8,9,10) ])

We compute the GIT-fan in terms of a set of orbit representatives of maximal dimensional GIT-cones under the action of the given symmetry group, where the GIT-cones are described via hashes encoding the cones as intersections of orbits cones. The data structure also contains the group action on the hashes encoded as GAP homomorphisms.

The algorithm is based on a fan traversal.

The function also returns the incidence relation of the orbits of GIT-cones.

In [9]:
(hash_list, edges) = GITFans.fan_traversal(oc);


There are six maximal cones, up to G-symmetry.

In [10]:
length(hash_list)

Out[10]:
6

One of the GIT-cones encoded as a hash (the entries of the list correspond to the orbit cone orbits):

In [11]:
hash_list[1]

Out[11]:
4-element Vector{BitSet}:
BitSet([])
BitSet([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
BitSet([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
BitSet([1])

We translate the descriptions of the six maximal cones back to cone objects and expand their G-orbits.

In [12]:
expanded = GITFans.orbits_of_maximal_GIT_cones(oc, hash_list);
orbit_lengths = map(length, expanded)

Out[12]:
6-element Vector{Int64}:
1
10
30
20
10
5

There are in total 76 maximal cones.

In [13]:
sum(orbit_lengths)

Out[13]:
76

We create the GIT-Fan represented by a fan object in polymake:

In [14]:
fanobj = GITFans.hashes_to_polyhedral_fan(oc, hash_list)

Out[14]:
type
PolyhedralFan
GROUP
type: Group as PolyhedralFan::GROUP
RAYS
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
0 1 -1 0 0
0 1 0 -1 0
0 1 0 0 -1
0 1 0 0 0
1 0 0 1 1
1 0 1 0 1
1 0 1 1 0
1 0 1 1 1
1 1/2 1/2 1/2 1/2
1 1 0 0 0
1 1 0 0 1
1 1 0 1 0
1 1 0 1 1
1 1 1 0 0
1 1 1 0 1
1 1 1 1 0
1 2 0 0 0

We ask polymake to compute its F-vector:

In [15]:
fanobj.F_VECTOR

Out[15]:
pm::Vector<pm::Integer>
20 110 240 225 76