|
1 | 1 | # ArraysOfArrays.jl
|
2 | 2 |
|
3 |
| -[](https://travis-ci.com/oschulz/ArraysOfArrays.jl) |
4 |
| -[](https://ci.appveyor.com/project/oschulz/ArraysOfArrays-jl) |
| 3 | +[](https://oschulz.github.io/ArraysOfArrays.jl/stable) |
| 4 | +[](https://oschulz.github.io/ArraysOfArrays.jl/dev) |
| 5 | +[](LICENSE.md) |
| 6 | +[](https://travis-ci.com/oschulz/ArraysOfArrays.jl) |
| 7 | +[](https://ci.appveyor.com/project/oschulz/ArraysOfArrays-jl) |
5 | 8 | [](https://codecov.io/gh/oschulz/ArraysOfArrays.jl)
|
6 | 9 |
|
7 | 10 |
|
8 | 11 | A Julia package for efficient storage and handling of nested arrays.
|
9 | 12 |
|
10 | 13 | ArraysOfArrays provides two different types of nested arrays: `ArrayOfSimilarArrays` and `VectorOfArrays`.
|
| 14 | +An `ArrayOfSimilarArrays` offers a duality of view between representing the same data as both a flat multi-dimensional array and as an array of equally-sized arrays. A `VectorOfArrays` represents a vector of arrays of equal dimensionality but different size. Internally, both types store their data in flat arrays that are accessible to the user `flatview()`. |
11 | 15 |
|
| 16 | +## Documentation |
12 | 17 |
|
13 |
| -## ArrayOfSimilarArrays |
14 |
| - |
15 |
| -An `ArrayOfSimilarArrays` offers duality of viewing the same data as both a flat multi-dimensional array and as an array of equally-sized arrays: |
16 |
| - |
17 |
| -```julia |
18 |
| -A_flat = rand(2,3,4,5,6) |
19 |
| -A_nested = nestedview(A_flat, 2) |
20 |
| -``` |
21 |
| - |
22 |
| -creates a view of `A_flat` as an array of arrays: |
23 |
| - |
24 |
| -```julia |
25 |
| -A_nested isa AbstractArray{<:AbstractArray{T,2},3} where T |
26 |
| -``` |
27 |
| - |
28 |
| -`A_flat` is always available via `flatview`. `A_flat` and `A_nested` are backed by the same data, no data is copied: |
29 |
| - |
30 |
| -```julia |
31 |
| -flatview(A_nested) === A_flat |
32 |
| -``` |
33 |
| - |
34 |
| -Calling `getindex` on `A_nested` returns a view into `A_flat`: |
35 |
| - |
36 |
| -```julia |
37 |
| -fill!(A_nested[2, 4, 3], 4.2) |
38 |
| -all(x -> x == 4.2, A_flat[:, :, 2, 4, 3]) |
39 |
| -``` |
40 |
| - |
41 |
| -### Type aliases |
42 |
| - |
43 |
| -The following type aliases are defined: |
44 |
| - |
45 |
| -* `VectorOfSimilarArrays{T,M} = AbstractArrayOfSimilarArrays{T,M,1}` |
46 |
| -* `ArrayOfSimilarVectors{T,N} = AbstractArrayOfSimilarArrays{T,1,N}` |
47 |
| -* `VectorOfSimilarVectors{T} = AbstractArrayOfSimilarArrays{T,1,1}` |
48 |
| - |
49 |
| -For each of the types there is also an abstract type (`AbstractArrayOfSimilarArrays`, etc.). |
50 |
| - |
51 |
| -If a `VectorOfSimilarArrays` is backed by an `ElasticArrays.ElasticArray`, additional element arrays can be pushed into it and `resize!` is available too: |
52 |
| - |
53 |
| -### Appending data and resizing |
54 |
| - |
55 |
| -```julia |
56 |
| -using ElasticArrays |
57 |
| - |
58 |
| -A_nested = nestedview(ElasticArray{Float64}(undef, 2, 3, 0), 2) |
59 |
| - |
60 |
| -for i in 1:4 |
61 |
| - push!(A_nested, rand(2, 3)) |
62 |
| -end |
63 |
| -size(flatview(A_nested)) == (2, 3, 4) |
64 |
| - |
65 |
| -resize!(A_nested, 6) |
66 |
| -size(flatview(A_nested)) == (2, 3, 6) |
67 |
| -``` |
68 |
| - |
69 |
| -There is a full duality between the nested and the flat view of the data. `A_flat` may be resized freely without breaking the inner consistency of `A_nested`: Changes in the shape of one will result in changes in the shape of the other. |
70 |
| - |
71 |
| -### Statistics functions |
72 |
| - |
73 |
| -`AbstractVectorOfSimilarArrays` supports the functions `sum`, `mean` and `var`, `AbstractVectorOfSimilarVectors` additionally support `cov` and `cor`. |
74 |
| - |
75 |
| -Methods for these function are defined both without and with weights (via `StatsBase.AbstractWeights`). Because of this, `ArraysOfArrays` currently requires `StatsBase`. It's possible that this requirement can be dropped in the future, though (see |
76 |
| -[Julia issue #29974](https://github.com/JuliaLang/julia/issues/29974)). |
77 |
| - |
78 |
| -## VectorOfArrays |
79 |
| - |
80 |
| -A `VectorOfArrays` represents a vector of arrays of equal dimensionality but different size. It is a nested interpretation of the concept of a "ragged array". |
81 |
| - |
82 |
| -```julia |
83 |
| -VA = VectorOfArrays{Float64, 2}() |
84 |
| - |
85 |
| -push!(VA, rand(2, 3)) |
86 |
| -push!(VA, rand(4, 2)) |
87 |
| - |
88 |
| -size(VA[1]) == (2,3) |
89 |
| -size(VA[2]) == (4,2) |
90 |
| -``` |
91 |
| - |
92 |
| -Internally, all data is stored efficiently in a single, flat and memory-contiguous vector, accessible via `flatview`: |
93 |
| - |
94 |
| -```julia |
95 |
| -VA_flat = flatview(VA) |
96 |
| -VA_flat isa Vector{Float64} |
97 |
| -``` |
98 |
| - |
99 |
| -Calling `getindex` on `A_nested` returns a view into `A_flat`: |
100 |
| - |
101 |
| -```julia |
102 |
| -VA_flat = flatview(VA) |
103 |
| -view(VA_flat, 7:14) == vec(VA[2]) |
104 |
| - |
105 |
| -fill!(view(VA_flat, 7:14), 2.4) |
106 |
| -all(x -> x == 2.4, VA[2]) |
107 |
| - |
108 |
| -fill!(view(VA_flat, 7:14), 4.2) |
109 |
| -all(x -> x == 4.2, VA[2]) |
110 |
| -``` |
111 |
| - |
112 |
| -### Type aliases |
113 |
| -The following type aliases are defined: |
114 |
| - |
115 |
| -* `VectorOfVectors{T,VT,VI,VD} = VectorOfArrays{T,1,VT,VI,VD}` |
116 |
| - |
117 |
| -### Appending data and resizing |
118 |
| - |
119 |
| -A `VectorOfArrays` is grown by appending data to it. `resize!` can be used to shrink it, but not to grow it (the size of the additional element arrays would be unknown): |
120 |
| - |
121 |
| -``` |
122 |
| -length(resize!(VA, 1)) == 1 |
123 |
| -``` |
124 |
| - |
125 |
| -but |
126 |
| - |
127 |
| -``` |
128 |
| -resize!(VA, 4) |
129 |
| -``` |
130 |
| - |
131 |
| -will fail. |
132 |
| - |
133 |
| -Note: The vector returned by `flatview(VA)` *must not* be resized directly, doing so would break the internal consistency of `VA`. |
134 |
| - |
135 |
| - |
136 |
| -## Allocation free element access |
137 |
| - |
138 |
| -Element access via `getindex` returns (possibly reshaped) instances of `SubArray` for both `ArrayOfSimilarArrays` and `VectorOfArrays`. Usually this is not a problem, but frequent allocation of a large number of views can become a limiting factor in multi-threaded applications. |
139 |
| - |
140 |
| -Both types support `UnsafeArrays.@uviews` for allocation-free getindex: |
141 |
| - |
142 |
| -```julia |
143 |
| -using UnsafeArrays |
144 |
| - |
145 |
| -A = nestedview(rand(2,3,4,5), 2) |
146 |
| - |
147 |
| -isbits(A[2,2]) == false |
148 |
| - |
149 |
| -@uviews A begin |
150 |
| - isbits(A[2,2]) == true |
151 |
| -end |
152 |
| -``` |
153 |
| - |
154 |
| -As always, `UnsafeArray`s should be used with great care: The pointer-based bitstype |
155 |
| -views *must not* be allowed to escape the `@uviews` scope, and internal data of `A` *must not* be reallocated (e.g. due to a `push!` or `append!` on `A`) while the `@uviews` scope is active. |
| 18 | +* [Documentation for stable version](https://oschulz.github.io/ArraysOfArrays.jl/stable) |
| 19 | +* [Documentation for development version](https://oschulz.github.io/ArraysOfArrays.jl/dev) |
0 commit comments