Skip to content

Support several inputs instead of just x #33

@gdalle

Description

@gdalle

At the moment, if derivatives wrt several inputs are needed, our recommendation is to use ComponentArrays.jl to concatenate them into a single vector. However, this is not very handy and can lead to performance issues: the naive keyword-based constructor for ComponentVector is type-unstable:

julia> using ComponentArrays, Test

julia> @inferred ComponentVector(a=1, b=[2, 3])
ERROR: return type ComponentVector{Int64, Vector{Int64}, Tuple{Axis{(a = 1, b = 2:3)}}} does not match inferred return type Any
Stacktrace:
   [1] error(s::String)
     @ Base ./error.jl:35

julia> f() = ComponentVector(a=1, b=[2, 3])
f (generic function with 1 method)

julia> @inferred f()
ERROR: return type ComponentVector{Int64, Vector{Int64}, Tuple{Axis{(a = 1, b = 2:3)}}} does not match inferred return type Any
Stacktrace:
   [1] error(s::String)
     @ Base ./error.jl:35

In fact, achieving type-stable construction would require knowing the array sizes statically (SciML/ComponentArrays.jl#126 (comment)), which is impossible in many cases.

An alternative would be to accept an arbitrary number of input arrays on our end. After brief experimentation, I fear this would introduce new sources of type instability as we loop through the args and splat them, storing results in vectors or tuples.

My proposal is to manually add support for two arguments. It will lead to code duplication but ensure type stability, and should cover a lot of use cases. Most notably, it will be necessary to implement implicit linear solvers, and thus enable second-order differentiation out of the box (#26).

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions