Skip to content

Instantly share code, notes, and snippets.

@JeffreySarnoff
Last active November 22, 2022 04:15
Show Gist options
  • Save JeffreySarnoff/2202e4c99c404172330b5f7fec7812a1 to your computer and use it in GitHub Desktop.
Save JeffreySarnoff/2202e4c99c404172330b5f7fec7812a1 to your computer and use it in GitHub Desktop.
examples (a) from the redesign of RollingFunctions.jl
# see example at line 60
using StatsBase
abstract type Accumulator{T} <: Function end
const AccNum = Float64 # client settable via ENV
StatsBase.nobs(acc::Accumulator) = acc.nobs
#=
incremental accumulation of `minimum`
=#
mutable struct AccMinimum{T} <: Accumulator{T}
nobs::Int
nmin::Int
min::T
end
nmin(acc::AccMinimum) = acc.nmin
function AccMinimum(::Type{T}=AccNum) where {T}
AccMinimum{T}(0, 0, typemax(T))
end
function (acc::AccMinimum{T})() where {T}
acc.min
end
function (acc::AccMinimum{T})(x) where {T}
acc.nobs += 1
if x < acc.min
acc.nmin += 1
acc.min = x
end
acc
end
function (acc::AccMinimum{T})(xs::A) where {T, A<:AbstractVector{T}}
acc.nobs += length(xs)
x = vminimum(xs)
if x < acc.min
acc.nmin += 1
acc.min = x
end
acc
end
function (acc::AccMinimum{T})(xs::NTuple{N,T}) where {T, N}
acc.nobs += N
x = minimum(xs)
if x < acc.min
acc.nmin += 1
acc.min = x
end
acc
end
#=
the following example shows
minimum at index 1 = 5.0
minimum at index 2 = 5.0
minimum at index 3 = 4.0
minimum at index 4 = 4.0
minimum at index 5 = 4.0
minimum at index 6 = 3.0
minimum at index 7 = 1.0
minimum at index 8 = 1.0
The minimum value is 1.0.
The rolling minimum changed 3 times.
=#
xs = Float32[5, 8, 4, 7, 6, 3, 1, 9]
acc = AccMinimum(eltype(xs))
for i in eachindex(xs)
acc(xs[i])
currentmin = acc()
str = string(" minimum at index ", i, " = ", currentmin)
println(str)
end
result = string("\n The minimum value is ", acc(),".");
changes = string("\n The rolling minimum changed ", nmin(acc)-1," times.");
println(result * changes)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment