github.com/biogo/store@v0.0.0-20201120204734-aad293a2328f/kdtree/points.go (about)

     1  // Copyright ©2012 The bíogo Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package kdtree
     6  
     7  import (
     8  	"math"
     9  )
    10  
    11  var (
    12  	_ Interface  = Points{}
    13  	_ Comparable = Point{}
    14  )
    15  
    16  // Randoms is the maximum number of random values to sample for calculation of median of
    17  // random elements.
    18  var Randoms = 100
    19  
    20  // A Point represents a point in a k-d space that satisfies the Comparable interface.
    21  type Point []float64
    22  
    23  func (p Point) Compare(c Comparable, d Dim) float64 { q := c.(Point); return p[d] - q[d] }
    24  func (p Point) Dims() int                           { return len(p) }
    25  func (p Point) Distance(c Comparable) float64 {
    26  	q := c.(Point)
    27  	var sum float64
    28  	for dim, c := range p {
    29  		d := c - q[dim]
    30  		sum += d * d
    31  	}
    32  	return sum
    33  }
    34  func (p Point) Extend(b *Bounding) *Bounding {
    35  	if b == nil {
    36  		b = &Bounding{append(Point(nil), p...), append(Point(nil), p...)}
    37  	}
    38  	min := b[0].(Point)
    39  	max := b[1].(Point)
    40  	for d, v := range p {
    41  		min[d] = math.Min(min[d], v)
    42  		max[d] = math.Max(max[d], v)
    43  	}
    44  	*b = Bounding{min, max}
    45  	return b
    46  }
    47  
    48  // A Points is a collection of point values that satisfies the Interface.
    49  type Points []Point
    50  
    51  func (p Points) Bounds() *Bounding {
    52  	if p.Len() == 0 {
    53  		return nil
    54  	}
    55  	min := append(Point(nil), p[0]...)
    56  	max := append(Point(nil), p[0]...)
    57  	for _, e := range p[1:] {
    58  		for d, v := range e {
    59  			min[d] = math.Min(min[d], v)
    60  			max[d] = math.Max(max[d], v)
    61  		}
    62  	}
    63  	return &Bounding{min, max}
    64  }
    65  func (p Points) Index(i int) Comparable         { return p[i] }
    66  func (p Points) Len() int                       { return len(p) }
    67  func (p Points) Pivot(d Dim) int                { return Plane{Points: p, Dim: d}.Pivot() }
    68  func (p Points) Slice(start, end int) Interface { return p[start:end] }
    69  
    70  // A Plane is a wrapping type that allows a Points type be pivoted on a dimension.
    71  type Plane struct {
    72  	Dim
    73  	Points
    74  }
    75  
    76  func (p Plane) Less(i, j int) bool              { return p.Points[i][p.Dim] < p.Points[j][p.Dim] }
    77  func (p Plane) Pivot() int                      { return Partition(p, MedianOfRandoms(p, Randoms)) }
    78  func (p Plane) Slice(start, end int) SortSlicer { p.Points = p.Points[start:end]; return p }
    79  func (p Plane) Swap(i, j int) {
    80  	p.Points[i], p.Points[j] = p.Points[j], p.Points[i]
    81  }