# Toric Blowups (Experimental)

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

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

We focus mainly on toric blowups given by a star subdivision of a polyhedral fan along a primitive vector, see 11.1 Star Subdivisions in [CLS11]. Below, we refer to this new primitive vector as `new_ray`

. The main constructor is the following

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

This will also construct the underlying toric morphism. We can specify the name for the coordinate in the Cox ring that is assigned to `new_ray`

using the optional argument `coordinate_name`

.

More generally, we can construct a blowup along a closed subscheme given by an ideal in the Cox ring or by an ideal sheaf of the corresponding covered scheme. In general, this will result in a non-toric variety.

## Constructors

The following methods blow up toric varieties. The closed subscheme along which the blowup is constructed can be provided in different formats. We discuss the methods in ascending generality.

For our most specialized blowup 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 morphism.

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

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> f = blow_up(P3, 5)
Toric blowup morphism
julia> bP3 = domain(f)
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 and construct a toric morphism as in Section 11.1 Star Subdivisions in [CLS11]. The resulting star subdivision leads to a polyhedral fan, or put differently, the blowup is always toric:

`blow_up`

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

Blow up the toric variety by subdividing the fan of the variety with the provided new ray. This function returns the corresponding morphism.

Note that this ray must be a primitive element in the lattice Z^d, with d the dimension of the fan. In particular, it is currently impossible to blow up along a ray which corresponds to a non-Q-Cartier divisor.

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

This function is type unstable. The type of the field `center_unnormalized`

is always a subtype of `AbsIdealSheaf`

(meaning that `center_unnormalized(f) isa Oscar.AbsIdealSheaf`

is always true). Sometimes, the function computes and sets the field `center_unnormalized`

for the output `f`

, giving it the type `ToricIdealSheafFromCoxRingIdeal`

(meaning that `center_unnormalized(f) isa Oscar.ToricIdealSheafFromCoxRingIdeal`

is true and `center_unnormalized(f) isa IdealSheaf`

is false). If it does not, then calling `center_unnormalized(f)`

computes and sets the field `center_unnormalized`

and it will have the type `IdealSheaf`

(meaning that `center_unnormalized(f) isa Oscar.ToricIdealSheafFromCoxRingIdeal`

is false and `center_unnormalized(f) isa IdealSheaf`

is true).

**Examples**

In the example below `center_unnormalized(f)`

has type `ToricIdealSheafFromCoxRingIdeal`

and we can access the corresponding ideal in the Cox ring using `Oscar.ideal_in_cox_ring`

.

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

In the below example, `center_unnormalized(f)`

has type `IdealSheaf`

and we cannot access the corresponding ideal in the Cox ring.

**Examples**

```
julia> rs = [1 1; -1 1]
2×2 Matrix{Int64}:
1 1
-1 1
julia> max_cones = incidence_matrix([[1, 2]])
1×2 IncidenceMatrix
[1, 2]
julia> v = normal_toric_variety(max_cones, rs)
Normal toric variety
julia> f = blow_up(v, [0, 1])
Toric blowup morphism
julia> center_unnormalized(f)
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_unnormalized(f))
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 closed subscheme along which we blow up by a homogeneous ideal in the Cox ring. Such blowups are often non-toric, 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 prime 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 a toric ideal sheaf.

This function is type unstable. The type of the domain of the output `f`

is always a subtype of `AbsCoveredScheme`

(meaning that `domain(f) isa AbsCoveredScheme`

is always true). Sometimes, the type of the domain will be a toric variety (meaning that `domain(f) isa NormalToricVariety`

is true) if the algorithm can successfully detect this. In the future, the detection algorithm may be improved so that this is successful more often.

**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> f = 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::ToricBlowupMorphism)`

Return the underlying toric morphism of a toric blowup. 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> f = blow_up(P3, [0, 1, 1])
Toric blowup morphism
julia> Oscar.underlying_morphism(f)
Toric morphism
```

`index_of_new_ray`

— Method`index_of_new_ray(bl::ToricBlowupMorphism)`

Return the index of the new ray used in the construction of the toric blowup.

**Examples**

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

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

`center_data`

— Method`center_data(bl::ToricBlowupMorphism)`

Returns the ideal, ideal sheaf or ray that was used to construct the morphism.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> f = blow_up(P3, [0, 2, 3])
Toric blowup morphism
julia> center_data(f)
3-element Vector{Int64}:
0
2
3
```

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

`center_unnormalized`

— Method`center_unnormalized(bl::ToricBlowupMorphism)`

Returns an ideal sheaf `I`

such that the normalization of the blowup along `I`

gives the morphism `bl`

.

**Examples**

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

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

`exceptional_prime_divisor`

— Method`exceptional_prime_divisor(bl::ToricBlowupMorphism)`

Return the exceptional prime Weil divisor (as a toric divisor) of the ray used to construct the toric blowup. Note that this divisor need not be Cartier and this divisor need not coincide with the locus where the morphism is not an isomorphism.

**Examples**

```
julia> P3 = projective_space(NormalToricVariety, 3)
Normal toric variety
julia> f = blow_up(P3, [0, 2, 3])
Toric blowup morphism
julia> E = exceptional_prime_divisor(f)
Torus-invariant, prime divisor on a normal toric variety
julia> is_cartier(E)
false
```

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 blowups:

`grid_morphism(bl::ToricBlowupMorphism)`

,`morphism_on_torusinvariant_weil_divisor_group(bl::ToricBlowupMorphism)`

,`morphism_on_torusinvariant_cartier_divisor_group(bl::ToricBlowupMorphism)`

,`morphism_on_class_group(bl::ToricBlowupMorphism)`

,`morphism_on_picard_group(bl::ToricBlowupMorphism)`

.

The total and strict transform of ideal sheaves along blowups, not necessarily toric, can be computed:

`total_transform`

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

Computes the total transform of an ideal sheaf along a blowup.

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 blowup 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 blowups can be added, subtracted and multiplied by rational numbers. The results of such operations will not be toric morphisms, i.e. they no longer correspond to the blowup of a certain closed subscheme. Arithmetics among toric blowups and general toric morphisms is also supported, as well as equality for toric blowups.