Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blow up along minimal supercone coordinates #4437

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/src/AlgebraicGeometry/ToricVarieties/BlowupMorphisms.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ toric:
```@docs
blow_up(v::NormalToricVariety, exceptional_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String = "e")
```
The ray can alternatively be given using minimal supercone coordinates:
```@docs
blow_up_along_minimal_supercone_coordinates(v::NormalToricVarietyType, minimal_supercone_coords::AbstractVector{<:RationalUnion}; coordinate_name::Union{String, Nothing} = nothing)
```
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.
Expand Down
2 changes: 2 additions & 0 deletions docs/src/PolyhedralGeometry/fans.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ cones(PF::PolyhedralFan, cone_dim::Int)
cones(PF::PolyhedralFan)
minimal_supercone_coordinates(PF::PolyhedralFan, v::AbstractVector{<:RationalUnion})
minimal_supercone_indices(PF::PolyhedralFan, v::AbstractVector{<:RationalUnion})
is_minimal_supercone_coordinate_vector(PF::PolyhedralFan, v::AbstractVector{<:RationalUnion})
standard_coordinates(PF::PolyhedralFan, coords::AbstractVector{<:RationalUnion})
n_maximal_cones(PF::PolyhedralFan)
n_cones(PF::PolyhedralFan)
n_rays(PF::PolyhedralFan)
Expand Down
2 changes: 1 addition & 1 deletion docs/src/PolyhedralGeometry/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ The primitive generator, also called minimal generator, of a ray can be
accessed as follows:

```@docs
primitive_generator(r::RayVector)
primitive_generator(r::AbstractVector{T}) where T<:RationalUnion
```

`AbstractCollection[PointVector]` can be given as:
Expand Down
2 changes: 2 additions & 0 deletions experimental/Schemes/src/Schemes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export SpaceGerm

export ambient_germ
export basis_representation
export blow_up_along_minimal_supercone_coordinates
export complete_intersection_germ
export cox_ring_module_homomorphism
export defining_ring_element
Expand All @@ -53,6 +54,7 @@ export minimal_supercone_coordinates_of_exceptional_ray
export point
export rational_point_coordinates
export standard_covering
export standard_coordinates
export strict_transform
export strict_transform_with_index
export total_transform
Expand Down
25 changes: 25 additions & 0 deletions experimental/Schemes/src/ToricBlowups/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,31 @@ function blow_up(v::NormalToricVarietyType, exceptional_ray::AbstractVector{<:In
return ToricBlowupMorphism(v, blown_up_variety, coordinate_name, exceptional_ray, exceptional_ray, center_unnormalized)
end

@doc raw"""
blow_up_along_minimal_supercone_coordinates(v::NormalToricVarietyType, minimal_supercone_coords::AbstractVector{<:IntegerUnion}; coordinate_name::Union{String, Nothing} = nothing)

This method first constructs the ray `r` by calling `standard_coordinates`, then blows up `v` along `r` using `blow_up`.

# Examples

```jldoctest
julia> P2 = projective_space(NormalToricVariety, 2)
Normal toric variety

julia> f = blow_up_along_minimal_supercone_coordinates(P2, [2, 3, 0])
Toric blowup morphism
```
"""
function blow_up_along_minimal_supercone_coordinates(v::NormalToricVarietyType, minimal_supercone_coords::AbstractVector{<:RationalUnion}; coordinate_name::Union{String, Nothing} = nothing)
coords = Vector{QQFieldElem}(minimal_supercone_coords)
ray_QQ = Vector{QQFieldElem}(standard_coordinates(polyhedral_fan(v), coords))
ray = primitive_generator(ray_QQ)
@assert ray == ray_QQ "The input vector must correspond to a primitive generator of a ray"
phi = blow_up(v, ray; coordinate_name=coordinate_name)
set_attribute!(phi, :minimal_supercone_coordinates_of_exceptional_ray, coords)
return phi
end

@doc raw"""
blow_up(v::NormalToricVariety, n::Int; coordinate_name::String = "e")

Expand Down
9 changes: 9 additions & 0 deletions experimental/Schemes/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@
@test exceptional_prime_divisor(bl1) == toric_divisor(domain(bl1), [1,0,0,0])
end

@testset "Blow ups along minimal supercone coordinates" begin
P2 = projective_space(NormalToricVariety, 2)
f_1 = blow_up_along_minimal_supercone_coordinates(P2, [2, 3, 0])
f_2 = blow_up(P2, [2, 3])
pf_1 = polyhedral_fan(domain(f_1))
pf_2 = polyhedral_fan(domain(f_2))
@test Set(rays(pf_1)) == Set(rays(pf_2))
end

@testset "Total and strict transforms in Cox rings" begin
# Affine space, (2, 3)-blowup
X = affine_space(NormalToricVariety, 2)
Expand Down
77 changes: 72 additions & 5 deletions src/PolyhedralGeometry/PolyhedralFan/properties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ function cones(PF::_FanLikeType)
end

@doc raw"""
primitive_generator(r::RayVector) -> Vector{ZZRingElem}
primitive_generator(r::AbstractVector{T}) where T<:RationalUnion -> Vector{ZZRingElem}

Returns the primitive generator, also called minimal generator, of a ray.

Expand All @@ -302,10 +302,11 @@ julia> primitive_generator(r)
-1
```
"""
function primitive_generator(r::RayVector)
function primitive_generator(r::AbstractVector{T}) where {T<:RationalUnion}
result = numerator.(lcm([denominator(i) for i in r]) * r)
result = 1 / gcd(result) * result
convert(Vector{ZZRingElem}, result)
g = gcd(result)
result = map(x -> div(x, g), result)
return Vector{ZZRingElem}(result)
end

@doc raw"""
Expand Down Expand Up @@ -404,7 +405,7 @@ function minimal_supercone_coordinates(
PF::PolyhedralFan, v::AbstractVector{<:RationalUnion}
)
# This function probably only makes sense for fans with no lineality
@req is_pointed(PF) "PolyhedralFan must be pointed."
@req is_pointed(PF) "The polyhedral fan must be pointed."

inds = sort(collect(minimal_supercone_indices(PF, v)))
M_ZZ = matrix(ZZ, rays(PF))[inds, :]
Expand Down Expand Up @@ -440,6 +441,72 @@ function minimal_supercone_coordinates(
return result
end

@doc raw"""
is_minimal_supercone_coordinate_vector(PF::PolyhedralFan, v::AbstractVector{<:RationalUnion})
-> Bool

Given a pointed polyhedral fan `PF` and a vector `v` of length equal to
the number of rays of `PF`, this function checks that both of the
following are true:
* all of the entries of `v` are nonnegative,
* `v` is in some maximal cone of `PF`.

# Examples
```jldoctest
julia> PF = normal_fan(Oscar.simplex(3))
Polyhedral fan in ambient dimension 3

julia> is_minimal_supercone_coordinate_vector(PF, [1, 1, 1, 0])
true

julia> is_minimal_supercone_coordinate_vector(PF, [1, 1, 1, 1])
false
```
"""
function is_minimal_supercone_coordinate_vector(
PF::PolyhedralFan, v::AbstractVector{<:RationalUnion}
)
@req is_pointed(PF) "The polyhedral fan must be pointed."
@assert length(v) == n_rays(PF) "Length of v must match the number of rays."
isnothing(findfirst(x -> x < 0, v)) || return false
positive_indices = [i for i in 1:length(v) if v[i] > 0]
maximal_cones_incidence_matrix = maximal_cones(IncidenceMatrix, PF)
maximal_cones_indices = map(
i -> row(maximal_cones_incidence_matrix, i),
1:n_rows(maximal_cones_incidence_matrix),
)
for i in 1:n_rows(maximal_cones_incidence_matrix)
issubset(positive_indices, maximal_cones_indices[i]) && return true
end
return false
end

@doc raw"""
standard_coordinates(PF::PolyhedralFan, v::AbstractVector{<:RationalUnion})
-> Vector{QQFieldElem}

If `is_minimal_supercone_coordinate_vector(PF, v)` is true, then return the dot product of `v` and the vector of primitive generators of the rays of `PF`.

# Examples
```jldoctest
julia> PF = normal_fan(Oscar.simplex(3))
Polyhedral fan in ambient dimension 3

julia> standard_coordinates(PF, [1, 1, 0, 1])
3-element Vector{QQFieldElem}:
0
0
-1
```
"""
function standard_coordinates(PF::PolyhedralFan, coords::AbstractVector{<:RationalUnion})
@assert is_minimal_supercone_coordinate_vector(
PF, coords
) "Input vector must be a minimal supercone coordinate vector"
primitive_ray_generators = Vector{Vector{QQFieldElem}}(map(primitive_generator, rays(PF)))
return Vector{QQFieldElem}(sum(coords .* primitive_ray_generators))
end

###############################################################################
###############################################################################
### Access properties
Expand Down
3 changes: 2 additions & 1 deletion src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ export minimal_faces
export minimal_generating_set
export minimal_generator
export minimal_size_generating_set, has_minimal_size_generating_set, set_minimal_size_generating_set
export minimal_supercone_coordinates, minimal_supercone_indices
export minimal_supercone_coordinates, minimal_supercone_indices, is_minimal_supercone_coordinate_vector
export minimal_nonfaces
export minimal_normal_subgroups, has_minimal_normal_subgroups, set_minimal_normal_subgroups
export minimal_primes
Expand Down Expand Up @@ -1556,6 +1556,7 @@ export stable_set_polytope
export standard_basis
export standard_basis_highest_corner
export standard_basis_with_transformation_matrix
export standard_coordinates
export standard_tableaux
export stanley_reisner_ideal
export stanley_reisner_ring
Expand Down
8 changes: 8 additions & 0 deletions test/PolyhedralGeometry/polyhedral_fan.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ end
@test minimal_supercone_coordinates(PF, [-1, -1, 1]) == [0, 0, 2, 1]
@test issetequal(minimal_supercone_indices(PF, [-2//3, QQFieldElem(-4//3), 1]), [1, 3, 4])
@test minimal_supercone_coordinates(PF, [-2//3, -4//3, 1]) == [2//3, 0, 7//3, 4//3]

@test is_minimal_supercone_coordinate_vector(PF, [1, 1, 1, 0])
@test !is_minimal_supercone_coordinate_vector(PF, [1, 1, 1, 1])
@test !is_minimal_supercone_coordinate_vector(PF, [1, 1, -1, 0])

@test standard_coordinates(PF, [1, 2, 3, 0]) == [1, 2, 3]
@test standard_coordinates(PF, [1, 1, 0, 1]) == [0, 0, -1]
@test standard_coordinates(PF, [1, 0, 0, 1]) == [0, -1, -1]

# Construct a nonsimplicial fan
PF = face_fan(cube(3))
Expand Down
Loading