Git Product home page Git Product logo

go-kdtree's Introduction

KDTree

Maintainability Test Coverage

Golang implementation of KD tree (https://en.wikipedia.org/wiki/K-d_tree) data structure

Getting started

Use go tool to install the package in your packages tree:

go get github.com/hongshibao/go-kdtree

Then you can use it in import section of your Go programs:

import "github.com/hongshibao/go-kdtree"

The package name is kdtree.

Basic example

First you need to implement the Point interface:

type Point interface {
	// Return the total number of dimensions
	Dim() int
	// Return the value X_{dim}, dim is started from 0
	GetValue(dim int) float64
	// Return the distance between two points
	Distance(p Point) float64
	// Return the distance between the point and the plane X_{dim}=val
	PlaneDistance(val float64, dim int) float64
}

Here is an example of implementing Point interface with square of Euclidean distance as the Distance definition:

type EuclideanPoint struct {
	Point
	Vec []float64
}

func (p *EuclideanPoint) Dim() int {
	return len(p.Vec)
}

func (p *EuclideanPoint) GetValue(dim int) float64 {
	return p.Vec[dim]
}

func (p *EuclideanPoint) Distance(other Point) float64 {
	var ret float64
	for i := 0; i < p.Dim(); i++ {
		tmp := p.GetValue(i) - other.GetValue(i)
		ret += tmp * tmp
	}
	return ret
}

func (p *EuclideanPoint) PlaneDistance(val float64, dim int) float64 {
	tmp := p.GetValue(dim) - val
	return tmp * tmp
}

Now you can create KD-tree from a list of points and get a list of k nearest neighbours for a target point:

func NewEuclideanPoint(vals ...float64) *EuclideanPoint {
	ret := &EuclideanPoint{}
	for _, val := range vals {
		ret.Vec = append(ret.Vec, val)
	}
	return ret
}

func main() {
	p1 := NewEuclideanPoint(0.0, 0.0, 0.0)
	p2 := NewEuclideanPoint(0.0, 0.0, 1.0)
	p3 := NewEuclideanPoint(0.0, 1.0, 0.0)
	p4 := NewEuclideanPoint(1.0, 0.0, 0.0)
	points := make([]Point, 0)
	points = append(points, p1)
	points = append(points, p2)
	points = append(points, p3)
	points = append(points, p4)
	tree := NewKDTree(points)
	targetPoint := NewEuclideanPoint(0.0, 0.0, 0.1)
	neighbours := tree.KNN(targetPoint, 2)
	for idx, p := range neighbours {
		fmt.Printf("Point %d: (%f", idx, p.GetValue(0))
		for i := 1; i < p.Dim(); i++ {
			fmt.Printf(", %f", p.GetValue(i))
		}
		fmt.Println(")")
	}
}

The returned k nearest neighbours are sorted by their distance with the target point.

go-kdtree's People

Contributors

8gian avatar hongshibao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

go-kdtree's Issues

KNN returns points number less than specified

Hi, we've tried to use your library but faced the problem.

I've added one more point to your test case and it returns the wrong response:

func TestKNN(t *testing.T) {
	points := []Point{
		NewEuclideanPoint(0.0, 0.0, 0.0),
		NewEuclideanPoint(0.0, 0.0, 1.0),
		NewEuclideanPoint(0.0, 1.0, 0.0),
		NewEuclideanPoint(1.0, 0.0, 0.0),
		NewEuclideanPoint(0.0, 0.0, 0.0),
		NewEuclideanPoint(0.0, 0.0, 0.1),
		NewEuclideanPoint(1.0, 1.0, 1.0),
		NewEuclideanPoint(0.1, 0.1, 0.1), // aditional point
	}

	tree := NewKDTree(points)

	ans := tree.KNN(NewEuclideanPoint(0.0, 0.0, 0.0), 7)
	if len(ans) != 7 {
		t.Errorf("expected 7 points, actual: %v", len(ans))
	}
}

This test returns
github.com/hongshibao/go-kdtree/kdtree_test.go:116: expected 7 points, actual: 5

If I add one more point a get error:
github.com/hongshibao/go-kdtree/kdtree_test.go:117: expected 7 points, actual: 6

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.