# Toric Blowdown Morphisms (Experimental)

It is a common goal in algebraic geometry to resolve singularities. Certainly, (sub)varieties of toric varieties are no exception and we provide a growing set of functionality for such tasks.

In general, resolutions need not be toric. Indeed, some of the functionality below requires fully-fledge schemes machinery, which – as of this writing (October 2023) – is still in Oscar's experimental state. For this reason, the methods below should be considered experimental.

## Constructors

Blowups of toric varieties are obtained from star subdivisions of polyhedral fans. In the most general form, a star subdivision is defined by a new primitive element in the fan. Below, we refer to this new primitive element as `new_ray`

. In addition to this `new_ray`

, our design of toric blowdown morphisms requires an underlying toric morphism. With an eye towards covered schemes as possible return value, any toric blowdown morphism must also know (to compute) its blowup center in the form of an ideal sheaf. The following constructor allows to set this ideal sheaf center upon construction:

`toric_blowdown_morphism(bl::ToricMorphism, new_ray::AbstractVector{<:IntegerUnion}, center::AbsIdealSheaf)`

The "working-horse" constructor however is the following:

`toric_blowdown_morphism(Y::NormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}, coordinate_name::String)`

This constructor will, among others, construct the underlying toric morphism. In addition, we can then specify a name for the coordinate in the Cox ring that is assigned to `new_ray`

.

## Blowdown morphisms from blowing up toric varieties

The following methods blow up toric varieties. The center of the blowup can be provided in different formats. We discuss the methods in ascending generality.

For our most specialized blow-up method, we focus on the n-th cone in the fan of the variety `v`

in question. This cone need not be maximal! The ensuing star subdivision will subdivide this cone about its "diagonal" (the sum of all its rays). The result of this will always be a toric variety:

`blow_up`

— Method`blow_up(v::NormalToricVariety, n::Int; coordinate_name::String = "e")`

Blow up the toric variety by subdividing the n-th cone in the list of *all* cones of the fan of `v`

. This cone need not be maximal. This function returns the corresponding blowdown morphism.

By default, we pick "e" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> blow_down_morphism = blow_up(P3, 5)
Toric blowdown morphism
julia> bP3 = domain(blow_down_morphism)
Normal toric variety
julia> cox_ring(bP3)
Multivariate polynomial ring in 5 variables over QQ graded by
x1 -> [1 0]
x2 -> [0 1]
x3 -> [0 1]
x4 -> [1 0]
e -> [1 -1]
```

This function is part of the experimental code in Oscar. Please read here for more details.

More generally, we can provide a primitive element in the fan of the variety in question. The resulting star subdivision leads to a polyhedral fan, or put differently, the blow-up along this center is always toric:

`blow_up`

— Method`blow_up(v::NormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String = "e")`

Blow up the toric variety by subdividing the fan of the variety with the provided new ray. Note that this ray must be a primitive element in the lattice Z^d, with d the dimension of the fan. This function returns the corresponding blowdown morphism.

By default, we pick "e" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> blow_down_morphism = blow_up(P3, [0, 1, 1])
Toric blowdown morphism
julia> bP3 = domain(blow_down_morphism)
Normal toric variety
julia> cox_ring(bP3)
Multivariate polynomial ring in 5 variables over QQ graded by
x1 -> [1 0]
x2 -> [0 1]
x3 -> [0 1]
x4 -> [1 0]
e -> [1 -1]
julia> typeof(center(blow_down_morphism))
Oscar.ToricIdealSheafFromCoxRingIdeal{NormalToricVariety, AbsAffineScheme, Ideal, Map}
julia> Oscar.ideal_in_cox_ring(center(blow_down_morphism))
Ideal generated by
x2
x3
```

Notice that in the above example, the blowup center is not just an ideal sheaf. Rather, it is an ideal sheaf that knows its datum, in the form of an ideal, in the Cox ring. Sadly, we cannot always (at least not yet) compute such a datum. The following example demonstrates such a case.

**Examples**

```
julia> rs = [1 1; -1 1]
2×2 Matrix{Int64}:
1 1
-1 1
julia> max_cones = IncidenceMatrix([[1, 2]])
1×2 IncidenceMatrix
[1, 2]
julia> v = normal_toric_variety(max_cones, rs)
Normal toric variety
julia> bu = blow_up(v, [0, 1])
Toric blowdown morphism
julia> center(bu)
Sheaf of ideals
on normal, non-smooth toric variety
with restriction
1: Ideal (x_3_1, x_2_1, x_1_1)
julia> typeof(center(bu))
IdealSheaf{NormalToricVariety, AbsAffineScheme, Ideal, Map}
```

This function is part of the experimental code in Oscar. Please read here for more details.

Most generally, we encode the blowup center by a homogeneous ideal in the Cox ring. Such blowups center may easily lead to non-toric blowups, i.e. the return value of the following method could well be non-toric.

`blow_up`

— Method`blow_up(v::NormalToricVariety, I::MPolyIdeal; coordinate_name::String = "e")`

Blow up the toric variety by subdividing the cone in the list of *all* cones of the fan of `v`

which corresponds to the provided ideal `I`

. Note that this cone need not be maximal.

By default, we pick "e" as the name of the homogeneous coordinate for the exceptional divisor. As third optional argument one can supply a custom variable name.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> (x1,x2,x3,x4) = gens(cox_ring(P3))
4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
x1
x2
x3
x4
julia> I = ideal([x2,x3])
Ideal generated by
x2
x3
julia> bP3 = domain(blow_up(P3, I))
Normal toric variety
julia> cox_ring(bP3)
Multivariate polynomial ring in 5 variables over QQ graded by
x1 -> [1 0]
x2 -> [0 1]
x3 -> [0 1]
x4 -> [1 0]
e -> [1 -1]
julia> I2 = ideal([x2 * x3])
Ideal generated by
x2*x3
julia> b2P3 = blow_up(P3, I2);
julia> codomain(b2P3) == P3
true
```

This function is part of the experimental code in Oscar. Please read here for more details.

Instead of providing the ideal, it is possible to turn a homogeneous ideal in the Cox ring into an ideal sheaf. Consequently, we also provide the support for the following method.

`blow_up`

— Method`blow_up(m::NormalToricVariety, I::ToricIdealSheafFromCoxRingIdeal; coordinate_name::String = "e")`

Blow up the toric variety along the center given by a toric ideal sheaf.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> x1, x2, x3, x4 = gens(cox_ring(P3))
4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
x1
x2
x3
x4
julia> II = ideal_sheaf(P3, ideal([x1*x2]))
Sheaf of ideals
on normal toric variety
with restrictions
1: Ideal (x_1_1*x_2_1)
2: Ideal (x_2_2)
3: Ideal (x_1_3)
4: Ideal (x_1_4*x_2_4)
julia> blow_down_morphism = blow_up(P3, II)
Blowup
of normal toric variety
in sheaf of ideals with restrictions
1b: Ideal (x_1_1*x_2_1)
2b: Ideal (x_2_2)
3b: Ideal (x_1_3)
4b: Ideal (x_1_4*x_2_4)
with domain
scheme over QQ covered with 4 patches
1a: [x_1_1, x_2_1, x_3_1] scheme(0)
2a: [x_1_2, x_2_2, x_3_2] scheme(0)
3a: [x_1_3, x_2_3, x_3_3] scheme(0)
4a: [x_1_4, x_2_4, x_3_4] scheme(0)
and exceptional divisor
effective cartier divisor defined by
sheaf of ideals with restrictions
1a: Ideal (x_1_1*x_2_1)
2a: Ideal (x_2_2)
3a: Ideal (x_1_3)
4a: Ideal (x_1_4*x_2_4)
```

This function is part of the experimental code in Oscar. Please read here for more details.

## Attributes

`underlying_morphism`

— Method`underlying_morphism(bl::ToricBlowdownMorphism)`

Return the underlying toric morphism of a toric blowdown morphism. Access to other attributes such as `domain`

, `codomain`

, `covering_morphism`

are executed via `underlying_morphism`

.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> blow_down_morphism = blow_up(P3, [0, 1, 1])
Toric blowdown morphism
julia> Oscar.underlying_morphism(blow_down_morphism)
Toric morphism
```

`index_of_new_ray`

— Method`index_of_new_ray(bl::ToricBlowdownMorphism)`

Return the index of the new ray used in the construction of the toric blowdown morphism.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> blow_down_morphism = blow_up(P3, [0, 1, 1])
Toric blowdown morphism
julia> index_of_new_ray(blow_down_morphism)
5
```

This function is part of the experimental code in Oscar. Please read here for more details.

`center`

— Method`center(bl::ToricBlowdownMorphism)`

Return the center of the toric blowdown morphism as ideal sheaf.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> blow_down_morphism = blow_up(P3, [0, 1, 1])
Toric blowdown morphism
julia> center(blow_down_morphism)
Sheaf of ideals
on normal, smooth toric variety
with restrictions
1: Ideal (x_3_1, x_2_1)
2: Ideal (x_3_2, x_2_2)
3: Ideal (1)
4: Ideal (1)
```

This function is part of the experimental code in Oscar. Please read here for more details.

`exceptional_divisor`

— Method`exceptional_divisor(bl::ToricBlowdownMorphism)`

Return the exceptional divisor (as toric divisor) of the toric blowdown morphism.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> blow_down_morphism = blow_up(P3, [0, 1, 1])
Toric blowdown morphism
julia> exceptional_divisor(blow_down_morphism)
Torus-invariant, cartier, prime divisor on a normal toric variety
```

This function is part of the experimental code in Oscar. Please read here for more details.

Based on `underlying_morphism`

, also the following attributes of toric morphisms are supported for toric blowdown morphisms:

`grid_morphism(bl::ToricBlowdownMorphism)`

,`morphism_on_torusinvariant_weil_divisor_group(bl::ToricBlowdownMorphism)`

,`morphism_on_torusinvariant_cartier_divisor_group(bl::ToricBlowdownMorphism)`

,`morphism_on_class_group(bl::ToricBlowdownMorphism)`

,`morphism_on_picard_group(bl::ToricBlowdownMorphism)`

.

The total and strict transform of ideal sheaves along toric blowdown morphisms can be computed:

`total_transform`

— Method`total_transform(f::AbsSimpleBlowdownMorphism, II::IdealSheaf)`

Computes the total transform of an ideal sheaf along a blowdown morphism.

In particular, this applies in the toric setting. However, note that currently (October 2023), ideal sheaves are only supported on smooth toric varieties.

**Examples**

```
julia> P2 = projective_space(NormalToricVariety, 2)
Normal toric variety
julia> bl = blow_up(P2, [1, 1])
Toric blowdown morphism
julia> S = cox_ring(P2);
julia> x, y, z = gens(S);
julia> I = ideal_sheaf(P2, ideal([x*y]))
Sheaf of ideals
on normal, smooth toric variety
with restrictions
1: Ideal (x_1_1*x_2_1)
2: Ideal (x_2_2)
3: Ideal (x_1_3)
julia> total_transform(bl, I)
Sheaf of ideals
on normal toric variety
with restrictions
1: Ideal (x_1_1*x_2_1^2)
2: Ideal (x_1_2^2*x_2_2)
3: Ideal (x_2_3)
4: Ideal (x_1_4)
```

This function is part of the experimental code in Oscar. Please read here for more details.

## Arithmetics

Toric blowdown morphisms can be added, subtracted and multiplied by rational numbers. The results of such operations will be toric morphisms, i.e. no longer attributed to the blowup of a certain locus. Arithmetics among toric blowdown morphisms and general toric morphisms is also supported, as well as equality for toric blowdown morphisms.