A performance-critical function of a bigger program that I’m writing consists of locating points on a grid. It amounts to finding the indices and weights needed for a linear interpolation/extrapolation—without doing the actual interpolation/extrapolation.
What I have written as of yet is below. I’ve been coding Julia for about a week and would very much appreciate some pointers on how I might improve what I’ve written.
Perhaps this functionality can be found in the Interpolations.jl package, but I haven’t been able to figure out how. The gridpoints
vectors will typically be irregularly spaced.
function locate(
value::AbstractFloat,
gridpoints::AbstractVector{<:AbstractFloat};
locate_below::Bool=false,
locate_above::Bool=false,
)::Tuple{Integer, AbstractVector{<:AbstractFloat}}
if value <= gridpoints[1]
index = 1
if !locate_below
weights = [1.0, 0.0]
return index, weights
end
elseif value >= gridpoints[end]
index = length(gridpoints) - 1
if !locate_above
weights = [0.0, 1.0]
return index, weights
end
else
index = findlast(gridpoints .<= value)
end
weights = (
[
gridpoints[index + 1] - value,
value - gridpoints[index]
] ./ (
gridpoints[index + 1] - gridpoints[index]
)
)
return index, weights
end
function locate(
values::AbstractArray{<:AbstractFloat},
gridpoints::AbstractVector{<:AbstractFloat};
locate_below::Bool=false,
locate_above::Bool=false,
)::Tuple{AbstractArray{Integer}, AbstractArray{<:AbstractFloat}}
indices = ones(Integer, size(values))
weights = zeros(2, size(values)...)
for ix in CartesianIndices(values)
indices[ix], weights[:, ix] = locate(
values[ix],
gridpoints;
locate_below=locate_below,
locate_above=locate_above
)
end
return indices, weights
end