I have a simple brute-force search function:
function run_query(search_data::Vector{Float64}, query::Vector{Float64}, search_f::Function)::Tuple{Float64, Int}
current_best = Inf
loc = -1
q_len = length(query)
for d_i in 1:(length(data) - q_len)
dist = search_f(data[d_i:d_i+q_len-1], query)
if dist < current_best
current_best = dist
loc = d_i
end
end
return current_best, loc
end
I have an alternative version of the function which also returns the maximum distance found while searching to data:
function run_query_max(search_data::Vector{Float64}, query::Vector{Float64}, search_f::Function)::Tuple{Float64, Int, Float64}
current_best = Inf
loc = -1
q_len = length(query)
max_dist = 0.
for d_i in 1:(length(data) - q_len)
dist = search_f(data[d_i:d_i+q_len-1], query)
if dist > max_dist
max_dist = dist
end
if dist < current_best
current_best = dist
loc = d_i
end
end
return current_best, loc, max_dist
end
This can be tested as follows:
function simple_dist(data::Vector{Float64}, query::Vector{Float64})::Float64
return sum((data .- query) .^ 2)
end
data = [0., 0., 1., 2.,
3., 1.1, 3., 3.,
1., 0., 0., 1.,
0., 0., 1., 4.5,
2., 1., 0., 0.]
query = [1., 2., 3., 1.]
val, idx = run_query(data, query, simple_dist)
@assert (idx == 3)
@assert isapprox(val, 0.01, atol=0.001)
val, idx, max_dist = run_query_max(data, query, simple_dist)
@assert (idx == 3)
@assert isapprox(val, 0.01, atol=0.001)
@assert isapprox(max_dist, 21.25, atol=0.001)
This pattern of:
- Basic search function
- Add keeping track of maximum distance in search function
Occurs in multiple places in my code. What is a reasonable way to refactor it out?