Skip to content

Commit

Permalink
Merge branch 'master' into custom-performance
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsch committed Jun 4, 2024
2 parents e95662d + 3f2d63f commit 2401c68
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
julia-version: ['1.6', '1', 'nightly']
julia-version: ['1', '1.6', 'nightly']
name: ${{ matrix.julia-version }}
steps:
- uses: actions/checkout@v2
Expand Down
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Ripserer"
uuid = "aa79e827-bd0b-42a8-9f10-2b302677a641"
authors = ["mtsch <matijacufar@gmail.com>"]
version = "0.16.10"
version = "0.16.13"

[deps]
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
Expand All @@ -22,7 +22,7 @@ TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6"

[compat]
Aqua = "0.8"
Compat = "4"
Compat = "^3.10, 4"
DataStructures = "0.17, 0.18"
Distances = "0.8, 0.9, 0.10"
Documenter = "1"
Expand All @@ -32,7 +32,7 @@ IterTools = "1"
LinearAlgebra = "1"
MLJBase = "1"
MLJModelInterface = "^0.3.5, 0.4, 1"
MiniQhull = "0.2, 0.3"
MiniQhull = "0.2, 0.3, 0.4"
PersistenceDiagrams = "0.9"
ProgressMeter = "1"
Random = "1"
Expand All @@ -43,7 +43,7 @@ StaticArrays = "0.12, 1"
Suppressor = "0.2"
Test = "1"
TupleTools = "1"
julia = "1"
julia = "1.6"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ matrices.

```julia
julia> ripserer(data)
# 2-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
# 2-element Vector{PersistenceDiagrams.PersistenceDiagram}:
# 200-element 0-dimensional PersistenceDiagram
# 84-element 1-dimensional PersistenceDiagram
```
Expand All @@ -56,7 +56,7 @@ tell `ripserer` to use them by passing them as the first argument.

```julia
julia> ripserer(EdgeCollapsedRips, data)
# 2-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
# 2-element Vector{PersistenceDiagrams.PersistenceDiagram}:
# 200-element 0-dimensional PersistenceDiagram
# 84-element 1-dimensional PersistenceDiagram
```
Expand All @@ -69,7 +69,7 @@ julia> rips = EdgeCollapsedRips(data, threshold=1)
```
```julia
julia> ripserer(rips, dim_max=2)
# 3-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
# 3-element Vector{PersistenceDiagrams.PersistenceDiagram}:
# 200-element 0-dimensional PersistenceDiagram
# 84-element 1-dimensional PersistenceDiagram
# 16-element 2-dimensional PersistenceDiagram
Expand Down
2 changes: 1 addition & 1 deletion docs/src/related-work.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ on my (limited) experience with these packages.
* [Ripser.jl](https://github.com/mtsch/Ripser.jl) my deprecated wrapper of the original
C++ program. Very bare-bones and outdated. Runs a bit slower than Ripserer.

* [Sparips.jl](https://github.com/mtsch/Ripser.jl) this is a preprocessor that comes with
* [Sparips.jl](https://github.com/bbrehm/Sparips.jl) this is a preprocessor that comes with
a different wrapper of Ripser. The preprocessor allows you to compute persistent homology
of very large datasets. Integrating it with Ripserer is on my TODO list.

Expand Down
100 changes: 78 additions & 22 deletions src/base/chain.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,95 @@ julia> data = [(rand(), rand(), rand()) for _ in 1:100];
julia> result = ripserer(data; reps=true, modulus=7);
julia> chain = result[end][end].representative
6-element Chain{Mod{7},Simplex{1, Float64, Int64}}:
+Simplex{1}((87, 59), 0.23148225999797645) => 6 mod 7
+Simplex{1}((59, 46), 0.3054281021426286) => 1 mod 7
+Simplex{1}((87, 14), 0.32453294355760326) => 6 mod 7
+Simplex{1}((87, 1), 0.34642558062390577) => 6 mod 7
+Simplex{1}((100, 87), 0.3480194268484163) => 1 mod 7
+Simplex{1}((79, 1), 0.36519064466525686) => 6 mod 7
28-element Chain{Ripserer.Mod{7},Ripserer.Simplex{1, Float64, Int64}}:
+Simplex{1}((68, 54), 0.25178097927369875) => 6 mod 7
+Simplex{1}((54, 46), 0.2575262844682746) => 1 mod 7
+Simplex{1}((88, 56), 0.25936896586973557) => 1 mod 7
+Simplex{1}((79, 22), 0.26690101517910964) => 6 mod 7
+Simplex{1}((53, 13), 0.27161939814693414) => 6 mod 7
+Simplex{1}((24, 13), 0.28686687771884056) => 6 mod 7
+Simplex{1}((56, 54), 0.2869400047523196) => 6 mod 7
+Simplex{1}((50, 42), 0.29274772369750884) => 6 mod 7
+Simplex{1}((93, 50), 0.3022995886824861) => 1 mod 7
+Simplex{1}((73, 54), 0.30771273548368216) => 6 mod 7
+Simplex{1}((70, 34), 0.3412250751087395) => 6 mod 7
+Simplex{1}((49, 42), 0.3414959312908324) => 6 mod 7
+Simplex{1}((49, 7), 0.35568373080560794) => 6 mod 7
+Simplex{1}((88, 46), 0.35629002982624475) => 1 mod 7
+Simplex{1}((95, 88), 0.3566986102316938) => 6 mod 7
+Simplex{1}((95, 54), 0.363029725360828) => 6 mod 7
+Simplex{1}((50, 13), 0.3648936036309352) => 6 mod 7
+Simplex{1}((24, 3), 0.3653704317993549) => 6 mod 7
+Simplex{1}((85, 42), 0.369953146904745) => 6 mod 7
julia> simplex.(chain)
6-element Vector{Simplex{1, Float64, Int64}}:
+Simplex{1}((87, 59), 0.23148225999797645)
+Simplex{1}((59, 46), 0.3054281021426286)
+Simplex{1}((87, 14), 0.32453294355760326)
+Simplex{1}((87, 1), 0.34642558062390577)
+Simplex{1}((100, 87), 0.3480194268484163)
+Simplex{1}((79, 1), 0.36519064466525686)
28-element Vector{Simplex{1, Float64, Int64}}:
+Simplex{1}((68, 54), 0.25178097927369875)
+Simplex{1}((54, 46), 0.2575262844682746)
+Simplex{1}((88, 56), 0.25936896586973557)
+Simplex{1}((79, 22), 0.26690101517910964)
+Simplex{1}((53, 13), 0.27161939814693414)
+Simplex{1}((24, 13), 0.28686687771884056)
+Simplex{1}((56, 54), 0.2869400047523196)
+Simplex{1}((50, 42), 0.29274772369750884)
+Simplex{1}((93, 50), 0.3022995886824861)
+Simplex{1}((73, 54), 0.30771273548368216)
+Simplex{1}((70, 34), 0.3412250751087395)
+Simplex{1}((49, 42), 0.3414959312908324)
+Simplex{1}((49, 7), 0.35568373080560794)
+Simplex{1}((88, 46), 0.35629002982624475)
+Simplex{1}((95, 88), 0.3566986102316938)
+Simplex{1}((95, 54), 0.363029725360828)
+Simplex{1}((50, 13), 0.3648936036309352)
+Simplex{1}((24, 3), 0.3653704317993549)
+Simplex{1}((85, 42), 0.369953146904745)
julia> vertices.(chain)
6-element Vector{Tuple{Int64, Int64}}:
(87, 59)
(59, 46)
(87, 14)
(87, 1)
(100, 87)
(79, 1)
28-element Vector{Tuple{Int64, Int64}}:
(68, 54)
(54, 46)
(88, 56)
(79, 22)
(53, 13)
(24, 13)
(56, 54)
(50, 42)
(93, 50)
(73, 54)
(70, 34)
(49, 42)
(49, 7)
(88, 46)
(95, 88)
(95, 54)
(50, 13)
(24, 3)
(85, 42)
julia> coefficient.(chain)
6-element Vector{Mod{7}}:
28-element Vector{Mod{7}}:
6 mod 7
1 mod 7
1 mod 7
6 mod 7
6 mod 7
6 mod 7
6 mod 7
6 mod 7
1 mod 7
6 mod 7
6 mod 7
6 mod 7
6 mod 7
1 mod 7
6 mod 7
6 mod 7
6 mod 7
6 mod 7
6 mod 7
```
Expand Down
11 changes: 9 additions & 2 deletions src/base/primefield.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Return `true` if `n` is a prime number.
"""
Base.@pure function is_prime(n::Int)
function is_prime(n::Int)
if iseven(n) || n < 2
return n == 2
else
Expand Down Expand Up @@ -81,6 +81,13 @@ Base.zero(::Type{Mod{M}}) where {M} = Mod{M}(0, false)
Base.one(::Type{Mod{M}}) where {M} = Mod{M}(1, false)
Base.sign(i::M) where {M<:Mod} = ifelse(iszero(i), zero(M), one(M))

Base.promote_rule(::Type{Mod{M}}, ::Type{<:Integer}) where {M} = Mod{M}
Base.promote_rule(::Type{Mod{M}}, ::Type{<:Mod}) where {M} = Union{}
function Base.promote_rule(::Type{Mod{M}}, ::Type{I}) where {M,I<:Integer}
if Base.promote_type(I, Int128) === Int128 || Base.promote_type(I, Int128) === UInt128
return Mod{M}
else
return Union{}
end
end

Base.inv(i::Mod{M}) where {M} = Mod{M}(invmod(Int(i), M), false)
6 changes: 3 additions & 3 deletions src/computation/ripserer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,17 @@ julia> ts = range(0, 2π; length=20)[1:(end - 1)];
julia> X = [((2 + cos(θ)) * cos(φ), (2 + cos(θ)) * sin(φ), sin(θ)) for θ in ts for φ in ts];
julia> ripserer(X)
2-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
2-element Vector{PersistenceDiagrams.PersistenceDiagram}:
361-element 0-dimensional PersistenceDiagram
362-element 1-dimensional PersistenceDiagram
julia> ripserer(EdgeCollapsedRips, X; modulus=7, threshold=2)
2-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
2-element Vector{PersistenceDiagrams.PersistenceDiagram}:
361-element 0-dimensional PersistenceDiagram
362-element 1-dimensional PersistenceDiagram
julia> ripserer(Rips(X; threshold=1); alg=:involuted)
2-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
2-element Vector{PersistenceDiagrams.PersistenceDiagram}:
361-element 0-dimensional PersistenceDiagram
362-element 1-dimensional PersistenceDiagram
Expand Down
2 changes: 1 addition & 1 deletion src/computation/zerodimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function interval(dset::DisjointSetsWithBirth, filtration, vertex, edge, cutoff,
rep = (;
representative=sort!([
simplex(filtration, Val(0), (v,)) for v in find_leaves!(dset, vertex)
]),
])
)
else
rep = NamedTuple()
Expand Down
2 changes: 1 addition & 1 deletion src/extra/circularcoordinates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ CircularCoordinates(
radius=(0.9510565162951535,),
n_landmarks=10,
partition=linear,
metric=Euclidean(0.0),
metric=Distances.Euclidean(0.0),
)
julia> summary(cc(data))
Expand Down
8 changes: 4 additions & 4 deletions src/filtrations/alpha.jl
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,13 @@ julia> length(Ripserer.edges(rips))
julia> sort(ripserer(alpha)[2], by=persistence)[end]
[0.375, 2.01) with:
birth_simplex: Simplex{1, Float64, Int64}
death_simplex: Simplex{2, Float64, Int64}
birth_simplex: Ripserer.Simplex{1, Float64, Int64}
death_simplex: Ripserer.Simplex{2, Float64, Int64}
julia> sort(ripserer(rips)[2], by=persistence)[end]
[0.375, 2.01) with:
birth_simplex: Simplex{1, Float64, Int64}
death_simplex: Simplex{2, Float64, Int64}
birth_simplex: Ripserer.Simplex{1, Float64, Int64}
death_simplex: Ripserer.Simplex{2, Float64, Int64}
```
"""
struct Alpha{I,P<:SVector} <: AbstractCustomFiltration{I,Float64}
Expand Down
14 changes: 7 additions & 7 deletions src/filtrations/edgecollapse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -164,24 +164,24 @@ julia> rips = Rips(data)
Rips{Int64, Float64}(nv=100, sparse=false)
julia> length(Ripserer.edges(rips))
3906
3934
julia> collapsed = EdgeCollapsedRips(data) # or EdgeCollapsedRips(rips)
EdgeCollapsedRips{Int64, Float64}(nv=100)
julia> length(Ripserer.edges(collapsed))
1419
1324
julia> ripserer(rips) == ripserer(collapsed)
true
julia> ripserer(collapsed; dim_max=4)
5-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
5-element Vector{PersistenceDiagrams.PersistenceDiagram}:
100-element 0-dimensional PersistenceDiagram
75-element 1-dimensional PersistenceDiagram
37-element 2-dimensional PersistenceDiagram
14-element 3-dimensional PersistenceDiagram
1-element 4-dimensional PersistenceDiagram
58-element 1-dimensional PersistenceDiagram
35-element 2-dimensional PersistenceDiagram
10-element 3-dimensional PersistenceDiagram
4-element 4-dimensional PersistenceDiagram
```
Expand Down
4 changes: 2 additions & 2 deletions src/filtrations/rips.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ julia> struct MyRips <: Ripserer.AbstractRipsFiltration{Int, Float16} end
julia> Ripserer.adjacency_matrix(::MyRips) = [0 1 1; 1 0 1; 1 1 0]
julia> ripserer(MyRips())
2-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
2-element Vector{PersistenceDiagrams.PersistenceDiagram}:
3-element 0-dimensional PersistenceDiagram
0-element 1-dimensional PersistenceDiagram
Expand Down Expand Up @@ -185,7 +185,7 @@ faster.
julia> data = [(sin(t), cos(t)) for t in range(0, 2π, length=101)][1:end-1];
julia> ripserer(Rips(data))
2-element Vector{PersistenceDiagramsBase.PersistenceDiagram}:
2-element Vector{PersistenceDiagrams.PersistenceDiagram}:
100-element 0-dimensional PersistenceDiagram
1-element 1-dimensional PersistenceDiagram
Expand Down
2 changes: 1 addition & 1 deletion test/base/primefield.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ end
@test_throws ErrorException Mod{3}(1) < Mod{3}(2)
@test_throws ErrorException Mod{3}(1) Mod{3}(2)

@test_throws StackOverflowError Mod{3}(1) + Mod{2}(1)
@test_throws ErrorException Mod{3}(1) + Mod{2}(1)
end

@testset "Printing" begin
Expand Down
6 changes: 3 additions & 3 deletions test/doctests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ using Documenter
using Distances
using Ripserer

if VERSION v"1.7-DEV" || VERSION < v"1.6-DEV" || !Sys.islinux()
@warn "Doctests only run on Linux and Julia 1.6"
if VERSION v"1.8-DEV" || VERSION < v"1.7-DEV" || !Sys.islinux()
@warn "Doctests only run on Linux and Julia 1.7"
else
DocMeta.setdocmeta!(
Ripserer, :DocTestSetup, :(using Ripserer; using Distances); recursive=true
)
doctest(Ripserer; fix=true)
doctest(Ripserer)
end
Loading

0 comments on commit 2401c68

Please sign in to comment.