The AbstractVectorOfArray and AbstractDiffEqArray Interfaces

RecursiveArrayTools.AbstractVectorOfArrayType
AbstractVectorOfArray{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.

Note

In 2023 the linear indexing A[i]was deprecated. It previously had the behavior thatA[i] = A.u[i]. However, this is incompatible with standardAbstractArrayinterfaces, Since ifA = VectorOfArray([[1,2],[3,4]])andAis supposed to act like[1 3; 2 4], then there is a differenceA[1] = [1,2]for the VectorOfArray whileA[1] = 1for the matrix. This causes many issues ifAbstractVectorOfArray <: AbstractArray. Thus we plan in 2026 to complete the deprecation and thus have a breaking update whereA[i]matches the linear indexing of anAbstractArray, and then makingAbstractVectorOfArray <: 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 jth array. For multidimensional systems, this will address first by component and lastly by time, and thus

A[i, j]

will be the ith 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 ith 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 AbstractArrays 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).

source
RecursiveArrayTools.AbstractDiffEqArrayType
AbstractDiffEqArray{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.
source