Public API
Ripserer
Ripserer.ripserer
— Functionripserer(dists::AbstractMatrix; kwargs...)
ripserer(points; metric=Distances.Euclidean(), births, kwargs...)
ripserer(filtration::AbstractFiltration; kwargs...)
Compute the persistent homology of metric space represented by dists
, points
, and metric
or a Ripserer.AbstractFiltration
.
If using points, points
must be an array of isbits
types, such as NTuple
s or SVector
s.
Keyword Arguments
dim_max
: compute persistent homology up to this dimension. Defaults to1
.modulus
: compute persistent homology with coefficients in the prime field of integers modmodulus
. Defaults to2
.field_type
: use this type of field of coefficients. Defaults toRipserer.Mod
{modulus}
.threshold
: compute persistent homology up to diameter smaller than threshold. This parameter is only applicable when using distance matrices or points as input. When using filtrations, threshold must be passed to the filtration constructor. Defaults to the radius of the input space. When using low thresholds with points or distance matrices, consider usingSparseRips
.cutoff
: only keep intervals withpersistence(interval) > cutoff
. Defaults to0
.reps
: iftrue
, return representative cocycles along with persistence intervals. Defaults tofalse
.progress
: Iftrue
, show a progress bar. Defaults tofalse
.metric
: when calculating persistent homology from points, any metric fromDistances.jl
can be used. Defaults toDistances.Euclidean()
.cohomology
: if set tofalse
, compute persistent homology instead of cohomology. This is much slower and gives the same result, but may give more informative representatives whenreps
is enabled. Currently unable to compute infinite intervals in dimensions higher than 0. Defaults tofalse
.
Filtrations
Ripserer.Rips
— TypeRips{I, T} <: AbstractRipsFiltration{I, T}
This type represents a filtration of Vietoris-Rips complexes. Diagonal items are treated as vertex birth times.
Threshold defaults to the radius of the input space. When using low threshold
s, consider using SparseRips
instead. It will give the same result, but may be much faster.
Constructors
Rips(distance_matrix; threshold=nothing)
Rips(points; metric=Euclidean(), threshold=nothing)
Rips{I}(args...)
:I
sets the size of integer used to represent simplices.
Examples
julia> data = [(sin(t), cos(t)) for t in range(0, 2π, length=101)][1:end-1];
julia> ripserer(Rips(data))
2-element Array{PersistenceDiagrams.PersistenceDiagram,1}:
100-element 0-dimensional PersistenceDiagram
1-element 1-dimensional PersistenceDiagram
julia> ripserer(Rips(data, threshold=1.7))[2]
1-element 1-dimensional PersistenceDiagram:
[0.0628, ∞)
julia> using Distances
julia> ripserer(Rips(data, metric=Cityblock()))[2]
1-element 1-dimensional PersistenceDiagram:
[0.0888, 2.0)
Ripserer.SparseRips
— TypeSparseRips{I, T} <: AbstractRipsFiltration{T, Simplex}
This type represents a sparse filtration of Vietoris-Rips complexes. The distance matrix will be converted to a sparse matrix with all values greater than threshold deleted. Off-diagonal zeros in the matrix are treated as missing
. Diagonal items are treated as vertex birth times.
Use this filtration type with low threshold
s.
Constructor
SparseRips{I}(distance_matrix; threshold=nothing)
SparseRips(distance_matrix; threshold=nothing)
:I
sets the integer size used to represent simplices.
Examples
julia> data = [(sin(t), cos(t)) for t in range(0, 2π, length=101)][1:end-1];
julia> ripserer(SparseRips(data))
2-element Array{PersistenceDiagrams.PersistenceDiagram,1}:
100-element 0-dimensional PersistenceDiagram
1-element 1-dimensional PersistenceDiagram
julia> ripserer(SparseRips(data, threshold=1.7))[2]
1-element 1-dimensional PersistenceDiagram:
[0.0628, ∞)
julia> using Distances
julia> ripserer(SparseRips(data, metric=Cityblock()))[2]
1-element 1-dimensional PersistenceDiagram:
[0.0888, 2.0)
Ripserer.Cubical
— TypeCubical{T, K} <: AbstractFiltration{CartesianIndex{K}, T}
Cubical
is used to compute sublevel persistent homology on N
-dimensional images, which are of type AbstractArray{T, N}
.
This type uses the CubeMap structure to find birth times of cubes (see reference).
Constructor
Cubical(image::AbstractArray{T, N}, threshold=maximum(image))
Reference
Wagner, H., Chen, C., & Vuçini, E. (2012). Efficient computation of persistent homology for cubical data. In Topological methods in data analysis and visualization II (pp. 91-106). Springer, Berlin, Heidelberg.
Example
julia> image = [1 0 0; 0 2 0; 0 0 0];
julia> ripserer(Cubical(image))[1]
1-element 0-dimensional PersistenceDiagram:
[0.0, ∞)
julia> ripserer(Cubical(image))[2]
1-element 1-dimensional PersistenceDiagram:
[1.0, 2.0)
Ripserer.Custom
— TypeCustom{I, T} <: AbstractCustomFiltration{I, T}
Build a custom filtration by specifying simplices and their birth times.
The list of simplices is corrected to form a valid filtration; birth times are corrected so a simplex is never born before its faces and missing simplices are added.
See the examples below for construction. Note how the unlisted 0-simplices were added with birth times equal to the lowest between their cofaces. The order in which simplices are given does not matter.
To create your own types of custom filtrations, subtype AbstractCustomFiltration
.
Examples
julia> flt = Custom([(1,) => 0, (4,) => 0, (1, 2) => 1, (1, 3) => 2, (1, 4) => 3, (2, 3) => 4, (2, 4) => 5, (3, 4) => 6, (1, 2, 3) => 7, (1, 2, 4) => 8, (1, 3, 4) => 9]; threshold=8)
Custom{Int64, Int64}(nv=4)
julia> flt[0] # Can be indexed with dimension to list simplices
4-element Array{Simplex{0,Int64,Int64},1}:
+Simplex{0}([4], 0)
+Simplex{0}([2], 1)
+Simplex{0}([3], 2)
+Simplex{0}([1], 0)
julia> ripserer(flt)[1]
2-element 0-dimensional PersistenceDiagram:
[0.0, 3.0)
[0.0, ∞)
julia> ripserer(flt)[2]
3-element 1-dimensional PersistenceDiagram:
[4.0, 7.0)
[5.0, 8.0)
[6.0, ∞)
Ripserer.Alpha
— TypeAlpha{I, P<:SVector} <: AbstractFiltration{I, Float64}
Alpha
filtrations are filtrations of the Delaunay complex.
They have much fewer simplices than Rips
, so they are efficient even with large datasets, as long as their dimensionality is low. What "low" means depends on the data, but this is definitely a good choice for 3D or lower. For high dimensional data, filtration construction may take a long time.
Unlike most implementations, this one uses circumdiameters instead of circumradii. This makes the scale of the results comparable to Rips
. If you need radius based values, divide your data or the resulting interval endpoints by 2.
This filtration uses MiniQhull.jl. Please see the installation instructions if constructions cause errors. MiniQhull currently has problems running on Windows. See this issue for more info.
Constructors
Alpha(points; threshold, progress)
:points
should be a vector ofTuple
s,SVector
s or similar.Alpha{I}(args...)
:I
sets the size of integer used to represent simplices. Try usingI=Int128
if construction complains about overflow.
Reference
Edelsbrunner, H. (1993, July). The union of balls and its dual shape. In Proceedings of the ninth annual symposium on Computational geometry (pp. 218-231).
Example
julia> data = [(sin(t), cos(t), (t - π)^2) for t in range(0, 2π, length=101)[1:end-1]];
julia> alpha = Alpha(data)
Alpha{Int64, Float64}(nv=100)
julia> rips = Rips(data)
Rips{Int64, Float64}(nv=100)
julia> length(Ripserer.edges(alpha))
197
julia> length(Ripserer.edges(rips))
3613
julia> sort(ripserer(alpha)[2], by=persistence)[end]
[0.375, 2.01) with:
birth_simplex: 2-element Ripserer.Simplex{1,Float64,Int64}
death_simplex: 3-element Ripserer.Simplex{2,Float64,Int64}
julia> sort(ripserer(rips)[2], by=persistence)[end]
[0.375, 2.01) with:
birth_simplex: 2-element Ripserer.Simplex{1,Float64,Int64}
death_simplex: 3-element Ripserer.Simplex{2,Float64,Int64}
Simplices
Ripserer.Simplex
— TypeSimplex{D, T, I<:Integer} <: AbstractSimplex{D, T, I}
The vanilla simplex type represented by dimension D
, an index of type I
, and a birth time of type T
.
Constructors
Simplex{D[, T, I]}(index, birth)
Simplex{D}(vertices, birth)
: vertices must be sorted descending. This constructor mainly exists for debugging purposes. Usingsimplex
is usually the better option.
Examples
julia> Simplex{2}(2, 1)
2-dimensional Simplex(index=2, birth=1):
+[4, 2, 1]
julia> Simplex{10}(Int128(-10), 1.0)
10-dimensional Simplex(index=10, birth=1.0):
-Int128[12, 11, 10, 9, 8, 7, 6, 5, 4, 2, 1]
julia> Simplex{2}((5, 2, 1), 1)
2-dimensional Simplex(index=5, birth=1):
+[5, 2, 1]
Ripserer.Cube
— TypeCube{D, T, K} <: AbstractSimplex{D, T, CartesianIndex{K}}
A Cube
is similar to a Simplex
, but it has 2^D
vertices instead of D+1
. The vertices are encoded as the position in the CubeMap (see reference in Cubical
). A Cube
's vertices are of type CartesianIndex{K}
.
Example
julia> Cube{1}(CartesianIndex(1, 2), 1.0)
1-dimensional Cube(index=CartesianIndex(1, 2), birth=1.0):
+CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(1, 2)]
LightGraphs.vertices
— Methodvertices(simplex::AbstractSimplex{dim, T, I})
Get the vertices of simplex
. Returns SVector{length(simplex), I}
. When index(simplex)
is an interger, a default implementation is provided.
Example
julia> vertices(Simplex{2}((3, 2, 1), 3.2))
3-element StaticArrays.SArray{Tuple{3},Int64,1,3} with indices SOneTo(3):
3
2
1
PersistenceDiagrams.birth
— Methodbirth(simplex::AbstractSimplex)
Get the birth time of simplex
, i.e. the time it first appears in the filtration.
Example
julia> birth(Simplex{2}((3, 2, 1), 3.2))
3.2
PersistenceDiagrams.dim
— Methoddim(::AbstractSimplex)
dim(::Type{<:AbstractSimplex})
Get the dimension of a simplex i.e. the value of D
. Can also be called on the type.
Examples
julia> dim(Simplex{2}((3, 2, 1), 3.2))
2
julia> dim(Cube{3, Int, 4})
3
Fields
Ripserer.Mod
— TypeMod{M} <: Integer
Mod{M}
is the default field used by Ripserer. It is a representation of a finite field $\mathbb{Z}_M$, integers modulo small, prime M
. Supports field arithmetic and can be converted to integer with Int
.
Its values are not comparable on purpose.
Example
julia> Mod{3}(5)
2 mod 3
julia> Mod{3}(5) + 1
0 mod 3
Persistence Diagrams
See also: PersistenceDiagrams.jl API. For convenience, Ripserer reexports the following:
PersistenceDiagrams.birth
— Methodbirth(interval)
Get the birth time of interval
.
PersistenceDiagrams.death
— Methoddeath(interval)
Get the death time of interval
.
PersistenceDiagrams.persistence
— Methodpersistence(interval)
Get the persistence of interval
, which is equal to death - birth
.
PersistenceDiagrams.representative
— Methodrepresentative(interval::PersistenceInterval)
Get the representative (co)cycle attached to interval
, if it has one.
PersistenceDiagrams.birth_simplex
— Methodbirth_simplex(interval::PersistenceInterval)
Get the critical birth simplex of interval
, if it has one.
PersistenceDiagrams.death_simplex
— Methoddeath_simplex(interval::PersistenceInterval)
Get the critical death simplex of interval
, if it has one.
Note: an infinite interval's death simplex is nothing
.
PersistenceDiagrams.barcode
— Functionbarcode(diagram)
Plot the barcode plot of persistence diagram or multiple diagrams diagrams. The infinity
keyword argument determines where the infinity line is placed. If unset, the function tries to use threshold(diagram)
or guess a good position to place the line at.