I’m trying to comprehend the details of the type system and its effect on performance, and would appreciate if you can help me understand how it applies to my current case, thank you!
Question:
Would it be a bad idea to use a SVector
of functions in the field of a composite type, e.g:
struct DifferentiableProblem{N, F <: Function}
target_function::F
derivatives::SVector{N, F}
end
I have two confusions:
- Since each function is its own concrete type with associated methods,
derivatives
field must obtain a concrete type as defined above. But I’m guessing a concrete function object doesn’t have a fixed size, so having aSVector
of them is probably not a good idea? - I know that high-order functions are performant in Julia, and it’s usually not a good idea to store functions in the structs. But in my case these functions are not “methods” to be applied to the data, but they are the part of the data. So that’s why I thought of storing them in a struct, but perhaps there are better approaches. Please see below for details.
Details of the case:
I’m developing a package where the user defines a problem by entering a (non-linear) function f \colon \mathbb{R}^{n+k} \to \mathbb{R}^n, where \mathbb{R}^k can be thought of as the parameter space. Then for each point p in (a grid of) a bounded subset of the parameter space, the program makes some computations, which uses the function f_p \colon \mathbb{R}^n \to \mathbb{R}^n given by f_p(x) = f(x,p), and the main diagonal of its Jacobian. Since for each problem the form of the function f and the relevant entries of its Jacobian is fixed, I thought it might make sense computationally to generate and store the relevant derivative functions once at the beginning when the user defines the problem.
Addendum:
For constructing the derivatives, I am currently doing symbolic calculations using build_function
of Symbolics.jl
for 2 reasons: (1) JuliaInterval
methods are utilized in the computations and I had hard time to mix them well with AD packages, since I guess both use propagation, (2) I thought it would be computationally cheaper to generate the derivative functions symbolically instead of calculating them via AD each time. But maybe I am also confused a bit here.