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

Decomposition info #2504

Merged
14 changes: 14 additions & 0 deletions experimental/Schemes/CoveredScheme.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,16 @@ affine_refinements(C::Covering) = C.affine_refinements
U = Vector{AbsSpec}()
# TODO: Check that all weights are equal to one. Otherwise the routine is not implemented.
s = symbols(S)
decomp_info = IdDict{AbsSpec, Vector{RingElem}}()
for i in 0:r
R, x = polynomial_ring(kk, [Symbol("("*String(s[k+1])*"//"*String(s[i+1])*")") for k in 0:r if k != i])
phi = hom(S, R, vcat(gens(R)[1:i], [one(R)], gens(R)[i+1:r]), check=false)
I = ideal(R, phi.(gens(defining_ideal(X))))
push!(U, Spec(quo(R, I)[1]))
decomp_info[last(U)] = gens(OO(last(U)))[1:i]
end
result = Covering(U)
set_decomposition_info!(result, decomp_info)
for i in 1:r
for j in i+1:r+1
x = gens(base_ring(OO(U[i])))
Expand Down Expand Up @@ -146,11 +149,14 @@ end
U = Vector{AbsSpec}()
# TODO: Check that all weights are equal to one. Otherwise the routine is not implemented.
s = symbols(S)
decomp_info = IdDict{AbsSpec, Vector{RingElem}}()
for i in 0:r
R, x = polynomial_ring(kk, [Symbol("("*String(s[k+1])*"//"*String(s[i+1])*")") for k in 0:r if k != i])
push!(U, Spec(R))
decomp_info[last(U)] = gens(OO(last(U)))[1:i]
end
result = Covering(U)
set_decomposition_info!(result, decomp_info)
for i in 1:r
for j in i+1:r+1
x = gens(OO(U[i]))
Expand Down Expand Up @@ -193,6 +199,7 @@ end
# ideal sheaf is trivial on some affine open part.
if r == 0
result = Covering(Y)
set_decomposition_info!(result, Y, elem_type(OO(Y))[])
pU[Y] = identity_map(Y)
covered_projection = CoveringMorphism(result, result, pU, check=false)
set_attribute!(X, :covering_projection_to_base, covered_projection)
Expand All @@ -202,6 +209,7 @@ end
# TODO: Check that all weights are equal to one. Otherwise the routine is not implemented.
s = symbols(S)
# for each homogeneous variable, set up the chart
decomp_info = IdDict{AbsSpec, Vector{RingElem}}()
for i in 0:r
R_fiber, x = polynomial_ring(kk, [Symbol("("*String(s[k+1])*"//"*String(s[i+1])*")") for k in 0:r if k != i])
F = Spec(R_fiber)
Expand All @@ -211,8 +219,10 @@ end
patch = subscheme(ambient_space, elem_type(OO(ambient_space))[evaluate(f, vcat(fiber_vars[1:i], [one(OO(ambient_space))], fiber_vars[i+1:end])) for f in mapped_polys])
push!(U, patch)
pU[patch] = restrict(pY, patch, Y, check=false)
decomp_info[last(U)] = gens(OO(last(U)))[1:i]
end
result = Covering(U)
set_decomposition_info!(result, decomp_info)
for i in 1:r
for j in i+1:r+1
x = gens(base_ring(OO(U[i])))
Expand Down Expand Up @@ -252,22 +262,26 @@ end
# ideal sheaf is trivial on some affine open part.
if r == 0
result = Covering(Y)
set_decomposition_info!(result, Y, elem_type(OO(Y))[])
pU[Y] = identity_map(Y)
covered_projection = CoveringMorphism(result, result, pU, check=false)
set_attribute!(X, :covering_projection_to_base, covered_projection)
return result
end

decomp_info = IdDict{AbsSpec, Vector{RingElem}}()
s = symbols(S)
# for each homogeneous variable, set up the chart
for i in 0:r
R_fiber, x = polynomial_ring(kk, [Symbol("("*String(s[k+1])*"//"*String(s[i+1])*")") for k in 0:r if k != i])
F = Spec(R_fiber)
ambient_space, pF, pY = product(F, Y)
push!(U, ambient_space)
decomp_info[last(U)] = gens(OO(last(U)))[1:i]
pU[ambient_space] = pY
end
result = Covering(U)
set_decomposition_info!(result, decomp_info)
for i in 1:r
for j in i+1:r+1
x = ambient_coordinates(U[i])
Expand Down
70 changes: 61 additions & 9 deletions experimental/Schemes/LazyGlueing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
GD::GlueingDataType
compute_function::Function
compute_glueing_domains::Function
glueing_domains::Union{Tuple{PrincipalOpenSubset, PrincipalOpenSubset},
Tuple{SpecOpen, SpecOpen}}
G::AbsGlueing

function LazyGlueing(X::AbsSpec, Y::AbsSpec,
Expand All @@ -40,34 +42,84 @@ function underlying_glueing(G::LazyGlueing)
return G.G
end

@attr function glueing_domains(G::LazyGlueing) # TODO: Type annotation
if isdefined(G, :compute_glueing_domains)
return compute_glueing_domains(G)
function glueing_domains(G::LazyGlueing) # TODO: Type annotation
if !isdefined(G, :glueing_domains)
# If there was a function provided to do the extra computation, use it.
if isdefined(G, :compute_glueing_domains)
G.glueing_domains = G.compute_glueing_domains(G.GD)
else
# Otherwise default to computation of the whole glueing.
G.glueing_domains = glueing_domains(underlying_glueing(G))
end
end
# If no extra function was provided, fall back to computing the full glueing.
return glueing_domains(underlying_glueing(G))
return G.glueing_domains
end


### Preparations for some sample use cases
struct RestrictionDataIsomorphism
mutable struct RestrictionDataIsomorphism
G::AbsGlueing
i::AbsSpecMor
j::AbsSpecMor
i_res::SchemeMor
j_res::SchemeMor
function RestrictionDataIsomorphism(G::AbsGlueing, i::AbsSpecMor, j::AbsSpecMor)
return new(G, i, j)
end
end

struct RestrictionDataClosedEmbedding
mutable struct RestrictionDataClosedEmbedding
G::AbsGlueing
X::AbsSpec
Y::AbsSpec
UX::Scheme
VY::Scheme
function RestrictionDataClosedEmbedding(G::AbsGlueing, X::AbsSpec, Y::AbsSpec)
return new(G, X, Y)
end
end

function _compute_restriction(GD::RestrictionDataClosedEmbedding)
return restrict(GD.G, GD.X, GD.Y, check=false)
_compute_domains(GD) # Fills in the empty fields for the glueing domains
return restrict(GD.G, GD.X, GD.Y, GD.UX, GD.VY, check=false)
end

function _compute_domains(GD::RestrictionDataClosedEmbedding)
if isdefined(GD, :UX) && isdefined(GD, :VY)
return GD.UX, GD.UY
end
(U, V) = glueing_domains(GD.G)
if U isa PrincipalOpenSubset
GD.UX = PrincipalOpenSubset(GD.X, OO(GD.X)(lifted_numerator(complement_equation(U))))
GD.VY = PrincipalOpenSubset(GD.Y, OO(GD.Y)(lifted_numerator(complement_equation(V))))
return GD.UX, GD.VY
elseif U isa SpecOpen
GD.UX = intersect(GD.X, U, check=false)
GD.VY = intersect(GD.Y, V, check=false)
return GD.UX, GD.VY
end
end

function _compute_restriction(GD::RestrictionDataIsomorphism)
return restrict(GD.G, GD.i, GD.j, check=false)
_compute_domains(GD) # Fills in the empty fields for the glueing domains
return restrict(GD.G, GD.i, GD.j, GD.i_res, GD.j_res, check=false)
end

function _compute_domains(GD::RestrictionDataIsomorphism)
if !(isdefined(GD, :i_res) && isdefined(GD, :j_res))
U, V = glueing_domains(GD.G)

GD.i_res = restrict(GD.i, U, preimage(inverse(GD.i), U, check=false), check=false)
i_res_inv = restrict(inverse(GD.i), codomain(GD.i_res), U, check=false)
set_attribute!(GD.i_res, :inverse, i_res_inv)
set_attribute!(i_res_inv, :inverse, GD.i_res)

GD.j_res = restrict(GD.j, V, preimage(inverse(GD.j), V, check=false), check=false)
j_res_inv = restrict(inverse(GD.j), codomain(GD.j_res), V, check=false)
set_attribute!(GD.j_res, :inverse, j_res_inv)
set_attribute!(j_res_inv, :inverse, GD.j_res)
end
return codomain(GD.i_res), codomain(GD.j_res)
end

# Method for compatibility with internal methods of the glueings
Expand Down
53 changes: 34 additions & 19 deletions experimental/Schemes/WeilDivisor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -210,34 +210,49 @@ function intersect(D::WeilDivisor, E::WeilDivisor)
return result
end

function colength(I::IdealSheaf)
function colength(I::IdealSheaf; covering::Covering=default_covering(scheme(I)))
X = scheme(I)
C = default_covering(X)
patches_todo = copy(affine_charts(X))
patches_done = AbsSpec[]
result = 0
while length(patches_todo) != 0
U = pop!(patches_todo)
J = I(U)
# To avoid overcounting, throw away all components that
# were already visible in other charts.
for V in patches_done
if !haskey(glueings(C), (U, V))
continue
if has_decomposition_info(covering)
HechtiDerLachs marked this conversation as resolved.
Show resolved Hide resolved
h = decomposition_info(covering)[U]
# The elements in h indicate where components must
# be located so that they can not be spotted in other charts.
# We iteratively single out these components by adding a sufficiently high
# power of the equation to the ideal.
Comment on lines +223 to +226
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and this here how this can be brought to work.

The next step would be to automatically keep track of this information for blowups. Then integration of cycles should go through in little time once we allow weil divisor components to be non-prime.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need this information to down to subschemes.

for f in h
k = 0
while !(f^(k) in ideal(OO(U), f^(k+1)) + J)
k = k + 1
end
J = J + ideal(OO(U), f^k)
HechtiDerLachs marked this conversation as resolved.
Show resolved Hide resolved
isone(J) && break
end
G = C[U, V]
(UV, VU) = glueing_domains(G)
UV isa PrincipalOpenSubset || error("method is only implemented for simple glueings")
f = complement_equation(UV)
# Find a sufficiently high power of f such that it throws
# away all components away from the horizon, but does not affect
# those on the horizon itself.
k = 0
while !(f^(k) in ideal(OO(U), f^(k+1)) + J)
k = k + 1
else
# To avoid overcounting, throw away all components that
# were already visible in other charts.
for V in patches_done
if !haskey(glueings(covering), (U, V))
continue
end
G = covering[U, V]
(UV, VU) = glueing_domains(G)
UV isa PrincipalOpenSubset || error("method is only implemented for simple glueings")
f = complement_equation(UV)
# Find a sufficiently high power of f such that it throws
# away all components away from the horizon, but does not affect
# those on the horizon itself.
k = 0
while !(f^(k) in ideal(OO(U), f^(k+1)) + J)
k = k + 1
end
afkafkafk13 marked this conversation as resolved.
Show resolved Hide resolved
J = J + ideal(OO(U), f^k)
isone(J) && break
end
J = J + ideal(OO(U), f^k)
isone(J) && break
end
if !isone(J)
JJ = leading_ideal(saturated_ideal(J))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function simplify(C::Covering)
iY, jY = identification_maps(Ysimp)
G = GD[(X, Y)]
#new_glueings[(Xsimp, Ysimp)] = restrict(G, jX, jY, check=false)
new_glueings[(Xsimp, Ysimp)] = LazyGlueing(Xsimp, Ysimp, _compute_restriction,
new_glueings[(Xsimp, Ysimp)] = LazyGlueing(Xsimp, Ysimp, _compute_restriction, _compute_domains,
RestrictionDataIsomorphism(G, jX, jY)
)
end
Expand Down
27 changes: 27 additions & 0 deletions src/AlgebraicGeometry/Schemes/Covering/Objects/Attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,30 @@ function glueing_graph(C::Covering)
return C.glueing_graph
end

@doc raw"""
decomposition_info(C::Covering)

Return an `IdDict` `D` with the `patches` of `C` as keys and values `D[U]` a list
of elements ``f₁,…,fᵣ ∈ 𝒪(U)``. These elements are chosen so that for
``Xᵤ = V(f₁,…,fᵣ) ⊂ U`` the scheme ``X`` covered by ``C`` decomposes as a
disjoint union ``X = ∪ Xᵤ``.
HechtiDerLachs marked this conversation as resolved.
Show resolved Hide resolved

!!! note This attribute might not be defined!
HechtiDerLachs marked this conversation as resolved.
Show resolved Hide resolved
"""
function decomposition_info(C::Covering)
return C.decomp_info
end

function set_decomposition_info!(C::Covering, U::AbsSpec, f::Vector{<:RingElem})
if !isdefined(C, :decomp_info)
C.decomp_info = IdDict{AbsSpec, Vector{RingElem}}()
end
all(x->parent(x) === OO(U), f) || error("elements do not belong to the correct ring")
decomp_info(C)[U] = f
end

function set_decomposition_info!(C::Covering, D::IdDict{<:AbsSpec, <:Vector{<:RingElem}})
C.decomp_info = D
end

has_decomposition_info(C::Covering) = isdefined(C, :decomp_info)
1 change: 1 addition & 0 deletions src/AlgebraicGeometry/Schemes/Covering/Objects/Types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mutable struct Covering{BaseRingType}
glueing_graph::Graph{Undirected}
transition_graph::Graph{Undirected}
edge_dict::Dict{Tuple{Int, Int}, Int}
decomp_info::IdDict{<:AbsSpec, <:Vector{<:RingElem}}

function Covering(
patches::Vector{<:AbsSpec},
Expand Down
61 changes: 61 additions & 0 deletions src/AlgebraicGeometry/Schemes/Glueing/Constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ function restrict(G::AbsGlueing, X::AbsSpec, Y::AbsSpec; check::Bool=true)
return restrict(underlying_glueing(G), X, Y, check=check)
end

function restrict(G::AbsGlueing, X::AbsSpec, Y::AbsSpec,
Ures::Scheme, Vres::Scheme;
check::Bool=true
)
return restrict(underlying_glueing(G), X, Y, Ures, Vres, check=check)
end


function restrict(G::Glueing, X::AbsSpec, Y::AbsSpec; check::Bool=true)
U, V = glueing_domains(G)
f, g = glueing_morphisms(G)
Expand All @@ -119,6 +127,30 @@ function restrict(G::SimpleGlueing, X::AbsSpec, Y::AbsSpec; check::Bool=true)
return SimpleGlueing(X, Y, f_res, g_res, check=check)
end

function restrict(G::Glueing, X::AbsSpec, Y::AbsSpec,
Ures::SpecOpen, Vres::SpecOpen;
check::Bool=true
)
U, V = glueing_domains(G)
f, g = glueing_morphisms(G)
@check is_closed_embedding(intersect(X, ambient_scheme(U)), ambient_scheme(U)) "the scheme is not a closed in the ambient scheme of the open set"
@check is_closed_embedding(intersect(Y, ambient_scheme(V)), ambient_scheme(V)) "the scheme is not a closed in the ambient scheme of the open set"
return Glueing(X, Y, restrict(f, Ures, Vres, check=check), restrict(g, Vres, Ures, check=check), check=check)
end

function restrict(G::SimpleGlueing, X::AbsSpec, Y::AbsSpec,
UX::PrincipalOpenSubset, VY::PrincipalOpenSubset;
check::Bool=true
)
U, V = glueing_domains(G)
f, g = glueing_morphisms(G)
@check is_closed_embedding(intersect(X, ambient_scheme(U)), ambient_scheme(U)) "the scheme is not a closed in the ambient scheme of the open set"
@check is_closed_embedding(intersect(Y, ambient_scheme(V)), ambient_scheme(V)) "the scheme is not a closed in the ambient scheme of the open set"
f_res = restrict(f, UX, VY, check=check)
g_res = restrict(g, VY, UX, check=check)
return SimpleGlueing(X, Y, f_res, g_res, check=check)
end

########################################################################
# Identification of glueings under isomorphisms of patches #
########################################################################
Expand Down Expand Up @@ -154,6 +186,35 @@ function restrict(G::AbsGlueing, f::AbsSpecMor, g::AbsSpecMor; check::Bool=true)
)
end

function restrict(G::AbsGlueing, f::AbsSpecMor, g::AbsSpecMor,
f_res::SchemeMor, g_res::SchemeMor;
check::Bool=true
)
(X1, Y1) = patches(G)
X1 === domain(f) || error("maps not compatible")
X2 = codomain(f)
finv = inverse(f)

Y1 === domain(g) || error("maps not compatible")
Y2 = codomain(g)
ginv = inverse(g)

(h1, h2) = glueing_morphisms(G)

U2 = codomain(f_res)
V2 = codomain(f_res)

return Glueing(X2, Y2,
compose(inverse(f_res),
compose(h1, g_res)
),
compose(inverse(g_res),
compose(h2, f_res)
),
check=check
)
end

########################################################################
# Maximal extensions from SimpleGlueings #
########################################################################
Expand Down
Loading
Loading