I played around with moving averages, but for an iterative algorithm and low memory requirements (storing a lot of values), exponential smoothing seems the way to go.
To calculate the smoothed value over time I came up with this monster:
smooth(t,x,w) = getindex.(
accumulate(
(a,b)->(b[1],(a[2]*exp(-a[1]/w)+(1-exp(-a[1]/w))*b[2])),
Iterators.zip(vcat(diff(t),0),x)
),2)
Is there a package that does something like this nicer / faster?
Here is an example:
t = rand(500)
t[170:200] .*=20
t = cumsum(t)
x = rand(500)
x[200:250] .*=10
x = cumsum(x)
using GLMakie
plot(t,x)
w = 20
plot!(t.-w,smooth(t,x,w))
julia> using BenchmarkTools
julia> @benchmark smooth(t,x,w)
@benchmark smooth(t,x,w)
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
Range (min … max): 13.840 μs … 97.470 μs ┊ GC (min … max): 0.00% … 0.00%
Time (median): 19.480 μs ┊ GC (median): 0.00%
Time (mean ± σ): 20.006 μs ± 2.835 μs ┊ GC (mean ± σ): 0.00% ± 0.00%
▅█▆▂
▂▂▂▂▂▁▂▁▁▂▂▂▂▂▂▂▁▁▂▂▂▂▁▁▂▁▂▂▂▂▂▂▄████▇▅▇▆▆▄▃▃▃▂▄▅▅▄▃▃▃▃▃▃▂▂ ▃
13.8 μs Histogram: frequency by time 22.9 μs <
Memory estimate: 20.12 KiB, allocs estimate: 4.