Double complexes – the user's interface
We briefly review the mathematical notion of a double complex. Let $\mathcal A$ be an Abelian category. A double complex $D_{\bullet, \bullet}$ consists of a collection of objects $D_{i, j}$ in $\mathcal A$ with indices $(i, j) \in \mathbb Z^2$ and usually arranged in a matrix-like grid, together with two collections of morphisms $D_{i, j} \to D_{i \pm 1, j}$, the horizontal morphisms, and $D_{i, j} \to D_{i, j \pm 1}$, the vertical morphisms, so that both the rows and the columns of $D_{\bullet, \bullet}$ are complexes in the classical sense and such that all resulting squares of maps commute.
In practice one usually encounters complexes which are bounded in the sense that outside some specified area of indices $(i, j) \in \mathbb Z^2$ the entries $D_{i, j}$ are all zero. Such entries are then usually omitted.
Basic getters and attributes
In OSCAR the generic functionality for double complexes is declared for the abstract type AbsDoubleComplexOfMorphisms
. These functions comprise
getindex(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int) # Get the `(i,j)`-th entry of `D`
horizontal_map
— Methodhorizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
Return the morphism $dc[i, j] → dc[i ± 1, j]$ (the sign depending on the horizontal_direction
of dc
).
This function is part of the experimental code in Oscar. Please read here for more details.
vertical_map
— Methodvertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
Return the morphism $dc[i, j] → dc[i, j ± 1]$ (the sign depending on the vertical_direction
of dc
).
This function is part of the experimental code in Oscar. Please read here for more details.
In which direction the maps in the rows and columns go can be asked with the following methods:
horizontal_direction
— Methodhorizontal_direction(dc::AbsDoubleComplexOfMorphisms)
Return a symbol :chain
or :cochain
depending on whether the morphisms of the rows of dc
decrease or increase the (co-)homological index.
This function is part of the experimental code in Oscar. Please read here for more details.
vertical_direction
— Methodvertical_direction(dc::AbsDoubleComplexOfMorphisms)
Return a symbol :chain
or :cochain
depending on whether the morphisms of the columns of dc
decrease or increase the (co-)homological index.
This function is part of the experimental code in Oscar. Please read here for more details.
Double complexes can be bounded or unbounded. It is important to note that even if such bounds exist and are known, this is a priori not related to whether or not certain entries are computable! I.e. even in the case of a bounded complex dc
it might still be valid to call dc[i, j]
beyond that bound. In general, one should use the following functions to determine whether or not it is legitimate to ask for a specific entry.
has_index
— Methodhas_index(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
Return true
if the (i, j)
-th entry of D
is already known, false
otherwise.
If the result is false
, then it might nevertheless still be possible to compute D[i, j]
; use can_compute_index
for such queries.
This function is part of the experimental code in Oscar. Please read here for more details.
can_compute_index
— Methodcan_compute_index(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
Return true
if the entry D[i, j]
is known or D
knows how to compute it.
This function is part of the experimental code in Oscar. Please read here for more details.
has_horizontal_map
— Methodhas_horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
Checks whether the double complex dc
has the horizontal morphism dc[i, j] → dc[i ± 1, j]
, the sign depending on the horizontal_direction
of dc
.
If this returns false
this might just mean that the map has not been computed, yet. Use can_compute_horizontal_map
to learn whether or not this is possible.
This function is part of the experimental code in Oscar. Please read here for more details.
can_compute_horizontal_map
— Methodcan_compute_horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
Return true
if dc
can compute the horizontal morphism dc[i, j] → dc[i ± 1, j]
, the sign depending on the horizontal_direction
of dc
, and false
otherwise.
This function is part of the experimental code in Oscar. Please read here for more details.
has_vertical_map
— Methodhas_vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
Checks whether the double complex dc
has the vertical morphism dc[i, j] → dc[i, j ± 1]
, the sign depending on the vertical_direction
of dc
.
If this returns false
this might just mean that the map has not been computed, yet. Use can_compute_vertical_map
to learn whether or not this is possible.
This function is part of the experimental code in Oscar. Please read here for more details.
can_compute_vertical_map
— Methodcan_compute_vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
Return true
if dc
can compute the vertical morphism dc[i, j] → dc[i, j ± 1]
, the sign depending on the vertical_direction
of dc
, and false
otherwise.
This function is part of the experimental code in Oscar. Please read here for more details.
Explicitly known bounds for the non-zero entries of a complex are nevertheless relevant for various generic functionalities. For example, computing a total complex is only possible in practice if one has an a priori estimate where the non-zero entries are located. For such purposes, we provide the following functionality:
has_upper_bound
— Methodhas_upper_bound(D::AbsDoubleComplexOfMorphisms)
Return true
if a universal upper bound $j ≤ B$ for non-zero D[i, j]
is known; false
otherwise.
This function is part of the experimental code in Oscar. Please read here for more details.
has_lower_bound
— Methodhas_lower_bound(D::AbsDoubleComplexOfMorphisms)
Return true
if a universal upper bound $B ≤ j$ for non-zero D[i, j]
is known; false
otherwise.
This function is part of the experimental code in Oscar. Please read here for more details.
has_right_bound
— Methodhas_right_bound(D::AbsDoubleComplexOfMorphisms)
Return true
if a universal upper bound $i ≤ B$ for non-zero D[i, j]
is known; false
otherwise.
This function is part of the experimental code in Oscar. Please read here for more details.
has_left_bound
— Methodhas_left_bound(D::AbsDoubleComplexOfMorphisms)
Return true
if a universal upper bound $B ≤ i$ for non-zero D[i, j]
is known; false
otherwise.
This function is part of the experimental code in Oscar. Please read here for more details.
If they exist, these bounds can be asked for using
right_bound
— Methodright_bound(D::AbsDoubleComplexOfMorphisms)
Return a bound $B$ such that D[i, j]
can be assumed to be zero for $i > B$. Whether or not requests for D[i, j]
beyond that bound are legitimate can be checked using can_compute_index
.
This function is part of the experimental code in Oscar. Please read here for more details.
left_bound
— Methodleft_bound(D::AbsDoubleComplexOfMorphisms)
Return a bound $B$ such that D[i, j]
can be assumed to be zero for $i < B$. Whether or not requests for D[i, j]
beyond that bound are legitimate can be checked using can_compute_index
.
This function is part of the experimental code in Oscar. Please read here for more details.
upper_bound
— Methodupper_bound(D::AbsDoubleComplexOfMorphisms)
Return a bound $B$ such that D[i, j]
can be assumed to be zero for $j > B$. Whether or not requests for D[i, j]
beyond that bound are legitimate can be checked using can_compute_index
.
This function is part of the experimental code in Oscar. Please read here for more details.
lower_bound
— Methodlower_bound(D::AbsDoubleComplexOfMorphisms)
Return a bound $B$ such that D[i, j]
can be assumed to be zero for $j < B$. Whether or not requests for D[i, j]
beyond that bound are legitimate can be checked using can_compute_index
.
This function is part of the experimental code in Oscar. Please read here for more details.
It is also possible to query whether or not a double complex is already complete in the sense that it knows about all of its non-zero entries.
is_complete
— Methodis_complete(dc::AbsDoubleComplexOfMorphisms)
Return true
if for all indices (i, j)
with has_index(dc, i, j) = true
and dc[i, j]
non-zero, the vertex (i, j)
is lying on an "island" of non-zero entries in the grid of the double complex, which is bounded by either zero entries or entries for indices (i', j')
where can_compute_index(dc, i', j') = false
. At least one index dc[i, j]
must be known for this to return true
.
⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
… → ? → ? → ? → ? → ? → ? → ? → ? → ? → ? → ? → 0 → 0 → ? → - → - → …
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
… → ? → ? → 0 → 0 → 0 → ? → ? → 0 → 0 → 0 → 0 → * → * → 0 → - → - → …
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
… → 0 → 0 → * → * → * → 0 → ? → 0 → ? → 0 → 0 → * → * → * → - → - → …
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
… → 0 → * → * → * → 0 → ? → ? → 0 → 0 → ? → 0 → * → 0 → * → - → - → …
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
… → 0 → * → * → * → 0 → ? → 0 → 0 → 0 → 0 → * → * → 0 → 0 → - → - → …
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
… → ? → 0 → 0 → 0 → ? → ? → ? → ? → ? → ? → 0 → 0 → ? → ? → - → - → …
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
Example of a pattern of a double complex with is_complete = true
. 0
: zero entry -
: entry can not be computed (can_compute_index
returns false
) *
: non-zero entry which has been computed ?
: entry can be computed, but that has not yet been done
!!! note If the double complex has several of the above "islands", then is_complete
might return true
even though one or more of the "islands" have not yet been uncovered. Use this carefully if your full double complex might be separated by zero entries!
This function is part of the experimental code in Oscar. Please read here for more details.
Generic functionality
total_complex
— Methodtotal_complex(D::AbsDoubleComplexOfMorphisms)
Construct the total complex of the double complex D
.
Note that D
needs to be reasonably bounded for this to work so that the strands $⨁ ᵢ₊ⱼ₌ₖ Dᵢⱼ$ are finite for every k
. Moreover, the generic code uses the internal function _direct_sum
. See the docstring of that function to learn more.
This function is part of the experimental code in Oscar. Please read here for more details.
Constructors
tensor_product
— Methodtensor_product(C::ComplexOfMorphisms{ChainType}, D::ComplexOfMorphisms{ChainType}) where {ChainType}
Create the tensor product of two complexes C
and D
as a double complex.
In order for the generic implementation to work for your specific ChainType
the following needs to be implemented.
morphism_type(ChainType)
must produce the type of morphisms between objects of typeChainType
;- the call signature for
function (fac::TensorProductFactory{ChainType})(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
needs to be overwritten for your specific instance ofChainType
to produce the(i, j)
-th entry of the double complex, i.e. the tensor product ofC[i]
andD[j]
; - the call signature for
function (fac::HorizontalTensorMapFactory{ChainType})(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
needs to be overwritten to produce the map on tensor productsC[i] ⊗ D[j] → C[i±1] ⊗ D[j]
induced by the (co-)boundary map onC
(the sign depending on thetyp
ofC
); - similarly for the
VerticalTensorMapFactory
.
See the file experimental/DoubleComplex/src/tensor_products.jl
for examples.
This function is part of the experimental code in Oscar. Please read here for more details.