func assertPileSanity(t *interval.IntTree, im *Feature, pi *Pile) { if im.Start() < pi.Start() || im.End() > pi.End() { panic(fmt.Sprintf("image extends beyond pile: %#v", im)) } if foundPiles := t.Get(&pileInterval{start: im.Start(), end: im.End()}); len(foundPiles) > 1 { var containing int for _, pile := range foundPiles { r := pile.Range() if (r.Start <= im.Start() && r.End > im.End()) || (r.Start < im.Start() && r.End >= im.End()) { containing++ } } if containing > 1 { panic(fmt.Sprintf("found too many piles for %#v", im)) } } }
func (s *S) TestDescribeTree(c *check.C) { for i, t := range testData { var ( it interval.IntTree r []lr ) for id, e := range t.ivs { e.UID = uintptr(id) err := it.Insert(e, false) c.Assert(err, check.Equals, nil) } DescribeTree(&it, func(pos int, l []int) { if len(l) > 0 { r = append(r, lr{pos, append([]int(nil), l...)}) } }) c.Check(r, check.DeepEquals, t.expect, check.Commentf("Test %d: %v", i, t.ivs)) } }
// 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 }) }