@@ -234,11 +234,77 @@ prob = ODEProblem(foo, ones(5, 5), (0., 1.0), (ones(5,5), LazyBufferCache()))
234234solve (prob, TRBDF2 ())
235235```
236236
237- ## Note About ReverseDiff Support for LazyBuffer
237+ ### Note About ReverseDiff Support for LazyBuffer
238238
239239ReverseDiff support is done in SciMLSensitivity.jl to reduce the AD requirements on this package.
240240Load that package if ReverseDiff overloads are required.
241241
242+ ## GeneralLazyBufferCache
243+
244+ ``` julia
245+ GeneralLazyBufferCache (f= identity)
246+ ```
247+
248+ A ` GeneralLazyBufferCache ` is a ` Dict ` -like type for the caches which automatically defines
249+ new caches on demand when they are required. The function ` f ` generates the cache matching
250+ for the type of ` u ` , and subsequent indexing reuses that cache if that type of ` u ` has
251+ already ben seen.
252+
253+ Note that ` LazyBufferCache ` does cause a dynamic dispatch and its return is not type-inferred.
254+ This means it's the slowest of the preallocation methods, but it's the most general.
255+
256+ ### Example
257+
258+ In all of the previous cases our cache was an array. However, in this case we want to preallocate
259+ a DifferentialEquations ` ODEIntegrator ` object. This object is the one created via
260+ ` DifferentialEquations.init(ODEProblem(ode_fnc, y₀, (0.0, T), p), Tsit5(); saveat = t) ` , and we
261+ want to optimize ` p ` in a way that changes its type to ForwardDiff. Thus what we can do is make a
262+ GeneralLazyBufferCache which holds these integrator objects, defined by ` p ` , and indexing it with
263+ ` p ` in order to retrieve the cache. The first time it's called it will build the integrator, and
264+ in subsequent calls it will reuse the cache.
265+
266+ Defining the cache as a function of ` p ` to build an integrator thus looks like:
267+
268+ ``` julia
269+ lbc = GeneralLazyBufferCache (function (p)
270+ DifferentialEquations. init (ODEProblem (ode_fnc, y₀, (0.0 , T), p), Tsit5 (); saveat = t)
271+ end )
272+ ```
273+
274+ then ` lbc[p] ` will be smart and reuse the caches. A full example looks like the following:
275+
276+ ``` julia
277+ using Random, DifferentialEquations, LinearAlgebra, Optimization, OptimizationNLopt, OptimizationOptimJL, PreallocationTools
278+
279+ lbc = GeneralLazyBufferCache (function (p)
280+ DifferentialEquations. init (ODEProblem (ode_fnc, y₀, (0.0 , T), p), Tsit5 (); saveat = t)
281+ end )
282+
283+ Random. seed! (2992999 )
284+ λ, y₀, σ = - 0.5 , 15.0 , 0.1
285+ T, n = 5.0 , 200
286+ Δt = T / n
287+ t = [j * Δt for j in 0 : n]
288+ y = y₀ * exp .(λ * t)
289+ yᵒ = y .+ [0.0 , σ * randn (n)... ]
290+ ode_fnc (u, p, t) = p * u
291+ function loglik (θ, data, integrator)
292+ yᵒ, n, ε = data
293+ λ, σ, u0 = θ
294+ integrator. p = λ
295+ reinit! (integrator, u0)
296+ solve! (integrator)
297+ ε = yᵒ .- integrator. sol. u
298+ ℓ = - 0.5 n * log (2 π * σ^ 2 ) - 0.5 / σ^ 2 * sum (ε.^ 2 )
299+ end
300+ θ₀ = [- 1.0 , 0.5 , 19.73 ]
301+ negloglik = (θ, p) -> - loglik (θ, p, lbc[θ[1 ]])
302+ fnc = OptimizationFunction (negloglik, Optimization. AutoForwardDiff ())
303+ ε = zeros (n)
304+ prob = OptimizationProblem (fnc, θ₀, (yᵒ, n, ε), lb= [- 10.0 , 1e-6 , 0.5 ], ub= [10.0 , 10.0 , 25.0 ])
305+ solve (prob, LBFGS ())
306+ ```
307+
242308## Similar Projects
243309
244310[ AutoPreallocation.jl] ( https://github.com/oxinabox/AutoPreallocation.jl ) tries
0 commit comments