@@ -13,7 +13,120 @@ import Adapt
13
13
14
14
import Tables, IteratorInterfaceExtensions
15
15
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
+ """
16
111
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
+ """
17
130
abstract type AbstractDiffEqArray{T, N, A} <: AbstractVectorOfArray{T, N, A} end
18
131
19
132
include (" utils.jl" )
0 commit comments