- 
                Notifications
    
You must be signed in to change notification settings  - Fork 9
 
Open
Description
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_intervals function
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
Metadata
Metadata
Assignees
Labels
No labels