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

document and clean up algebraic cycles #4137

Merged
merged 17 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions docs/doc.main
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@
"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes.md",
"AlgebraicGeometry/Schemes/RationalPointsProjective.md",
"AlgebraicGeometry/Schemes/Sheaves.md",
"AlgebraicGeometry/Schemes/Cycles.md",
],
"Algebraic Sets" => [
"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet.md",
Expand Down
84 changes: 84 additions & 0 deletions docs/src/AlgebraicGeometry/Schemes/Cycles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
```@meta
CurrentModule = Oscar
```

# Cycles and divisors

## Algebraic Cycles
```@docs
AbsAlgebraicCycle{CoveredSchemeType<:AbsCoveredScheme, CoefficientRingType<:AbstractAlgebra.Ring}
```
### Constructors
```@docs
algebraic_cycle(X::AbsCoveredScheme, R::Ring)
algebraic_cycle(I::AbsIdealSheaf, R::Ring)
algebraic_cycle(I::AbsIdealSheaf)
```
### Properties
```@docs
scheme(D::AbsAlgebraicCycle)
components(D::AbsAlgebraicCycle)
dim(D::AbsAlgebraicCycle)
irreducible_decomposition(D::AbsAlgebraicCycle)
integral(W::AbsAlgebraicCycle; check::Bool=true)
```
### Attributes
```@docs
is_effective(A::AbsAlgebraicCycle)
is_prime(D::AbsAlgebraicCycle)
```
### Methods
```@docs
Base.:<=(A::AbsAlgebraicCycle,B::AbsAlgebraicCycle)
```

## Weil Divisors
```@docs
AbsWeilDivisor{CoveredSchemeType, CoefficientRingType}
```
### Constructors
```@docs
weil_divisor(X::AbsCoveredScheme, R::Ring)
weil_divisor(I::AbsIdealSheaf; check::Bool=true)
weil_divisor(I::AbsIdealSheaf, R::Ring; check::Bool=true)
```
### Methods
Besides the methods for [`AbsAlgebraicCycle`](@ref)
the following are available.
```@docs
colength(I::AbsIdealSheaf; covering::Covering=default_covering(scheme(I)))
is_in_linear_system(f::VarietyFunctionFieldElem, D::AbsWeilDivisor; regular_on_complement::Bool=false, check::Bool=true)
order_of_vanishing(f::VarietyFunctionFieldElem, D::AbsWeilDivisor; check::Bool=true)
intersect(D::AbsWeilDivisor, E::AbsWeilDivisor; covering::Covering=default_covering(scheme(D)))
```

## Linear Systems
```@docs
LinearSystem{DivisorType<:AbsWeilDivisor}
weil_divisor(L::LinearSystem)
variety(L::LinearSystem)
subsystem(L::LinearSystem, D::AbsWeilDivisor)
```

## Cartier Divisors
```@docs
CartierDivisor{CoveredSchemeType<:AbsCoveredScheme, CoeffType<:RingElem}
EffectiveCartierDivisor{CoveredSchemeType<:AbsCoveredScheme}
```
Cartier divisors support elementary arithmetic.
### Constructors
```@docs
effective_cartier_divisor(I::AbsIdealSheaf; trivializing_covering::Covering = default_covering(scheme(I)), check::Bool = true)
effective_cartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRingElem, MPolyQuoRingElem})
cartier_divisor(E::EffectiveCartierDivisor)
cartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRingElem, MPolyQuoRingElem})
```
### Attributes
```@docs
ideal_sheaf(C::EffectiveCartierDivisor)
scheme(C::EffectiveCartierDivisor)
scheme(C::CartierDivisor)
coefficient_ring(C::CartierDivisor)
components(C::CartierDivisor)
trivializing_covering(C::EffectiveCartierDivisor)
```
97 changes: 70 additions & 27 deletions src/AlgebraicGeometry/Schemes/Divisors/AlgebraicCycles.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@



########################################################################
#
# AbsAlgebraicCycle
Expand Down Expand Up @@ -39,25 +36,42 @@ getindex(D::AbsAlgebraicCycle, I::AbsIdealSheaf) = getindex(underlying_cycle(D),
@doc raw"""
components(D::AbsAlgebraicCycle)

Return the irreducible components ``Eⱼ`` of the divisor
``D = Σⱼ aⱼ ⋅ Eⱼ``.
Return a list of ideal sheaves such that `D` is a linear combination of
the corresponding cycles.

!!! note
The only guarantee on the ideal sheaves is that they are equidimensional.

See [`irreducible_decomposition(::AbsAlgebraicCycle)`](@ref)
for the more conventional decomposition.

The order of the components may change in between julia sessions.
"""
components(D::AbsAlgebraicCycle) = components(underlying_cycle(D))

# Return the coefficient ring over which the cycle is defined
coefficient_ring(D::AbsAlgebraicCycle) = coefficient_ring(underlying_cycle(D))

# All `components` of a cycle `D` must be prime. This returns the supremum
# of their dimensions.

@doc raw"""
dim(D::AbsAlgebraicCycle)

Return the dimension of the support of the cycle `D`.
"""
dim(D::AbsAlgebraicCycle) = dim(underlying_cycle(D))

set_name!(X::AbsAlgebraicCycle, name::String) = set_attribute!(X, :name, name)
name(X::AbsAlgebraicCycle) = get_attribute(X, :name)::String
has_name(X::AbsAlgebraicCycle) = has_attribute(X, :name)

function setindex!(D::AbsAlgebraicCycle, c::RingElem, I::AbsIdealSheaf)
@doc raw"""
setindex!(D::AbsAlgebraicCycle, c::RingElem, I::AbsIdealSheaf)

Set the coefficient of `D` at `I` to `c`.
"""
function setindex!(D::AbsAlgebraicCycle, c::RingElem, I::AbsIdealSheaf; check::Bool=true)
parent(c) === coefficient_ring(D) || error("coefficient does not belong to the correct ring")
return setindex!(underlying_cycle(D), c, I)
return setindex!(underlying_cycle(D), c, I; check)
end

# Non user-facing getters
Expand All @@ -76,10 +90,39 @@ function coeff(D::AbsAlgebraicCycle, I::AbsIdealSheaf)
end
end

@doc raw"""
is_effective(A::AbsAlgebraicCycle)

Return whether all the coefficients are non-negative.
"""
function is_effective(A::AbsAlgebraicCycle)
return all(coeff(A, I)>=0 for I in components(A))
end

# Prime cycles are those written as 1*Sheaf of prime ideals
@doc raw"""
is_prime(D::AbsAlgebraicCycle)

An algebraic cycle is called prime if it consists of a single irreducible subvariety.

Note that this property is not stable under base extension.
"""
@attr Bool function is_prime(D::AbsAlgebraicCycle)
length(components(D)) == 0 && return false # Cannot be prime if there are no components
E = irreducible_decomposition(D)
C = coefficient_dict(E)
length(C)>1 && return false
return isone(first(values(C)))
end

is_irreducible(D::AbsAlgebraicCycle) = is_prime(D)


@doc raw"""
Base.:<=(A::AbsAlgebraicCycle, B::AbsAlgebraicCycle)

$A \leq B$ if and only if $B - A$ is effective.
"""
function Base.:<=(A::AbsAlgebraicCycle,B::AbsAlgebraicCycle)
for I in components(A)
coeff(A, I) <= coeff(B, I) || return false
Expand Down Expand Up @@ -107,8 +150,9 @@ set_name!(X::AlgebraicCycle, name::String) = set_attribute!(X, :name, name)
name(X::AlgebraicCycle) = get_attribute(X, :name)::String
has_name(X::AlgebraicCycle) = has_attribute(X, :name)

function setindex!(D::AlgebraicCycle, c::RingElem, I::AbsIdealSheaf)
function setindex!(D::AlgebraicCycle, c::RingElem, I::AbsIdealSheaf; check::Bool=true)
parent(c) === coefficient_ring(D) || error("coefficient does not belong to the correct ring")
@check is_equidimensional(I)
coefficient_dict(D)[I] = c
end

Expand All @@ -118,13 +162,13 @@ end
Return the zero `AlgebraicCycle` over `X` with coefficients
in `R`.
"""
function AlgebraicCycle(X::AbsCoveredScheme, R::Ring)
function AlgebraicCycle(X::AbsCoveredScheme, R::Ring; check::Bool=true)
D = IdDict{AbsIdealSheaf, elem_type(R)}()
return AlgebraicCycle(X, R, D)
return AlgebraicCycle(X, R, D; check)
end

function zero(D::AbsAlgebraicCycle)
return AlgebraicCycle(scheme(D), coefficient_ring(D))
function zero(D::AbsAlgebraicCycle; check::Bool=true)
return AlgebraicCycle(scheme(D), coefficient_ring(D); check)
end

# provide non-camelcase methods
Expand Down Expand Up @@ -152,25 +196,24 @@ Zero algebraic cycle
with coefficients in integer ring
```
"""
algebraic_cycle(X::AbsCoveredScheme, R::Ring) = AlgebraicCycle(X, R)
algebraic_cycle(X::AbsCoveredScheme, R::Ring; check::Bool=true) = AlgebraicCycle(X, R; check)

@doc raw"""
AlgebraicCycle(I::AbsIdealSheaf, R::Ring)

Return the `AlgebraicCycle` ``D = 1 ⋅ V(I)`` with coefficients
in ``R`` for a sheaf of prime ideals ``I``.
Return the `AlgebraicCycle` ``D = colength(I) ⋅ V(I)`` with coefficients
in ``R`` for an equidimensional sheaf of ideals ``I``.
"""
simonbrandhorst marked this conversation as resolved.
Show resolved Hide resolved
function AlgebraicCycle(I::AbsIdealSheaf, R::Ring)
D = AlgebraicCycle(space(I), R)
function AlgebraicCycle(I::AbsIdealSheaf, R::Ring; check::Bool=true)
D = AlgebraicCycle(space(I), R; check)
D[I] = one(R)
return D
end

@doc raw"""
algebraic_cycle(I::AbsIdealSheaf, R::Ring) -> AlgebraicCycle

Return the `AlgebraicCycle` ``D = 1 ⋅ V(I)`` with coefficients
in ``R`` for a sheaf of prime ideals ``I``.
Return the `AlgebraicCycle` defined by the equidimensional ideal sheaf `I`.

simonbrandhorst marked this conversation as resolved.
Show resolved Hide resolved
# Examples
```jldoctest
Expand Down Expand Up @@ -198,8 +241,8 @@ algebraic_cycle(I::AbsIdealSheaf, R::Ring) = AlgebraicCycle(I, R)
@doc raw"""
AlgebraicCycle(I::AbsIdealSheaf)

Return the `AlgebraicCycle` ``D = 1 ⋅ V(I)`` with coefficients
in ``ℤ`` for a sheaf of prime ideals ``I``.
Return the `AlgebraicCycle` ``D = 1 ⋅ I`` with coefficients
in ``ℤ`` for a sheaf of equidimensional ideals ``I``.
"""
function AlgebraicCycle(I::AbsIdealSheaf)
D = AlgebraicCycle(space(I), ZZ)
Expand All @@ -210,8 +253,8 @@ end
@doc raw"""
algebraic_cycle(I::AbsIdealSheaf) -> AlgebraicCycle

Return the `AlgebraicCycle` ``D = 1 ⋅ V(I)`` with coefficients
in ``ℤ`` for a sheaf of prime ideals ``I``.
Return the `AlgebraicCycle` ``D = 1 ⋅ I`` with coefficients
in ``ℤ`` for a sheaf of equidimensional ideals ``I``.

# Examples
```jldoctest
Expand Down Expand Up @@ -330,7 +373,7 @@ function Base.show(io::IO, D::AlgebraicCycle)
end


@attr Any function dim(D::AlgebraicCycle)
@attr Int function dim(D::AlgebraicCycle)
result = -1
for I in components(D)
d = dim(I)
Expand Down Expand Up @@ -402,7 +445,7 @@ end
@doc raw"""
irreducible_decomposition(D::AbsAlgebraicCycle)

Return a divisor ``E`` equal to ``D`` but as a formal sum ``E = ∑ₖ aₖ ⋅ Iₖ``
Return a cycle ``E`` equal to ``D`` but as a formal sum ``E = ∑ₖ aₖ ⋅ Iₖ``
where the `components` ``Iₖ`` of ``E`` are all sheaves of prime ideals.
"""
function irreducible_decomposition(D::AbsAlgebraicCycle)
Expand Down
Loading
Loading