-
Notifications
You must be signed in to change notification settings - Fork 73
Expand file tree
/
Copy pathbrute_tree.jl
More file actions
84 lines (73 loc) · 2.68 KB
/
Copy pathbrute_tree.jl
File metadata and controls
84 lines (73 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
struct BruteTree{V <: AbstractVector,M <: PreMetric} <: NNTree{V,M}
data::Vector{V}
metric::M
reordered::Bool
end
"""
BruteTree(data [, metric = Euclidean()) -> brutetree
Creates a `BruteTree` from the data using the given `metric`.
"""
function BruteTree(data::AbstractVector{V}, metric::PreMetric = Euclidean();
reorder::Bool=false, leafsize::Int=0, storedata::Bool=true) where {V <: AbstractVector}
if metric isa Distances.UnionMetrics
p = parameters(metric)
if p !== nothing && length(p) != length(V)
throw(ArgumentError(
"dimension of input points:$(length(V)) and metric parameter:$(length(p)) must agree"))
end
end
BruteTree(storedata ? Vector(data) : Vector{V}(), metric, reorder)
end
function BruteTree(data::AbstractVecOrMat{T}, metric::PreMetric = Euclidean();
reorder::Bool=false, leafsize::Int=0, storedata::Bool=true) where {T}
dim = size(data, 1)
BruteTree(copy_svec(T, data, Val(dim)),
metric, reorder = reorder, leafsize = leafsize, storedata = storedata)
end
function _knn(tree::BruteTree{V},
point::AbstractVector,
best_idxs::AbstractVector{<:Integer},
best_dists::AbstractVector,
skip::F) where {V, F}
knn_kernel!(tree, point, best_idxs, best_dists, skip)
return
end
function knn_kernel!(tree::BruteTree{V},
point::AbstractVector,
best_idxs::AbstractVector{<:Integer},
best_dists::AbstractVector,
skip::F) where {V, F}
for i in 1:length(tree.data)
if skip(i)
continue
end
dist_d = evaluate(tree.metric, tree.data[i], point)
if dist_d <= best_dists[1]
best_dists[1] = dist_d
best_idxs[1] = i
percolate_down!(best_dists, best_idxs, dist_d, i)
end
end
end
function _inrange(tree::BruteTree,
point::AbstractVector,
radius::Number,
point_index::Int = 1,
callback::Union{Nothing, Function} = nothing)
return inrange_kernel!(tree, point, radius, callback, point_index)
end
function inrange_kernel!(tree::BruteTree,
point::AbstractVector,
r::Number,
callback::Union{Nothing, Function},
point_index::Int)
count = 0
for i in 1:length(tree.data)
d = evaluate(tree.metric, tree.data[i], point)
if d <= r
count += 1
!isnothing(callback) && callback(point_index, i)
end
end
return count
end