Skip to content

Commit

Permalink
Toric morphisms to morphisms of covered schemes (#2779)
Browse files Browse the repository at this point in the history
  • Loading branch information
HechtiDerLachs authored and antonydellavecchia committed Sep 19, 2023
1 parent 01c557c commit 7e9812e
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 6 deletions.
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 @@ -153,3 +153,117 @@ Map: GrpAb: Z^2 -> GrpAb: 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 @@ -196,3 +207,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

0 comments on commit 7e9812e

Please sign in to comment.