-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5c18577
commit c33155b
Showing
4 changed files
with
123 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,38 @@ | ||
# rindex | ||
Rindex: reverse nearest neighbor search index for high-dimensional clustered datasets. | ||
Rindex: fully dynamic nearest neighbor search index for high-dimensional clustered datasets. | ||
|
||
## Usage | ||
|
||
The following example shows how to update and query Rindex: | ||
``` | ||
let mut rindex = Rindex::default(); | ||
// Insert some points | ||
let a = rindex.insert([1.0, 1.0]); | ||
let b = rindex.insert([2.0, 2.0]); | ||
let c = rindex.insert([3.0, 3.0]); | ||
let d = rindex.insert([20.0, 20.0]); | ||
// Query the tree for 3 nearest neighbors of the query point | ||
let query_point = [0.0, 0.0]; | ||
let result = rindex.query_neighbors(query_point, 3); | ||
// The result should contain the points a, b, and c | ||
assert_eq!(result.len(), 3); | ||
assert!(result.contains(&a)); | ||
assert!(result.contains(&b)); | ||
assert!(result.contains(&c)); | ||
// Delete the point c | ||
rindex.delete(c); | ||
// Query the tree again (c should not be in the result) | ||
let result = rindex.query_neighbors(query_point, 3); | ||
assert_eq!(result.len(), 3); | ||
assert!(result.contains(&a)); | ||
assert!(result.contains(&b)); | ||
assert!(result.contains(&d)); | ||
``` | ||
|
||
## License | ||
This project is licensed under the [Apache License, Version 2.0](LICENSE.md) - See the [LICENSE.md](https://github.com/azizkayumov/rindex/blob/main/LICENSE) file for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use rand::{rngs::StdRng, Rng, SeedableRng}; | ||
use rindex::Rindex; | ||
|
||
#[test] | ||
fn test_random() { | ||
let mut rindex = Rindex::default(); | ||
|
||
let mut rng = StdRng::seed_from_u64(0); | ||
let deletion_probability = 0.2; | ||
|
||
let num_ops = 1000; | ||
let mut points = Vec::new(); | ||
|
||
for _ in 0..num_ops { | ||
// Randomly insert or delete a point | ||
let should_delete = rng.gen_bool(deletion_probability); | ||
if should_delete && !points.is_empty() { | ||
let idx = rng.gen_range(0..points.len()); | ||
let (point_id, _) = points.swap_remove(idx); | ||
rindex.delete(point_id); | ||
} else { | ||
let x = rng.gen_range(-100.0..100.0); | ||
let y = rng.gen_range(-100.0..100.0); | ||
let point_id = rindex.insert([x, y]); | ||
points.push((point_id, [x, y])); | ||
} | ||
|
||
// Creata a random query point and radius | ||
let x = rng.gen_range(-100.0..100.0); | ||
let y = rng.gen_range(-100.0..100.0); | ||
let query_point = [x, y]; | ||
let query_radius = rng.gen_range(5.0..10.0); | ||
|
||
// Compute the expected results | ||
let mut expected = Vec::new(); | ||
for (id, point) in &points { | ||
let dx = point[0] - query_point[0]; | ||
let dy = point[1] - query_point[1]; | ||
let distance = (dx * dx + dy * dy).sqrt(); | ||
if distance <= query_radius { | ||
expected.push(*id); | ||
} | ||
} | ||
expected.sort(); | ||
|
||
// Compute the actual results using the range query | ||
let mut actual = rindex.query(query_point, query_radius); | ||
actual.sort(); | ||
assert_eq!(expected, actual); | ||
|
||
// Compute the actual results using the k nearest neighbors query | ||
let mut actual = rindex.query_neighbors(query_point, expected.len()); | ||
actual.sort(); | ||
assert_eq!(expected, actual); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use rindex::Rindex; | ||
|
||
#[test] | ||
fn basic_usage() { | ||
let mut rindex = Rindex::default(); | ||
|
||
// Insert some points | ||
let a = rindex.insert([1.0, 1.0]); | ||
let b = rindex.insert([2.0, 2.0]); | ||
let c = rindex.insert([3.0, 3.0]); | ||
let d = rindex.insert([20.0, 20.0]); | ||
|
||
// Query the tree for nearest neighbors of the query point | ||
let query_point = [0.0, 0.0]; | ||
let result = rindex.query_neighbors(query_point, 3); | ||
|
||
// The result should contain the points a, b, and c | ||
assert_eq!(result.len(), 3); | ||
assert!(result.contains(&a)); | ||
assert!(result.contains(&b)); | ||
assert!(result.contains(&c)); | ||
|
||
// Delete the point c | ||
rindex.delete(c); | ||
|
||
// Query the tree again (c should not be in the result) | ||
let result = rindex.query_neighbors(query_point, 3); | ||
assert_eq!(result.len(), 3); | ||
assert!(result.contains(&a)); | ||
assert!(result.contains(&b)); | ||
assert!(result.contains(&d)); | ||
} |