Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use FindFirstFunctions.jl #233

Merged
merged 6 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ uuid = "82cc6244-b520-54b8-b5a6-8a565e85f1d0"
version = "4.7.0"

[deps]
FindFirstFunctions = "64ca27bc-2ba2-4a57-88aa-44e436879224"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
Expand All @@ -24,6 +25,7 @@ DataInterpolationsSymbolicsExt = "Symbolics"
[compat]
Aqua = "0.8"
ChainRulesCore = "1"
FindFirstFunctions = "1"
ChrisRackauckas marked this conversation as resolved.
Show resolved Hide resolved
FiniteDifferences = "0.12.31"
ForwardDiff = "0.10.19"
LinearAlgebra = "1.10"
Expand Down
6 changes: 0 additions & 6 deletions docs/src/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,3 @@ CubicSpline
BSplineInterpolation
BSplineApprox
```

# Utility Functions

```@docs
DataInterpolations.bracketstrictlymontonic
```
2 changes: 2 additions & 0 deletions src/DataInterpolations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ end

using LinearAlgebra, RecipesBase
using PrettyTables
import FindFirstFunctions: searchsortedfirstcorrelated, searchsortedlastcorrelated,
bracketstrictlymontonic

include("interpolation_caches.jl")
include("interpolation_utils.jl")
Expand Down
66 changes: 0 additions & 66 deletions src/interpolation_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,69 +62,3 @@ function munge_data(U::StridedMatrix, t::AbstractVector)

return hcat(newUs...), newt
end

"""
bracketstrictlymontonic(v, x, guess; lt=<comparison>, by=<transform>, rev=false)

Starting from an initial `guess` index, find indices `(lo, hi)` such that `v[lo] ≤ x ≤ v[hi]`
according to the specified order, assuming that `x` is actually within the range of
values found in `v`. If `x` is outside that range, either `lo` will be `firstindex(v)` or
`hi` will be `lastindex(v)`.

Note that the results will not typically satisfy `lo ≤ guess ≤ hi`. If `x` is precisely
equal to a value that is not unique in the input `v`, there is no guarantee that `(lo, hi)`
will encompass *all* indices corresponding to that value.

This algorithm is essentially an expanding binary search, which can be used as a precursor
to `searchsorted` and related functions, which can take `lo` and `hi` as arguments. The
purpose of using this function first would be to accelerate convergence in those functions
by using correlated `guess`es for repeated calls. The best `guess` for the next call of
this function would be the index returned by the previous call to `searchsorted`.

See `sort!` for an explanation of the keyword arguments `by`, `lt` and `rev`.
"""
function bracketstrictlymontonic(v::AbstractVector,
x,
guess::T,
o::Base.Order.Ordering)::NTuple{2, keytype(v)} where {T <: Integer}
bottom = firstindex(v)
top = lastindex(v)
if guess < bottom || guess > top
return bottom, top
# # NOTE: for cache efficiency in repeated calls, we avoid accessing the first and last elements of `v`
# # on each call to this function. This should only result in significant slow downs for calls with
# # out-of-bounds values of `x` *and* bad `guess`es.
# elseif lt(o, x, v[bottom])
# return bottom, bottom
# elseif lt(o, v[top], x)
# return top, top
else
u = T(1)
lo, hi = guess, min(guess + u, top)
@inbounds if Base.Order.lt(o, x, v[lo])
while lo > bottom && Base.Order.lt(o, x, v[lo])
lo, hi = max(bottom, lo - u), lo
u += u
end
else
while hi < top && !Base.Order.lt(o, x, v[hi])
lo, hi = hi, min(top, hi + u)
u += u
end
end
end
return lo, hi
end

function searchsortedfirstcorrelated(v::AbstractVector, x, guess)
lo, hi = bracketstrictlymontonic(v, x, guess, Base.Order.Forward)
searchsortedfirst(v, x, lo, hi, Base.Order.Forward)
end

function searchsortedlastcorrelated(v::AbstractVector, x, guess)
lo, hi = bracketstrictlymontonic(v, x, guess, Base.Order.Forward)
searchsortedlast(v, x, lo, hi, Base.Order.Forward)
end

searchsortedfirstcorrelated(r::AbstractRange, x, _) = searchsortedfirst(r, x)
searchsortedlastcorrelated(r::AbstractRange, x, _) = searchsortedlast(r, x)
Loading