// DescribeTree calculates the persistence landscape functions λₖ for the interval // data in the provided interval tree. fn is called for each position t of the span // of the interval data with the values for t and the k λ functions at t. // Explicit zero values for a λₖ(t) are included only at the end points of intervals // in the span. Note that intervals stored in the tree must have unique id values // within the tree. func DescribeTree(it *interval.IntTree, fn func(t int, λₜ []int)) { if it == nil || it.Len() == 0 { return } var ( h endHeap t = it.Root.Range.Start end = it.Root.Range.End last = it.Max().ID() l []int ) it.Do(func(iv interval.IntInterface) (done bool) { if s := iv.Range().Start; s >= t || iv.ID() == last { if iv.ID() == last { heap.Push(&h, iv) s, iv = iv.Range().End, nil } for ; t < s; t++ { for len(h) > 0 && h[0].Range().End <= t { heap.Pop(&h) l = append(l, 0) } for _, iv := range h { r := iv.Range() if r.Start == t { l = append(l, 0) } if v := max(0, min(t-r.Start, r.End-t)); v > 0 { l = append(l, v) } } sort.Ints(l) reverse(l) fn(t, l) l = l[:0] } } if iv != nil { heap.Push(&h, iv) } else { for ; t <= end; t++ { for len(h) > 0 && h[0].Range().End <= t { heap.Pop(&h) l = append(l, 0) } for _, iv := range h { r := iv.Range() if r.Start == t { l = append(l, 0) } if v := max(0, min(t-r.Start, r.End-t)); v > 0 { l = append(l, v) } } sort.Ints(l) reverse(l) fn(t, l) l = l[:0] } } return }) }