A Julia design paradigm I often see to avoid allocating temporary arrays in repeated calculations is to use a struct that contains the temporary array and a “functor” for performing the calculation:
struct MyStruct
data::Vector{Float64}
f::FunctionWrapper{Float64, Tuple{Float64, Float64}}
end
function (m::MyStruct)(u)
# mutate u using m.data and m.f
end
In the above example, I’ve also included a function as a field of MyStruct that is used in the calculation, too. I’ve used FunctionWrappers.jl so that this field has a concrete type.
To use this paradigm with ForwardDiff.jl, I know I can use PreallocationTools.jl to replace the temporary array with a cache that can store both, e.g., Float64 data as well as Dual data used by ForwardDiff.jl. Is there an equivalent approach for functions that would replace FunctionWrappers.jl, i.e., so I can have a function that takes and returns both Float64 and Dual data but can be made a field of a struct with a concrete type?