I've been trying to see how to add the feature of keeping track which component merged with whom. I have some preliminary (messy code) that does this. I guess this would only work for dim=0 homology since only there these merges make sense.
function zeroth_intervals_with_merges(filtration, cutoff::T = T(0); verbose=true) where T <: AbstractFloat
F = Mod
reps = false
V = simplex_type(filtration, 0)
CE = chain_element_type(V, F)
dset = DisjointSetsWithBirth(vertices(filtration), births(filtration))
intervals = PersistenceInterval[]
to_skip = simplex_type(filtration, 1)[]
to_reduce = simplex_type(filtration, 1)[]
simplices = sort!(edges(filtration))
merged_vertices = Dict()
persistence_merged_vertices = Dict()
if verbose
progbar = Progress(
length(simplices) + nv(filtration); desc="Computing 0d intervals... "
)
end
for edge in simplices
u, v = vertices(edge)
i = find_root!(dset, u)
j = find_root!(dset, v)
if i ≠ j
# According to the elder rule, the vertex with the higher birth will die first.
last_vertex = birth(dset, i) > birth(dset, j) ? i : j
int = interval(dset, filtration, last_vertex, edge, cutoff, reps)
btime_last, bvertex_last = birth(dset, last_vertex)
if !isnothing(int)
push!(intervals, int)
if last_vertex == i
btime_first, bvertex_first = birth(dset, j)
else
btime_first, bvertex_first = birth(dset, i)
end
merged_vertices[simplex(filtration, Val(0), (bvertex_last,))] = simplex(filtration, Val(0), (bvertex_first,))
persistence_merged_vertices[simplex(filtration, Val(0), (bvertex_last,))] = persistence(int)
end
union!(dset, i, j)
push!(to_skip, edge)
else
push!(to_reduce, edge)
end
verbose && next!(progbar; showvalues=((:n_intervals, length(intervals)),))
end
for v in vertices(filtration)
if find_root!(dset, v) == v && !isnothing(simplex(filtration, Val(0), (v,)))
int = interval(dset, filtration, v, nothing, cutoff, reps)
push!(intervals, int)
end
verbose && next!(progbar; showvalues=((:n_intervals, length(intervals)),))
end
reverse!(to_reduce)
thresh = T(threshold(filtration))
diagram = PersistenceDiagram(
sort!(intervals; by=persistence);
threshold=thresh,
dim=0,
field=F,
filtration=filtration,
)
return merged_vertices, Ripserer.postprocess_diagram(filtration, diagram), persistence_merged_vertices
end
I can also share the code to construct and plot the corresponding merge tree if you think it's worthwhile or necessary
Hi Matija,
I've been trying to see how to add the feature of keeping track which component merged with whom. I have some preliminary (messy code) that does this. I guess this would only work for dim=0 homology since only there these merges make sense.
1.) Do you perhaps have any suggestion on how/what to improve on this?
2.) Would it be worth to add support in Ripserer for this, as well as constructing/plotting the corresponding merge tree?
I haven't found anything that supports this out there so perhaps could be useful
The code below is a simple modification of the
zeroth_intervalsfunctionI can also share the code to construct and plot the corresponding merge tree if you think it's worthwhile or necessary