You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -78,6 +78,7 @@ knn!(idxs, dists, tree, point, k [, skip=Returns(false)])
78
78
*`point[s]`: A vector or matrix of points to find the `k` nearest neighbors for. A vector of numbers represents a single point; a matrix means the `k` nearest neighbors for each point (column) will be computed. `points` can also be a vector of vectors.
79
79
*`k`: Number of nearest neighbors to find.
80
80
*`skip` (optional): A predicate function to skip certain points, e.g., points already visited.
81
+
*`skip_self` (optional, batched queries only): Skip the point with the same index as the current query when the query set is identical to the tree data, e.g. `knn(tree, data, 1; skip_self=true)`.
81
82
82
83
83
84
For the single closest neighbor, you can use `nn`:
@@ -145,6 +146,12 @@ dists
145
146
# 0.04556078331418939
146
147
# 0.049967238112417205
147
148
149
+
# Self-query the same dataset without returning each point as its own neighbor
150
+
idxs, dists =knn(kdtree, data, 1; skip_self=true)
151
+
152
+
# Retrieve just the nearest neighbor per point
153
+
nn_idx, nn_dist =nn(kdtree, data; skip_self=true)
154
+
148
155
# Preallocating input results
149
156
idxs, dists =zeros(Int32, k), zeros(Float32, k)
150
157
knn!(idxs, dists, kdtree, v, k)
@@ -162,6 +169,8 @@ inrange!(idxs, tree, point, radius)
162
169
*`tree`: The tree instance.
163
170
*`point[s]`: A vector or matrix of points to find neighbors for.
164
171
*`radius`: Search radius.
172
+
*`skip` (optional): Predicate to skip certain points.
173
+
*`skip_self` (optional, batched queries only): When querying the same dataset, skip the point whose index matches the query.
165
174
166
175
Note: Distances are not returned, only indices.
167
176
@@ -188,6 +197,10 @@ inrange!(idxs, balltree, point, r)
inrange_point!(tree, point, radius, sortres, idx, skip::F) where {F} =_inrange_point!(tree, point, radius, sortres, idx, skip)
39
+
inrange_point!(tree, point, radius, sortres, idx, skip::F, self_idx::Int) where {F} =_inrange_point!(tree, point, radius, sortres, idx, skip, self_idx)
36
40
37
-
function_inrange_point!(tree, point, radius, sortres, idx, skip::F) where {F}
38
-
count =_inrange(tree, point, radius, idx, skip)
41
+
function_inrange_point!(tree, point, radius, sortres, idx, skip::F, self_idx::Int) where {F}
42
+
count =_inrange(tree, point, radius, idx, skip, self_idx)
39
43
if idx !==nothing
40
44
inner_tree =get_tree(tree)
41
45
if inner_tree.reordered
@@ -62,25 +66,38 @@ Useful to avoid allocations or specify the element type of the output vector.
62
66
63
67
See also: `inrange`, `inrangecount`.
64
68
"""
65
-
functioninrange!(idxs::AbstractVector, tree::NNTree{V}, point::AbstractVector{T}, radius::Number, sortres=false, skip=Returns(false)) where {V, T <:Number}
69
+
functioninrange!(idxs::AbstractVector, tree::NNTree{V}, point::AbstractVector{T}, radius::Number, sortres=false, skip=Returns(false); skip_self::Bool=false) where {V, T <:Number}
70
+
skip_self &&throw(ArgumentError("skip_self is only supported for batched queries; pass a skip predicate instead for single points"))
66
71
check_input(tree, point)
67
72
check_for_nan_in_points(point)
68
73
check_radius(radius)
69
74
length(idxs) ==0||throw(ArgumentError("idxs must be empty"))
70
-
inrange_point!(tree, point, radius, sortres, idxs, skip)
75
+
inrange_point!(tree, point, radius, sortres, idxs, skip, 0)
71
76
return idxs
72
77
end
73
78
74
-
functioninrange(tree::NNTree{V}, point::AbstractVector{T}, radius::Number, sortres=false) where {V, T <:Number}
79
+
functioninrange(tree::NNTree{V}, point::AbstractVector{T}, radius::Number, sortres=false; skip_self::Bool=false) where {V, T <:Number}
80
+
skip_self &&throw(ArgumentError("skip_self is only supported for batched queries; pass a skip predicate instead for single points"))
75
81
returninrange!(Int[], tree, point, radius, sortres)
76
82
end
77
83
78
-
functioninrange(tree::NNTree{V}, points::AbstractMatrix{T}, radius::Number, sortres=false) where {V, T <:Number}
84
+
# Single-point variant with an explicit skip predicate
85
+
functioninrange(tree::NNTree{V}, point::AbstractVector{T}, radius::Number, sortres::Bool, skip::F=Returns(false); skip_self::Bool=false) where {V, T <:Number, F}
86
+
skip_self &&throw(ArgumentError("skip_self is only supported for batched queries; pass a skip predicate instead for single points"))
87
+
returninrange!(Int[], tree, point, radius, sortres, skip)
88
+
end
89
+
90
+
functioninrange(tree::NNTree{V}, points::AbstractMatrix{T}, radius::Number, sortres=false; skip_self::Bool=false) where {V, T <:Number}
functioninrange_matrix(tree::NNTree{V}, points::AbstractMatrix{T}, radius::Number, ::Val{dim}, sortres, skip::F=Returns(false)) where {V, T <:Number, dim, F}
100
+
functioninrange_matrix(tree::NNTree{V}, points::AbstractMatrix{T}, radius::Number, ::Val{dim}, sortres, skip::F=Returns(false); skip_self::Bool=false) where {V, T <:Number, dim, F}
84
101
#TODO: DRY with inrange for AbstractVector
85
102
check_input(tree, points)
86
103
check_for_nan_in_points(points)
@@ -90,7 +107,8 @@ function inrange_matrix(tree::NNTree{V}, points::AbstractMatrix{T}, radius::Numb
90
107
91
108
for i in1:n_points
92
109
point =SVector{dim,T}(ntuple(j -> points[j, i], Val(dim)))
93
-
inrange_point!(tree, point, radius, sortres, idxs[i], skip)
110
+
self_idx = skip_self ? i :0
111
+
inrange_point!(tree, point, radius, sortres, idxs[i], skip, self_idx)
94
112
end
95
113
return idxs
96
114
end
@@ -104,32 +122,40 @@ Count all the points in the tree which are closer than `radius` to `points`.
104
122
- `tree`: The tree instance
105
123
- `points`: Query point(s) - can be a vector (single point), matrix (multiple points), or vector of vectors
106
124
- `radius`: Search radius
125
+
- `skip` (optional): Predicate to skip certain points.
126
+
- `skip_self` (optional, batched queries only): When querying the same dataset, skip the point whose index matches the query index.
107
127
108
128
# Returns
109
129
- `count`: Number of points within the radius (integer for single point, vector for multiple points)
110
130
"""
111
-
functioninrangecount(tree::NNTree{V}, point::AbstractVector{T}, radius::Number, skip::F=Returns(false)) where {V, T <:Number, F}
131
+
functioninrangecount(tree::NNTree{V}, point::AbstractVector{T}, radius::Number, skip::F=Returns(false); skip_self::Bool=false) where {V, T <:Number, F}
132
+
skip_self &&throw(ArgumentError("skip_self is only supported for batched queries; pass a skip predicate instead for single points"))
112
133
check_input(tree, point)
113
134
check_for_nan_in_points(point)
114
135
check_radius(radius)
115
-
returninrange_point!(tree, point, radius, false, nothing, skip)
136
+
returninrange_point!(tree, point, radius, false, nothing, skip, 0)
116
137
end
117
138
118
139
functioninrangecount(tree::NNTree,
119
140
points::AbstractVector{T},
120
-
radius::Number, skip::F=Returns(false)) where {T <:AbstractVector, F}
141
+
radius::Number, skip::F=Returns(false); skip_self::Bool=false) where {T <:AbstractVector, F}
functioninrangecount(tree::NNTree{V}, points::AbstractMatrix{T}, radius::Number, skip::F=Returns(false)) where {V, T <:Number, F}
153
+
functioninrangecount(tree::NNTree{V}, points::AbstractMatrix{T}, radius::Number, skip::F=Returns(false); skip_self::Bool=false) where {V, T <:Number, F}
0 commit comments