Mapping the library: class- and type-diagrams

Support for different coefficients

We handle coefficient types by requiring a Fractional instance to be defined, which produces all the expected arithmetic operations on coefficients. Fractional[Double] already exists in Scala, and we also implement in the same way as is main-stream in the persistent homology library ecosystem finite field arithmetic with lookup tables for inverses.

classDiagram
    class FiniteField {
        val p: Int
        type Fp
        given val FpIsFractional: Fractional[Fp]
        extension Fp.norm() Fp
        extension Fp.toInt() Int
        extension Fp.toString() String
        extension Fp.toUInt() UInt
    }
    namespace Scala {
        class Double {
        }

        class `DoubleIsFractional:Fractional[Double]` {
        }
    }
    FiniteField -- Fractional

    class `Chain[CellT: Cell, CoefficientT: Fractional]` {
        ...
    }

    Double -- Fractional

    Fractional *-- `Chain[CellT: Cell, CoefficientT: Fractional]`
    `Cell[CellT]` *-- `Chain[CellT: Cell, CoefficientT: Fractional]`
    `Cell[CellT]` --> `Simplex[VertexT]`
    class `Cell[CellT]` {
<<interface Typeclass>>
boundary() Chain[CellT, CoefficientT]
}
class `Simplex[VertexT]` {
<<extends SortedSet, Cell>>
size : Int
iterator : Iterator[VertexT]
boundary() Chain[AbstractSimplex[VertexT],CoefficientT]
}

How do we describe a Simplicial Complex?

classDiagram
    `Cell[CellT]` --> `Simplex[VertexT]`
    class `Cell[CellT]` {
<<interface>>
boundary() Chain[CellT, CoefficientT]
}
class `Simplex[VertexT]` {
<<extends SortedSet, Cell>>
size : Int
iterator : Iterator[VertexT]
boundary() Chain[AbstractSimplex[VertexT],CoefficientT]
}
class `SimplexContext[VertexT]` {
<<interface Context>>
type Simplex = AbstractSimplex[VertexT]
given Ordering[Simplex]
s(vs*: Simplex) Simplex
}
class `IterableOnce[T]` {
iterator : Iterator[T]
knownSize : Int
}
class `SimplexFiltration[VertexT,FiltrationT]` {
filtrationValue(simplex: AbstractSimplex[VertexT]) FiltrationT
}
class `SimplexStream[VertexT,FiltrationT]` {
<<extends Filtration[VertexT,FiltrationT], IterableOnce[AbstractSimplex[VertexT]]>>
}
`IterableOnce[T]` --> `SimplexStream[VertexT,FiltrationT]` : inherits
`SimplexFiltration[VertexT,FiltrationT]` --> `SimplexStream[VertexT,FiltrationT]` : inherits
`Simplex[VertexT]` "*" o-- "1" `SimplexStream[VertexT,FiltrationT]` : contains

class `ExplicitStream[VertexT,FiltrationT]` {
filtrationValues : Map[AbstractSimplex[VertexT],FiltrationT]
simplices: Seq[AbstractSimplex[VertexT]]
}
class `VietorisRips[VertexT]` {
metricSpace: FiniteMetricSpace[VertexT]
maxDimension: Int
maxFiltrationValue: Double
cliqueFinder: CliqueFinder[VertexT]
}
`SimplexStream[VertexT,FiltrationT]` --> `ExplicitStream[VertexT,FiltrationT]`: inherits
`SimplexStream[VertexT,FiltrationT]` --> `VietorisRips[VertexT]`: inherits FiltrationT=Double
`VietorisRips[VertexT]` -- `CliqueFinder[VertexT]` : uses
class `CliqueFinder[VertexT]` {
<<interface>>
apply(metricSpace, maxFiltrationValue, maxDimension) Seq[AbstractSimplex[VertexT]]
    }
`CliqueFinder[VertexT]` --> BronKerbosch : implements
`CliqueFinder[VertexT]` --> ZomorodianIncremental : implements
`CliqueFinder[VertexT]` --> SymmetricZomorodianIncremental : implements

Revision 2024-09-18

classDiagram
    namespace Barcode_scala {
        class BarcodeEndpoint
        class PositiveInfinity
        class NegativeInfinity
        class OpenEndpoint
        class ClosedEndpoint
        class PersistenceBar {
            dim : int
            lower : BarcodeEndpoint
            upper : BarcodeEndpoint
            annotation : Option[AnnotationT]
            toString()
        }
        class BarcodeContext {
            FiltrationT bc FiltrationT : PersistenceBar
            FiltrationT clcl FiltrationT : PersistenceBar
            FiltrationT clop FiltrationT : PersistenceBar
            FiltrationT opcl FiltrationT : PersistenceBar
            FiltrationT opop FiltrationT : PersistenceBar
            clinf FiltrationT : PersistenceBar
            opinf FiltrationT : PersistenceBar
            infcl FiltrationT : PersistenceBar
            infop FiltrationT : PersistenceBar
        }
        class Barcode {
            isMap(List~PersistenceBar~, List~PersistenceBar~, RealMatrix) bool
            imageMatrix(List~PersistenceBar~, List~PersistenceBar~, RealMatrix) RealMatrix
            image(List~PersistenceBar~, List~PersistenceBar~, RealMatrix) List~PersistenceBar~
            kernel(List~PersistenceBar~, List~PersistenceBar~, RealMatrix) List~PersistenceBar~
            cokernelMatrix(List~PersistenceBar~, List~PersistenceBar~, RealMatrix) RealMatrix
            cokernel(List~PersistenceBar~, List~PersistenceBar~, RealMatrix) List~PersistenceBar~
            reduceMatrix(RealMatrix) RealMatrix
        }
    }
    BarcodeEndpoint --|> PositiveInfinity
    BarcodeEndpoint --|> NegativeInfinity
    BarcodeEndpoint --|> OpenEndpoint
    BarcodeEndpoint --|> ClosedEndpoint
classDiagram
    namespace Chain_scala {
        class HasBoundary {
            type Self : Ordering
            extension Self.boundary[CoefficientT : Fractional] : Chain[Self, CoefficientT]
        }
        class HasDimension {
            type Self
            extension Self.dim : Int
        }
        class Cell
        class OrderedCell
        class given_Ordering~OrderedCell~
        class OrderedBasis {
            type Self
            extension Self.leadingTerm: Tuple[Option[CellT], CoefficientT]
            extension Self.leadingCoefficient : CoefficientT
            extension Self.leadingCell : Option[CellT]
        }
        class Chain~CellT, CoefficientT~ {
            private entries : mutable.PriorityQueue[Tuple[CellT, CoefficientT]]
            collapseHead()
            collapseAll()
            isZero() bool
            items : Seq[Tuple[CellT, CoefficientT]]
            chainBoundary() Chain~CellT, CoefficientT~ 
        }
        class object_Chain {
            apply(cs : vararg Tuple[CellT, CoefficientT]) Chain~CellT, CoefficientT~
            apply(c : CellT) Chain~CellT, CoefficientT~
            from(cs : Seq[Tuple[CellT, CoefficientT]]) Chain~CellT, CoefficientT~ 
        }
        class given_Chain_is_OrderedBasis
        class ChainOps~CellT, CoefficientT~
    }
    HasBoundary --|> Cell
    HasDimension --|> Cell
    Cell --|> OrderedCell
    RingModule --|> ChainOps

classDiagram
    namespace Cube_scala {
        class ElementaryInterval {
            n : int
        }
        class DegenerateInterval
        class FullInterval
        class given_Ordering_ElementaryInterval
        class given_ElementaryInterval_is_OrderedCell
        class ElementaryCube {
            intervals : List[ElementaryInterval]
        }
    }
    ElementaryInterval --|> DegenerateInterval
    ElementaryInterval --|> FullInterval
classDiagram
    namespace FiniteField_scala {
        class FiniteField {
            p : int
            type Fp
            given Fp_is_Fractional
        }
    }
classDiagram
    namespace FiniteMetricSpace_scala {
        class FiniteMetricSpace {
            distance(vertex, vertex) Double
            size : int
            elements : Iterable[VertexT]
            contains(vertex) bool
            minimumEnclosingRadius : lazy Double
        }
        class MaximumDistanceFiltrationValue
        class ExplicitMetricSpace
        class EuclideanMetricSpace
    }
    FiniteMetricSpace --|> ExplicitMetricSpace
    FiniteMetricSpace --|> EuclideanMetricSpace
classDiagram
    namespace Homology_scala {
        class HomologyState {
            cycles : mutable.Map[CellT, Chain[CellT, CoefficientT]]
            cyclesBornBy : mutable.Map[CellT, CellT]
            boundaries : mutable.Map[CellT, Chain[CellT, CoefficientT]]
            boundariesBornBy : mutable.Map[CellT, CellT]
            coboundaries : mutable.Map[CellT, Chain[CellT, CoefficientT]]
            stream : CellStream[CellT, FiltrationT]
            current : FiltrationT
            barcode : mutable.ArrayDeque[Tuple[Int, FiltrationT, FiltrationT, Chain[CellT, CoefficientT]]
            diagramAt(f : FiltrationT) List[Tuple[Int,FiltrationT,FiltrationT]]
            barcodeAt(f : FiltrationT) List[PersistenceBar]
            advanceOne()
            advanceTo(f: FiltrationT)
            advanceAll()
        }
    }
classDiagram
    namespace RingModule_scala {
        class RingModule {
            zero : T
            isZero(t : T) bool
            plus(s : T, t: T) T
            minus(s : T, t: T) T
            negate(t: T) T
            scale(r : R, t : T) T
            extension T.+
            extension T.-
            extension T.unary_-
            extension infix T.mul
            extension R.⊠
            extension infix R.scale
        }
    }
classDiagram
    namespace Simplex_scala {
        class Simplex {
            vertices : SortedSet[VertexT]
            union(other : Simplex) Simplex
        }
        class given_Ordering_Simplex
        class given_Simplex_is_OrderedCell
        class object_Simplex {
            apply(vertices : vararg VertexT) Simplex
            from(vertices : Seq[VertexT]) Simplex
            empty() Simplex
            ∆(vertices : vararg VertexT) Simplex
        }
    }
classDiagram
    namespace SimplexStream_scala {
        class SimplexStream
    }
classDiagram
    namespace SymmetryGroup_scala {
        class SymmetryGroup
    }
classDiagram
    namespace UnionFind_scala {
        class UnionFind
    }
classDiagram
    namespace VietorisRips_scala {
        class VietorisRips
    }