Last active
November 22, 2022 08:07
-
-
Save JeffreySarnoff/849d7352be08645d9b712c3a5272644a to your computer and use it in GitHub Desktop.
examples (b) from the redesign of RollingFunctions.jl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# see example at line 70 | |
# see accumulator enhancement at line 70 | |
using StatsBase | |
abstract type Accumulator{T} <: Function end | |
const AccNum = Float64 # client settable via ENV | |
StatsBase.nobs(acc::Accumulator) = acc.nobs | |
fn(acc::Accumulator) = acc.fn | |
#= | |
incremental accumulation of `minimum` | |
with optional preprocessing function | |
=# | |
mutable struct AccMinimum{T,F} <: Accumulator{T} | |
nobs::Int | |
nmin::Int | |
min::T | |
const fn::F | |
end | |
nmin(acc::AccMinimum) = acc.nmin | |
function AccMinimum(::Type{T}=AccNum, fn::F=identity) where {T,F} | |
AccMinimum{T,F}(0, 0, typemax(T), fn) | |
end | |
function (acc::AccMinimum{T,F})() where {T,F} | |
acc.min | |
end | |
function (acc::AccMinimum{T,F})(x) where {T,F} | |
acc.nobs += 1 | |
y = acc.fn(x) | |
if y < acc.min | |
acc.nmin += 1 | |
acc.min = y | |
end | |
acc | |
end | |
function (acc::AccMinimum{T})(xs::A) where {T, A<:AbstractVector{T}} | |
acc.nobs += length(xs) | |
ys = map(acc.fn, xs) | |
y = vminimum(ys) | |
if y < acc.min | |
acc.nmin += 1 | |
acc.min = y | |
end | |
acc | |
end | |
function (acc::AccMinimum{T})(xs::NTuple{N,T}) where {T, N} | |
acc.nobs += N | |
ys = map(acc.fn, xs) | |
y = minimum(ys) | |
if y < acc.min | |
acc.nmin += 1 | |
acc.min = y | |
end | |
acc | |
end | |
#= | |
the following example shows | |
minimum at index 1 = 6.0 | |
minimum at index 2 = 6.0 | |
minimum at index 3 = 5.0 | |
minimum at index 4 = -2.0 | |
minimum at index 5 = -5.0 | |
minimum at index 6 = -5.0 | |
minimum at index 7 = -5.0 | |
minimum at index 8 = -8.0 | |
The minimum value is -8.0. | |
The rolling minimum changed 4 times. | |
=# | |
xs = Float32[5, 8, 4, -3, -6, 3, 1, -9] | |
acc = AccMinimum(eltype(xs), x->x+1) | |
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) | |
#= | |
accumulator wrapping without the wrapper | |
given the preceeding implementation of AccMinimum | |
that accumulates the minimum value | |
implement an accumulator of the minimum magnitude | |
see example at line 120 | |
=# | |
function AccMinimumMag(::Type{T}=AccNum, fn::F=abs) where {T,F} | |
AccMinimum{T,F}(0, 0, typemax(T), fn) | |
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 = 3.0 | |
minimum at index 5 = 3.0 | |
minimum at index 6 = 3.0 | |
minimum at index 7 = 1.0 | |
minimum at index 8 = 1.0 | |
The minimum magnitude is 1.0. | |
The rolling minimum magnitude changed 3 times. | |
=# | |
xs = Float32[5, 8, 4, -3, -6, 3, 1, -9] | |
acc = AccMinimumMag(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 magnitude is ", acc(),"."); | |
changes = string("\n The rolling minimum magnitude 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