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

Toric morphisms to morphisms of covered schemes #2779

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
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ morphism_on_torusinvariant_weil_divisor_group(tm::ToricMorphism)
morphism_on_torusinvariant_cartier_divisor_group(tm::ToricMorphism)
morphism_on_class_group(tm::ToricMorphism)
morphism_on_picard_group(tm::ToricMorphism)
covering_morphism(f::ToricMorphism)
```

### Special attributes of toric varieties
Expand Down
114 changes: 114 additions & 0 deletions src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,117 @@ Abelian group with structure: Z^2
codomain_projection = map_from_torusinvariant_cartier_divisor_group_to_picard_group(codomain_variety)
return domain_preinverse * morphism_on_cartier_divisors * codomain_projection
end


########################################################################
# Functionality for the associated CoveredSchemeMorphism #
########################################################################

@doc raw"""
covering_morphism(f::ToricMorphism)

For a given toric morphism `tm`, we can compute the corresponding
morphism of covered schemes. The following demonstrates this for the
blow-down morphism of a blow-up of the projective space.

# Examples
```jldoctest
julia> IP2 = projective_space(NormalToricVariety, 2)
Normal, non-affine, smooth, projective, gorenstein, fano, 2-dimensional toric variety without torusfactor

julia> bl = blow_up(IP2, [1, 1]);

julia> cov_bl = covering_morphism(bl);

julia> domain(cov_bl)
Covering
described by patches
1: normal, affine toric variety
2: normal, affine toric variety
3: normal, affine toric variety
4: normal, affine toric variety
in the coordinate(s)
1: [x_1_1, x_2_1]
2: [x_1_2, x_2_2]
3: [x_1_3, x_2_3]
4: [x_1_4, x_2_4]

julia> codomain(cov_bl)
Covering
described by patches
1: normal, affine toric variety
2: normal, affine toric variety
3: normal, affine toric variety
in the coordinate(s)
1: [x_1_1, x_2_1]
2: [x_1_2, x_2_2]
3: [x_1_3, x_2_3]
```
"""
@attr CoveringMorphism function covering_morphism(f::ToricMorphism)
# TODO: If f is a blowdown morphism, we can simplify
# the matchings of cones below.
X = domain(f)
Y = codomain(f)

# Find the image cones
codomain_cones = maximal_cones(Y)
domain_cones = maximal_cones(X)
A = matrix(grid_morphism(f))
image_cones = [positive_hull(matrix(ZZ, rays(c)) * A) for c in domain_cones]

# construct the corresponding morphism of rings
morphism_dict = IdDict{AbsSpec, AbsSpecMor}()
domain_cov = default_covering(X) # ordering of the patches must be the same as `maximal_cones`
codomain_cov = default_covering(Y)
for i in 1:n_maximal_cones(X)
U = domain_cov[i] # The corresponding chart in the domain
k = findfirst(x-> is_subset(image_cones[i], x), codomain_cones)
V = codomain_cov[k] # The chart in the codomain whose cone contains the image of the cone of U

wc1 = weight_cone(U)
hb_U = hilbert_basis(wc1) # corresponds to the variables of OO(U)
wc2 = weight_cone(V)
hb_V = hilbert_basis(wc2)

At = transpose(A) # the matrix for the dual of the lattice_map
hb_V_mat = matrix(ZZ, hb_V)
hb_V_img = hb_V_mat * At
hb_U_mat = matrix(ZZ, hb_U)
sol = solve_left(hb_U_mat, hb_V_img)
@assert sol*hb_U_mat == hb_V_img
@assert all(x->x>=0, sol)

# assemble the monomials where the variables of OO(V) are mapped
imgs = [prod(gens(OO(U))[k]^sol[i, k] for k in 1:ngens(OO(U)); init=one(OO(U))) for i in 1:nrows(sol)]
morphism_dict[U] = SpecMor(U, V, imgs)
end
return CoveringMorphism(domain_cov, codomain_cov, morphism_dict, check=false)
end

# Some helper functions for conversion.
# These are here, because we didn't know better and documentation on how to convert polymake
# objects is too poor to be used by us. Please improve if you know how to!
function _my_mult(u::PointVector{ZZRingElem}, A::ZZMatrix)
m = length(u)
m == nrows(A) || error("sizes incompatible")
n = ncols(A)
result = zero(MatrixSpace(ZZ, 1, n))
for k in 1:n
result[1, k] = sum(u[i]*A[i, k] for i in 1:m; init=zero(ZZ))
end
return result
end

function _to_ZZ_matrix(u::PointVector{ZZRingElem})
n = length(u)
result = zero(MatrixSpace(ZZ, 1, n))
for i in 1:n
result[1, i] = u[i]
end
return result
end

@attr CoveredSchemeMorphism function underlying_morphism(f::ToricMorphism)
return CoveredSchemeMorphism(domain(f), codomain(f), covering_morphism(f))
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@
# 1: The Julia type for ToricMorphisms
####################################################

@attributes mutable struct ToricMorphism
domain::NormalToricVarietyType
grid_morphism::GrpAbFinGenMap
codomain::NormalToricVarietyType
ToricMorphism(domain, grid_morphism, codomain) = new(domain, grid_morphism, codomain)
@attributes mutable struct ToricMorphism{
DomainType<:AbsCoveredScheme,
CodomainType<:AbsCoveredScheme,
BaseMorphismType
} <: AbsCoveredSchemeMorphism{
DomainType,
CodomainType,
BaseMorphismType,
ToricMorphism
}
domain::NormalToricVarietyType
grid_morphism::GrpAbFinGenMap
codomain::NormalToricVarietyType
function ToricMorphism(domain, grid_morphism, codomain)
result = new{typeof(domain), typeof(codomain), Nothing}(domain, grid_morphism, codomain)
end
end


Expand Down Expand Up @@ -202,3 +213,5 @@ end
function Base.show(io::IO, tm::ToricMorphism)
join(io, "A toric morphism")
end

Base.show(io::IO, ::MIME"text/plain", tm::ToricMorphism) = Base.show(pretty(io), tm)
38 changes: 37 additions & 1 deletion test/AlgebraicGeometry/ToricVarieties/toric_schemes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ using Test
end

IP1 = projective_space(NormalToricVariety, 1; set_attributes = set_attributes)
set_coordinate_names(IP1, ["x", "y"])
Y = IP1*IP1

@testset "Product of projective spaces" begin
Expand All @@ -29,6 +30,7 @@ using Test
end

IP2 = projective_space(NormalToricVariety, 2; set_attributes = set_attributes)
set_coordinate_names(IP2, ["x", "y", "z"])
X, iso = Oscar.forget_toric_structure(IP2)

@testset "Forget toric structure" begin
Expand All @@ -49,5 +51,39 @@ using Test
I = ideal(S, gens(S)[2:3])
II = IdealSheaf(IP3, I)
end


S = cox_ring(IP2)
(x, y, z) = gens(S)
I = IdealSheaf(IP2, ideal(S, [z*(x-y)]))
J = IdealSheaf(IP2, ideal(S, [x, y]))
bl = blow_up(IP2, [1, 1])
pb_I = pullback(bl, I)
pb_J = pullback(bl, J)

@testset "toric blowdown morphism as morphism of covered schemes" begin
@test scheme(I) === IP2
@test length(Oscar.maximal_associated_points(I)) == 2
@test length(Oscar.maximal_associated_points(pb_I)) == 3
@test dim(J) == 0
@test dim(pb_J) == 1
end

F2 = hirzebruch_surface(NormalToricVariety, 2; set_attributes = set_attributes)
f = toric_morphism(F2, matrix(ZZ, [[1], [0]]), IP1; check = true)
S = cox_ring(IP1)
(x, y) = gens(S)
K = IdealSheaf(IP1, ideal(S, [x]))
pb_K = pullback(f, K)
# The support of pb_K should be nothing but P1, it is the fiber
# of the P1-fibration that defines the Hirebruch surface over the
# point defined by K.
# TODO: Add a test that verifies that indeed pb_K is P1.
@testset "Hirzebruch surface as P1 fibration over P1" begin
@test length(Oscar.maximal_associated_points(K)) == 1
@test dim(K) == 0
@test length(Oscar.maximal_associated_points(pb_K)) == 1
@test dim(pb_K) == 1
@test is_smooth(subscheme(pb_K)) == true
end

end