# Normal forms

## Normal form of toric surfaces

`CStarSurfaces.normal_form`

— Method`normal_form(X :: ToricSurface)`

Bring a toric surface into normal form. Here, we call a toric surface with generator matrix $P$ in normal form, if and only if:

- $P$ in Hermite normal form,
- neighbouring columns in $P$ are adjacent rays (i.e. the columns are sorted either clockwise or counterclockwise),
- $P$ is lexicographically minimal among all generator matrices satisfying 1. and 2.

These properties are enough to ensure that that two toric surfaces `X`

and `Y`

are isomorphic if and only if `gen_matrix(normal_form(X)) == gen_matrix(normal_form(Y))`

.

`CStarSurfaces.is_normal_form`

— Method`is_normal_form(X :: ToricSurface)`

Check whether a toric surface is in normal form.

`CStarSurfaces.are_isomorphic`

— Method`are_isomorphic(X :: ToricSurface, Y :: ToricSurface)`

Check whether two toric surfaces are isomorphic to each other.

## Types of admissible operations

`CStarSurfaces.AdmissibleOperation`

— Type`AdmissibleOperation`

Abstract Julia type for admissible operations on C-star surfaces. All subtypes `T <: AdmissibleOperation`

should at least implement the following functions:

```
(α :: T)(X :: CStarSurface)
Base.:*(α :: T, β :: T)
Base.one(α :: T)
Base.one(::Type{T})
Base.inv(α :: T)
```

`CStarSurfaces.InvertLastRow`

— Type`InvertLastRow <: AdmissibleOperation`

Julia type for an admissible operation that may or may not invert the last row in the generator matrix of a C-star surface. Geometrically, this means swapping source and sink of the C-star action.

`CStarSurfaces.InvertLastRow`

— Method`InvertLastRow(factor :: Int)`

Construct an admissible operation that multiplies the last row of the generator matrix of a C-star surface by `factor`

, which can take the values `1`

and `-1`

.

`CStarSurfaces.PermutationOfRays`

— Type`PermutationOfRays <: AdmissibleOperation`

Julia type for an admissible operation that permutes rays within the blocks of the generator matrix of C-star surfaces. Only permutations that are local to each block are permitted.

`CStarSurfaces.PermutationOfBlocks`

— Type`PermutationOfBlocks <: AdmissibleOperation`

Julia type for an admissible operation that permutes the blocks of the generator matrix of a C-star surface.

`CStarSurfaces.AdmissibleRowOperation`

— Type`AdmissibleRowOperation <: AdmissibleOperation`

Julia type for an admissible operation that adds integral multiples of the upper rows of the generator matrix of a C-star surface to its last row.

`CStarSurfaces.CompositeAdmissibleOperation`

— Type`CompositeAdmissibleOperation <: AdmissibleOperation`

Julia type for an admissible operation that arises as the composition of multiple admissible operations.

`CStarSurfaces.normalize_admissible_operation`

— Method`normalize_admissible_operation(γ :: CompositeAdmissibleOperation)`

Normalize a composite admissible operation by reordering the steps and merging multiple operations of the same kind into one. The resulting `CompositeAdmissibleOperation`

is guaranteed to consist of at most four admissible operations in the following order:

`InvertLastRow`

, `PermutationOfRays`

, `PermutationOfBlocks`

, `AdmissibleRowOperation`

.

If only one type of operation remains, that operation is returned instead.

## Normal form of $\mathbb{C}^*$-surfaces

`CStarSurfaces.beta_plus`

— Function`beta_plus(X :: CStarSurface)`

Return a `β :: DoubleVector`

with entries `β[i][j] == slopes(X)[i][j] - floor(maximum(slopes(X)[i]))`

`CStarSurfaces.beta_minus`

— Function`beta_minus(X :: CStarSurface)`

Return a `β :: DoubleVector`

with entries `β[i][j] == ceil(minimum(slopes(X)[i])) - slopes(X)[i][j]`

.

`CStarSurfaces.beta_plus_sorted`

— Function`beta_plus_sorted(X :: CStarSurface)`

Return the sorted `beta_plus(X)`

. Each vector in `beta_plus(X)`

are individually sorted and the vectors themselves are sorted by first by size and then lexicographically.

`CStarSurfaces.beta_minus_sorted`

— Function`beta_minus_sorted(X :: CStarSurface)`

Return the sorted `beta_minus(X)`

. Each vector in `beta_minus(X)`

are individually sorted and the vectors themselves are sorted by first by size and then lexicographically.

`CStarSurfaces.orientation`

— Function`orientation(X :: CStarSurface)`

Return the orientation of a C-star surface. This function takes the values `1`

, `0`

or `-1`

. Note that `orientation`

is not an isomorphy invariant, as applying `InvertLastRow(-1)`

inverts the orientation of a C-star surface. All other types of `AdmissibleOperation`

's leave the orientation invariant.

A C-star surface `X`

has orientation `1`

, if and only if one of the following conditions hold:

`X.case == :pe`

,`X.case ∈ [:ee, :pp]`

and`m_plus(X) > m_minus(X)`

,`X.case ∈ [:ee, :pp]`

and`m_plus(X) == m_minus(X)`

and`beta_plus_sorted(X) > beta_minus_sorted(X)`

.

Similarly, `X`

has orientation `-1`

if and only if one of the following conditions hold:

`X.case == :ep`

,`X.case ∈ [:ee, :pp]`

and`m_plus(X) < m_minus(X)`

,`X.case ∈ [:ee, :pp]`

and`m_plus(X) == m_minus(X)`

and`beta_plus_sorted(X) < beta_minus_sorted(X)`

.

The remaining case is that `X.case ∈ [:ee, :pp]`

and `m_plus(X) == m_minus(X)`

and `beta_plus_sorted(X) == beta_minus_sorted(X)`

, in which case `X`

has orientation `0`

.

`CStarSurfaces.normal_form`

— Method`normal_form(X :: CStarSurface)`

Compute the normal form of a C-star surface. Here, a C-star surface `X`

is said to be in normal form, if and only if the following properties hold:

`orientation(X) ≠ -1`

,`beta_plus(X) == beta_plus_sorted(X)`

,`0 ≤ X.d[i][1] < X.l[i][i]`

for all`1 ≤ i ≤ r`

, where`r+1 == nblocks(X)`

.

The third condition can also be phrased as `floor(maximum(slopes(X)[i])) == 0`

for all `1 ≤ i ≤ r`

.

The algorithm works by applying an `InvertLastRow`

operation to achieve 1., then applying `PermutationOfRays`

and `PermutationOfBlocks`

operations to achieve 2. and finally, applying an `AdmissibleRowOperation`

to achieve 3. Together, these properties are enough to ensure that `X`

and `Y`

are isomorphic if and only if they have the same normal form.

This function then returns a pair `(Y, α)`

, where `Y`

is a C-star surface in normal form and `α`

is an admissible operation with `α(X) == Y`

.

`CStarSurfaces.is_normal_form`

— Method`is_normal_form(X :: CStarSurface) = normal_form(X)[1] == X`

Check whether a C-star surface is in normal form, see the docstring of `normal_form`

.

`CStarSurfaces.are_isomorphic`

— Method`are_isomorphic(X :: CStarSurface, Y :: CStarSurface)`

Check whether two C-star surfaces are isomorphic to each other. This function returns a pair, where the first entry is a boolean and the second entry is either `nothing`

or an admissible operation turning `X`

into `Y`

.