The AbstractVectorOfArray and AbstractDiffEqArray Interfaces
RecursiveArrayTools.AbstractVectorOfArray
— TypeAbstractVectorOfArray{T, N, A}
An AbstractVectorOfArray is an object which represents arrays of arrays, and arbitrary recursive nesting of arrays, as a single array-like object. Thus a canonical example of an AbstractVectorOfArray is something of the form VectorOfArray([[1,2],[3,4]])
, which "acts" like the matrix [1 3; 2 4] where the data is stored and accessed in a column-ordered fashion (as is typical in Julia), but the actual matrix is never constructed and instead lazily represented through the type.
An AbstractVectorOfArray subtype should match the following behaviors.
In 2023 the linear indexing A[i]
was deprecated. It previously had the behavior that
A[i] = A.u[i]. However, this is incompatible with standard
AbstractArrayinterfaces, Since if
A = VectorOfArray([[1,2],[3,4]])and
Ais supposed to act like
[1 3; 2 4], then there is a difference
A[1] = [1,2]for the VectorOfArray while
A[1] = 1for the matrix. This causes many issues if
AbstractVectorOfArray <: AbstractArray. Thus we plan in 2026 to complete the deprecation and thus have a breaking update where
A[i]matches the linear indexing of an
AbstractArray, and then making
AbstractVectorOfArray <: AbstractArray. Until then,
AbstractVectorOfArray` due to this interface break but manually implements an AbstractArray-like interface for future compatibility.
Fields
An AbstractVectorOfArray has the following fields:
u
which holds the Vector of values at each timestep
Array Interface
The general operations are as follows. Use
A.u[j]
to access the j
th array. For multidimensional systems, this will address first by component and lastly by time, and thus
A[i, j]
will be the i
th component at array j
. Hence, A[j][i] == A[i, j]
. This is done because Julia is column-major, so the leading dimension should be contiguous in memory. If the independent variables had shape (for example, was a matrix), then i
is the linear index. We can also access solutions with shape:
A[i, k, j]
gives the [i,k]
component of the system at array j
. The colon operator is supported, meaning that
A[i, :]
gives the timeseries for the i
th component.
Using the AbstractArray Interface
The AbstractArray
interface can be directly used. For example, for a vector system of variables A[i,j]
is a matrix with rows being the variables and columns being the timepoints. Operations like A'
will transpose the solution type. Functionality written for AbstractArray
s can directly use this. For example, the Base cov
function computes correlations amongst columns, and thus:
cov(A)
computes the correlation of the system state in time, whereas
cov(A, 2)
computes the correlation between the variables. Similarly, mean(A,2)
is the mean of the variable in time, and var(A,2)
is the variance. Other statistical functions and packages which work on AbstractArray
types will work on the solution type.
Conversions
At anytime, a true Array
can be created using Array(A)
, or more generally stack(A)
to make the array type match the internal array type (for example, if A
is an array of GPU arrays, stack(A)
will be a GPU array).
RecursiveArrayTools.AbstractDiffEqArray
— TypeAbstractDiffEqArray{T, N, A} <: AbstractVectorOfArray{T, N, A}
An AbstractVectorOfArray object which has extra information of a time array A.t
in order to specify a time series. A canonical AbstractDiffEqArray is for example the pairing DiffEqArray([[1,2],[3,4]],[1.0,2.0])
which means that at time 1.0 the values were [1,2]
and at time 2.0 the values were [3,4]
.
An AbstractDiffEqArray has all of the same behaviors as an AbstractVectorOfArray with the additional properties:
Fields
An AbstractDiffEqArray adds the following fields:
t
which holds the times of each timestep.