Skip to content

Commit

Permalink
Merge pull request #9 from Deduction42/DEV
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
RGonTheNoble authored Sep 26, 2024
2 parents 1cc59d4 + acefb35 commit 73791f5
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "TimeRecords"
uuid = "b543fe20-4c68-4b5f-af79-4641a0d39826"
authors = ["Ruben Gonzalez <[email protected]> and contributors"]
version = "1.1.1"
version = "1.2.0"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
1 change: 0 additions & 1 deletion src/TimeRecords.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,5 @@ module TimeRecords
findouter,
findbounds,
clampedbounds,
extendedbounds,
keeplatest!
end
12 changes: 5 additions & 7 deletions src/_TimeSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,11 @@ function Base.keepat!(ts::AbstractTimeSeries, inds)
return ts
end

Base.length(ts::AbstractTimeSeries) = length(records(ts))
Base.size(ts::AbstractTimeSeries) = (length(records(ts)),)
Base.firstindex(ts::AbstractTimeSeries) = firstindex(records(ts))
Base.lastindex(ts::AbstractTimeSeries) = lastindex(records(ts))
Base.sort!(ts::AbstractTimeSeries) = sort!(records(ts))


Base.length(ts::AbstractTimeSeries) = length(records(ts))
Base.size(ts::AbstractTimeSeries) = (length(records(ts)),)
Base.firstindex(ts::AbstractTimeSeries) = firstindex(records(ts))
Base.lastindex(ts::AbstractTimeSeries) = lastindex(records(ts))
Base.sort!(ts::AbstractTimeSeries) = sort!(records(ts))

"""
push!(ts::TimeSeries, tr::TimeRecord)
Expand Down
58 changes: 33 additions & 25 deletions src/find.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ findinner(ts::AbstractTimeSeries, Δt::TimeInterval, indhint::Integer=firstindex
Finds the indices of the time series (ts) where Δt[begin] <= ts.t <= Δt[end])
"""
function findinner(ts::AbstractTimeSeries, Δt::TimeInterval, indhint=nothing)
bndL = extendedbounds(ts, Δt[begin], indhint)
bndL = findbounds(ts, Δt[begin], indhint)
lb = ifelse(_equal_timestamp(ts, bndL[1], Δt[begin]), bndL[1], bndL[2])

bndU = extendedbounds(ts, Δt[end], lb)
bndU = findbounds(ts, Δt[end], lb)
ub = ifelse(_equal_timestamp(ts, bndU[2], Δt[end]), bndU[2], bndU[1])
return lb:ub
end
Expand All @@ -44,12 +44,8 @@ function findinner(ts::AbstractTimeSeries, Δt::TimeInterval, indhint::Base.RefV
return ind
end

function _equal_timestamp(ts::TimeSeries, ind::Integer, t::Real)
if firstindex(ts) <= ind <= lastindex(ts)
return timestamp(ts[ind])==t
else
return false
end
function _equal_timestamp(ts::TimeSeries, ind::Integer, t::Real)
return checkbounds(Bool, ts, ind) ? timestamp(ts[ind])==t : false
end


Expand Down Expand Up @@ -85,6 +81,8 @@ _unitrange(x::Pair) = x[begin]:x[end]
findbounds(ts::AbstractTimeSeries, t::Real, indhint::Integer)
Finds the index of the TimeRecord before and after t::Real; indhint is the first index searched for
If t is not inside the timeseries, one of the bounds will not be in its index range
If in-range bounds are desired, use clampedbounds(ts, t, indhint) instead
"""
function findbounds(ts::AbstractTimeSeries, t::Real, indhint::Integer)
earlier_than_t(x::TimeRecord) = timestamp(x) <= t
Expand All @@ -95,45 +93,47 @@ function findbounds(ts::AbstractTimeSeries, t::Real, indhint::Integer)
indhint = clamp(indhint, ind0, indN)

if earlier_than_t(ts[indhint]) #Walk forward in time if indhint record occurs earlier than t
indH = findnext(later_than_t, ts, indhint)
indL = something(indH, indN+1) - 1
indL = max(indL, ind0)
indH = something(findnext(later_than_t, ts, indhint), indN+1)
indL = indH - 1
return indL => indH

else #Walk backwards in time if indhint reccord occurs later than t
indL = findprev(earlier_than_t, ts, indhint)
indH = something(indL, firstindex(ts)-1) + 1
indH = min(indH, indN)
indL = something(findprev(earlier_than_t, ts, indhint), ind0-1)
indH = indL + 1
return indL => indH
end
end

"""
findbounds(ts::AbstractTimeSeries, t::Real, indhint::RefValue{<:Integer})
findbounds(ts::AbstractTimeSeries, t::Real, indhint::Base.RefValue{<:Integer})
Finds the index of the TimeRecord before and after t::Real; indhint is the first index searched for
The upper limit of the boundary is saved in indhint (unless it's nothing, then the lower boundary is saved)
Previous results are saved in indhint in order to provide hits for future calls if they're made in order
If t is not inside the timeseries, one of the bounds will not be in its index range
If in-range bounds are desired, use clampedbounds(ts, t, indhint) instead
"""
function findbounds(ts::AbstractTimeSeries, t::Real, indhint::Base.RefValue{<:Integer})
(lb, ub) = findbounds(ts, t, indhint[])
indhint[] = something(ub, lb)
indhint[] = clamp(ub, firstindex(ts), lastindex(ts))
return lb => ub
end


"""
findbounds(ts::AbstractTimeSeries, t::Real)
Finds bounding indices for timeseries (ts) at time (t) using a bisection method
Finds the index of the TimeRecord before and after t::Real using the bisection method
If t is not inside the timeseries, one of the bounds will not be in its index range
If in-range bounds are desired, use clampedbounds(ts, t, indhint) instead
"""
function findbounds(ts::AbstractTimeSeries, t::Real)
(lb, ub) = (firstindex(ts), lastindex(ts))
T = typeof(lb)

if t < timestamp(ts[lb])
return nothing=>lb
return (lb-1)=>lb
elseif timestamp(ts[ub]) < t
return ub => nothing
return ub => (ub+1)
end

while (ub-lb) > 1
Expand All @@ -151,18 +151,25 @@ end
findbounds(ts::AbstractTimeSeries, t::Real, indhint::Nothing) = findbounds(ts, t)

"""
clampedbounds(ts::AbstractTimeSeries, t::Real, indhint::RefValue{<:Integer})
clampedbounds(ts::AbstractTimeSeries, t::Real, indhint=nothing)
Behaves like findbounds except that it always returns integer boundaries within the timeseries bounds
Out-of-bound results yield repeating lower bounds, or repeating upper bounds
"""
clampedbounds(ts::AbstractTimeSeries, t::Real, indhint) = clampbounds(findbounds(ts, t, indhint))
function clampedbounds(ts::AbstractTimeSeries, t::Real, indhint=nothing)
(lb, ub) = findbounds(ts, t, indhint)
(minb, maxb) = (firstindex(ts), lastindex(ts))
return clamp(lb, minb, maxb) => clamp(ub, minb, maxb)
end


#=
"""
extendedbounds(ts::AbstractTimeSeries, t::Real, indhint::RefValue{<:Integer})
findbounds(ts::AbstractTimeSeries, t::Real, indhint::RefValue{<:Integer})
Behaves like findbounds except that it always returns integer boundaries within the timeseries bounds
"""
extendedbounds(ts::AbstractTimeSeries, t::Real, indhint) = extendbounds(findbounds(ts, t, indhint))
findbounds(ts::AbstractTimeSeries, t::Real, indhint) = extendbounds(findbounds(ts, t, indhint))
"""
Expand All @@ -181,4 +188,5 @@ Clamps the result of findbounds so that results contain integers (not Nothing) b
"""
extendbounds(t::Pair{Nothing, <:Integer}) = (t[2]-1) => t[2]
extendbounds(t::Pair{<:Integer, Nothing}) = t[1] => (t[1]+1)
extendbounds(t::Pair{<:Integer, <:Integer}) = t
extendbounds(t::Pair{<:Integer, <:Integer}) = t
=#
2 changes: 1 addition & 1 deletion src/interpolate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Will return TimeRecord{t, Missing} if t is not within the range of the timeserie
"""
function strictinterp(f_extrap::Function, ts::AbstractTimeSeries, t::Real, indhint=nothing)
(lb, ub) = findbounds(ts, t, indhint)
if isnothing(lb) | isnothing(ub)
if !(checkbounds(Bool, ts, lb) & checkbounds(Bool, ts, ub))
return TimeRecord(t, missing)
else
return f_extrap(ts[lb], ts[ub], t)
Expand Down

2 comments on commit 73791f5

@RGonTheNoble
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register

Release notes:

Breaking changes

  1. extendedbounds(ts, t, indhint) is now removed, its functionality is replaced by findbounds(ts, t, indhint)
  2. findbounds(ts, t, indhint) no longer returns "nothing" in any results, but will potentially return out-of-bounds indices if t is not inside the range of ts. Those who want results to always be within the bounds can still use clampedbounds(ts, t, indhint)

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/116064

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.2.0 -m "<description of version>" 73791f53d9f49d5cbb524935f71e896cd4edd943
git push origin v1.2.0

Please sign in to comment.