Public API

Ripserer

Ripserer.ripsererFunction
ripserer(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 NTuples or SVectors.

Keyword Arguments

  • dim_max: compute persistent homology up to this dimension. Defaults to 1.
  • modulus: compute persistent homology with coefficients in the prime field of integers mod modulus. Defaults to 2.
  • field_type: use this type of field of coefficients. Defaults to Ripserer.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 using SparseRips.
  • cutoff: only keep intervals with persistence(interval) > cutoff. Defaults to 0.
  • reps: if true, return representative cocycles along with persistence intervals. Defaults to false.
  • progress: If true, show a progress bar. Defaults to false.
  • metric: when calculating persistent homology from points, any metric from Distances.jl can be used. Defaults to Distances.Euclidean().
  • cohomology: if set to false, compute persistent homology instead of cohomology. This is much slower and gives the same result, but may give more informative representatives when reps is enabled. Currently unable to compute infinite intervals in dimensions higher than 0. Defaults to false.
source

Filtrations

Ripserer.RipsType
Rips{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 thresholds, 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)
source
Ripserer.SparseRipsType
SparseRips{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 thresholds.

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)
source
Ripserer.CubicalType
Cubical{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)
source
Ripserer.CustomType
Custom{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, ∞)
source
Ripserer.AlphaType
Alpha{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.

Note

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.

Warning

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 of Tuples, SVectors or similar.
  • Alpha{I}(args...): I sets the size of integer used to represent simplices. Try using I=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}
source

Simplices

Ripserer.SimplexType
Simplex{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. Using simplex 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]
source
Ripserer.CubeType
Cube{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)]
source
LightGraphs.verticesMethod
vertices(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
source
PersistenceDiagrams.birthMethod
birth(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
source
PersistenceDiagrams.dimMethod
dim(::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
source

Fields

Ripserer.ModType
Mod{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
source

Persistence Diagrams

See also: PersistenceDiagrams.jl API. For convenience, Ripserer reexports the following:

PersistenceDiagrams.death_simplexMethod
death_simplex(interval::PersistenceInterval)

Get the critical death simplex of interval, if it has one.

Note: an infinite interval's death simplex is nothing.

PersistenceDiagrams.barcodeFunction
barcode(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.