Skip to content

Commit 50b064f

Browse files
add a documentation page for the interface
1 parent a2d0d5e commit 50b064f

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

docs/pages.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
pages = [
44
"Home" => "index.md",
5+
"AbstractVectorOfArrayInterface.md",
56
"array_types.md",
67
"recursive_array_functions.md"
78
]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# The AbstractVectorOfArray and AbstractDiffEqArray Interfaces
2+
3+
```@doc
4+
AbstractVectorOfArray
5+
AbstractDiffEqArray
6+
```

src/RecursiveArrayTools.jl

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,120 @@ import Adapt
1313

1414
import Tables, IteratorInterfaceExtensions
1515

16+
"""
17+
AbstractVectorOfArray{T, N, A}
18+
19+
An AbstractVectorOfArray is an object which represents arrays of arrays,
20+
and arbitrary recursive nesting of arrays, as a single array-like object.
21+
Thus a canonical example of an AbstractVectorOfArray is something of the
22+
form `VectorOfArray([[1,2],[3,4]])`, which "acts" like the matrix [1 3; 2 4]
23+
where the data is stored and accessed in a column-ordered fashion (as is typical
24+
in Julia), but the actual matrix is never constructed and instead lazily represented
25+
through the type.
26+
27+
An AbstractVectorOfArray subtype should match the following behaviors.
28+
29+
!!! note
30+
31+
In 2023 the linear indexing `A[i]`` was deprecated. It previously had the behavior that
32+
`A[i] = A.u[i]`. However, this is incompatible with standard `AbstractArray` interfaces,
33+
Since if `A = VectorOfArray([[1,2],[3,4]])` and `A` is supposed to act like `[1 3; 2 4]`,
34+
then there is a difference `A[1] = [1,2]` for the VectorOfArray while `A[1] = 1` for the
35+
matrix. This causes many issues if `AbstractVectorOfArray <: AbstractArray`. Thus we
36+
plan in 2026 to complete the deprecation and thus have a breaking update where `A[i]`
37+
matches the linear indexing of an `AbstractArray`, and then making
38+
`AbstractVectorOfArray <: AbstractArray`. Until then, `AbstractVectorOfArray` due to
39+
this interface break but manaully implements an AbstractArray-like interface for
40+
future compatability.
41+
42+
## Fields
43+
44+
An AbstractVectorOfArray has the following fields:
45+
46+
* `u` which holds the Vector of values at each timestep
47+
48+
## Array Interface
49+
50+
The general operations are as follows. Use
51+
52+
```julia
53+
A.u[j]
54+
```
55+
56+
to access the `j`th array. For multidimensional systems, this
57+
will address first by component and lastly by time, and thus
58+
59+
```julia
60+
A[i, j]
61+
```
62+
63+
will be the `i`th component at array `j`. Hence, `A[j][i] == A[i, j]`. This is done
64+
because Julia is column-major, so the leading dimension should be contiguous in memory.
65+
If the independent variables had shape (for example, was a matrix), then `i` is the
66+
linear index. We can also access solutions with shape:
67+
68+
```julia
69+
A[i, k, j]
70+
```
71+
72+
gives the `[i,k]` component of the system at array `j`. The colon operator is
73+
supported, meaning that
74+
75+
```julia
76+
A[i, :]
77+
```
78+
79+
gives the timeseries for the `i`th component.
80+
81+
## Using the AbstractArray Interface
82+
83+
The `AbstractArray` interface can be directly used. For example, for a vector
84+
system of variables `A[i,j]` is a matrix with rows being the variables and
85+
columns being the timepoints. Operations like `A'` will
86+
transpose the solution type. Functionality written for `AbstractArray`s can
87+
directly use this. For example, the Base `cov` function computes correlations
88+
amongst columns, and thus:
89+
90+
```julia
91+
cov(A)
92+
```
93+
94+
computes the correlation of the system state in time, whereas
95+
96+
```julia
97+
cov(A, 2)
98+
```
99+
100+
computes the correlation between the variables. Similarly, `mean(A,2)` is the
101+
mean of the variable in time, and `var(A,2)` is the variance. Other statistical
102+
functions and packages which work on `AbstractArray` types will work on the
103+
solution type.
104+
105+
## Conversions
106+
107+
At anytime, a true `Array` can be created using `Array(A)`, or more generally `stack(A)`
108+
to make the array type match the internal array type (for example, if `A` is an array
109+
of GPU arrays, `stack(A)` will be a GPU array).
110+
"""
16111
abstract type AbstractVectorOfArray{T, N, A} end
112+
113+
"""
114+
AbstractDiffEqArray{T, N, A} <: AbstractVectorOfArray{T, N, A}
115+
116+
An AbstractVectorOfArray object which has extra information of a time array `A.t`
117+
in order to specify a time series. A canonical AbstractDiffEqArray is for example
118+
the pairing `DiffEqArray([[1,2],[3,4]],[1.0,2.0])` which means that at time 1.0
119+
the values were `[1,2]` and at time 2.0 the values were `[3,4]`.
120+
121+
An AbstractDiffEqArray has all of the same behaviors as an AbstractVectorOfArray with the
122+
additional properties:
123+
124+
## Fields
125+
126+
An AbstractDiffEqArray adds the following fields:
127+
128+
* `t` which holds the times of each timestep.
129+
"""
17130
abstract type AbstractDiffEqArray{T, N, A} <: AbstractVectorOfArray{T, N, A} end
18131

19132
include("utils.jl")

0 commit comments

Comments
 (0)