mirror of
https://github.com/andreytkachenko/kdtree-rust.git
synced 2024-11-21 17:06:24 +04:00
Reformatted files, changed package name, added description
This commit is contained in:
parent
4ea61ebfbc
commit
9f03f67c1d
13
Cargo.toml
13
Cargo.toml
@ -1,7 +1,8 @@
|
||||
[package]
|
||||
name = "kdtree_rust"
|
||||
name = "fux_kdtree"
|
||||
version = "0.1.0"
|
||||
authors = ["Aleksander Fular <ntszar@gmail.com>"]
|
||||
authors = ["fulara <ntszar@gmail.com>"]
|
||||
description = "K-dimensional tree implemented in Rust for fast NN querying."
|
||||
|
||||
[lib]
|
||||
name = "kdtree"
|
||||
@ -12,9 +13,7 @@ bench = false
|
||||
name = "bench"
|
||||
harness = false
|
||||
|
||||
[dependencies]
|
||||
rand = "*"
|
||||
bencher = "*"
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = "0.3"
|
||||
quickcheck = "0.3"
|
||||
rand = "*"
|
||||
bencher = "*"
|
@ -1,18 +1,18 @@
|
||||
use ::kdtree::*;
|
||||
|
||||
pub struct Bounds {
|
||||
pub bounds: [(f64,f64);3],
|
||||
pub bounds: [(f64, f64); 3],
|
||||
|
||||
widest_dim : usize,
|
||||
midvalue_of_widest_dim : f64,
|
||||
widest_dim: usize,
|
||||
midvalue_of_widest_dim: f64,
|
||||
}
|
||||
|
||||
impl Bounds {
|
||||
pub fn new_from_points<T: KdtreePointTrait>(points: &[T]) -> Bounds {
|
||||
let mut bounds = Bounds {
|
||||
bounds: [(0.,0.),(0.,0.),(0.,0.)],
|
||||
widest_dim : 0,
|
||||
midvalue_of_widest_dim : 0.,
|
||||
bounds: [(0., 0.), (0., 0.), (0., 0.)],
|
||||
widest_dim: 0,
|
||||
midvalue_of_widest_dim: 0.,
|
||||
};
|
||||
|
||||
for i in 0..points[0].dims().len() {
|
||||
@ -64,7 +64,7 @@ impl Bounds {
|
||||
cloned
|
||||
}
|
||||
|
||||
fn calculate_widest_dim(&mut self) {
|
||||
fn calculate_widest_dim(&mut self) {
|
||||
let mut widest_dimension = 0usize;
|
||||
let mut max_found_spread = self.bounds[0].1 - self.bounds[0].0;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
pub fn squared_euclidean(a : &[f64], b: &[f64]) -> f64 {
|
||||
pub fn squared_euclidean(a: &[f64], b: &[f64]) -> f64 {
|
||||
debug_assert!(a.len() == b.len());
|
||||
|
||||
a.iter().zip(b.iter())
|
||||
.map(|(x,y)| (x - y) * (x-y))
|
||||
.map(|(x, y)| (x - y) * (x - y))
|
||||
.sum()
|
||||
}
|
||||
|
||||
@ -10,29 +10,30 @@ pub fn squared_euclidean(a : &[f64], b: &[f64]) -> f64 {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn squared_euclidean_test_1d() {
|
||||
let a = [2.];
|
||||
let b = [4.];
|
||||
let c = [-2.];
|
||||
|
||||
assert_eq!(0., squared_euclidean(&a,&a));
|
||||
assert_eq!(0., squared_euclidean(&a, &a));
|
||||
|
||||
assert_eq!(4., squared_euclidean(&a,&b));
|
||||
assert_eq!(4., squared_euclidean(&a, &b));
|
||||
|
||||
assert_eq!(16., squared_euclidean(&a,&c));
|
||||
assert_eq!(16., squared_euclidean(&a, &c));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn squared_euclidean_test_2d() {
|
||||
let a = [2.,2.];
|
||||
let b = [4.,2.];
|
||||
let c = [4.,4.];
|
||||
let a = [2., 2.];
|
||||
let b = [4., 2.];
|
||||
let c = [4., 4.];
|
||||
|
||||
assert_eq!(0., squared_euclidean(&a,&a));
|
||||
assert_eq!(0., squared_euclidean(&a, &a));
|
||||
|
||||
assert_eq!(4., squared_euclidean(&a,&b));
|
||||
assert_eq!(4., squared_euclidean(&a, &b));
|
||||
|
||||
assert_eq!(8., squared_euclidean(&a,&c));
|
||||
assert_eq!(8., squared_euclidean(&a, &c));
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ mod bounds;
|
||||
use self::bounds::*;
|
||||
use self::distance::*;
|
||||
|
||||
pub trait KdtreePointTrait {
|
||||
pub trait KdtreePointTrait: Copy {
|
||||
fn dims(&self) -> &[f64];
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ pub struct Kdtree<T> {
|
||||
nodes: Vec<KdtreeNode<T>>,
|
||||
}
|
||||
|
||||
impl<T: KdtreePointTrait + Copy> Kdtree<T> {
|
||||
impl<T: KdtreePointTrait> Kdtree<T> {
|
||||
pub fn new(mut points: &mut [T]) -> Kdtree<T> {
|
||||
if points.len() == 0 {
|
||||
panic!("empty vector point not allowed");
|
||||
@ -34,16 +34,16 @@ impl<T: KdtreePointTrait + Copy> Kdtree<T> {
|
||||
tree
|
||||
}
|
||||
|
||||
pub fn nearest_search(&self, node : &T) -> T
|
||||
pub fn nearest_search(&self, node: &T) -> T
|
||||
{
|
||||
let mut nearest_neighbor = 0usize;
|
||||
let mut best_distance = squared_euclidean(node.dims(), &self.nodes[0].point.dims());
|
||||
self.nearest_search_impl(node, 0usize, &mut best_distance , &mut nearest_neighbor);
|
||||
self.nearest_search_impl(node, 0usize, &mut best_distance, &mut nearest_neighbor);
|
||||
|
||||
self.nodes[nearest_neighbor].point
|
||||
}
|
||||
|
||||
fn nearest_search_impl(&self, p : &T, searched_index: usize, best_distance_squared : &mut f64, best_leaf_found : &mut usize) {
|
||||
fn nearest_search_impl(&self, p: &T, searched_index: usize, best_distance_squared: &mut f64, best_leaf_found: &mut usize) {
|
||||
let node = &self.nodes[searched_index];
|
||||
|
||||
let dimension = node.dimension;
|
||||
@ -68,7 +68,7 @@ impl<T: KdtreePointTrait + Copy> Kdtree<T> {
|
||||
}
|
||||
|
||||
if let Some(farther_node) = farther_node {
|
||||
let distance_on_single_dimension = squared_euclidean(&[splitting_value],&[point_splitting_dim_value]);
|
||||
let distance_on_single_dimension = squared_euclidean(&[splitting_value], &[point_splitting_dim_value]);
|
||||
|
||||
if distance_on_single_dimension <= *best_distance_squared {
|
||||
self.nearest_search_impl(p, farther_node, best_distance_squared, best_leaf_found);
|
||||
@ -77,8 +77,8 @@ impl<T: KdtreePointTrait + Copy> Kdtree<T> {
|
||||
}
|
||||
|
||||
|
||||
fn add_node(&mut self, p: T, dimension : usize, split_on : f64) -> usize {
|
||||
let node = KdtreeNode::new(p, dimension, split_on );
|
||||
fn add_node(&mut self, p: T, dimension: usize, split_on: f64) -> usize {
|
||||
let node = KdtreeNode::new(p, dimension, split_on);
|
||||
|
||||
self.nodes.push(node);
|
||||
self.nodes.len() - 1
|
||||
@ -117,14 +117,14 @@ pub struct KdtreeNode<T> {
|
||||
}
|
||||
|
||||
impl<T: KdtreePointTrait> KdtreeNode<T> {
|
||||
fn new(p: T, splitting_dimension: usize, split_on_value : f64) -> KdtreeNode<T> {
|
||||
fn new(p: T, splitting_dimension: usize, split_on_value: f64) -> KdtreeNode<T> {
|
||||
KdtreeNode {
|
||||
left_node: None,
|
||||
right_node: None,
|
||||
|
||||
point: p,
|
||||
dimension : splitting_dimension,
|
||||
split_on : split_on_value
|
||||
dimension: splitting_dimension,
|
||||
split_on: split_on_value
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,11 +194,11 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn qc_value_vec_to_2d_points_vec(xs : &Vec<f64>) -> Vec<Point2WithId> {
|
||||
let mut vec : Vec<Point2WithId> = vec![];
|
||||
for i in 0 .. xs.len() {
|
||||
fn qc_value_vec_to_2d_points_vec(xs: &Vec<f64>) -> Vec<Point2WithId> {
|
||||
let mut vec: Vec<Point2WithId> = vec![];
|
||||
for i in 0..xs.len() {
|
||||
let mut is_duplicated_value = false;
|
||||
for j in 0 .. i {
|
||||
for j in 0..i {
|
||||
if xs[i] == xs[j] {
|
||||
is_duplicated_value = true;
|
||||
break;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#[cfg(test)]
|
||||
pub mod tests_utils {
|
||||
use super::super::*;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub struct Point3WithId {
|
||||
dims: [f64; 3],
|
||||
|
@ -2,6 +2,7 @@
|
||||
#[macro_use]
|
||||
extern crate quickcheck;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate rand;
|
||||
|
||||
pub mod kdtree;
|
Loading…
Reference in New Issue
Block a user