Thanks for the suggestions, I really need to how Ref
s work, as I am not yet familiar with them. In the meantime, I also have managed to find an implementation that relies on a FunctionCallingCallback
that simply updates a value in an array. The relevant code is as follows:
function functioncallback(saved_value)
du = zeros(Float64, S)
#~ Define Welford's algorithm for rolling mean and variance
#!note: need to be properly weighted by the current time
function f(u, t, integrator)
#~ Compute differences and update mean and sum of squared differences
du .= u .- saved_value[:,1]
saved_value[:,1] .= saved_value[:,1] .+ du .* (dt / (t - tstart))
saved_value[:,2] .= saved_value[:,2] .+ du .* (u .- saved_value[:,1]) .* dt
return nothing
end
#!note: start at tstart=dt to avoid Δt=0
funcat = (tstart+dt):dt:prob.tspan[end]
return FunctionCallingCallback(f, funcat=funcat)
end
This seems to allocate the same amount regardless of dt
, which is exactly the behavior that I would expect. It also appears to be thread-safe, but I am not sure whether it actually is…