You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
stack([(i,2.0,3//j) for i=1:4, j=1:5])# isa Array{Real, 3} # size(ans) == (3, 4, 5)
31
-
```
25
+
Generators such as `lazystack([i,2i] for i in 1:5)` and arrays of mixed eltype like `lazystack([1,2], [3.0, 4.0], [5im, 6im])` used to be be handled here, making a dense array, but are now simply passed through to `Base.stack`.
32
26
33
-
The slices must all have the same `size`, but they (and the container)
34
-
can have any number of dimensions. `stack` always places the slice dimensions first.
35
-
There are no options.
27
+
When the individual slices aren't backed by an `Array`, as for instance with `CuArray`s on a GPU, then again `Base.stack` is called.
28
+
This should make one big `CuArray`, since scalar indexing of individual slices won't work well.
36
29
37
30
### Ragged stack
38
31
39
-
There is also a version which does not demand that slices have equal `size` (or equal `ndims`),
40
-
which always returns a new `Array`. You can control the position of slices `using OffsetArrays`:
32
+
There is also a version which does not demand that slices have equal `size` (or equal `ndims`).
33
+
For now this is not lazy:
41
34
42
35
```julia
43
-
rstack([1:n for n in1:10]) # upper triangular Matrix{Int}
44
-
rstack(OffsetArray(fill(n,4), rand(-2:2)) for n in1:10; fill=NaN)
36
+
julia>raggedstack([10:10+n for n in1:3])
37
+
4×3 Matrix{Int64}:
38
+
101010
39
+
111111
40
+
01212
41
+
0013
42
+
43
+
julia>using OffsetArrays
44
+
45
+
julia>raggedstack(OffsetArray(fill(1.0n, 3), rand(-1:1)) for n in1:10; fill=NaN)
46
+
5×10OffsetArray(::Matrix{Float64}, 0:4, 1:10) with eltype Float64 with indices 0:4×1:10:
47
+
NaN2.0NaN4.0NaN6.07.0NaN9.0NaN
48
+
1.02.03.04.05.06.07.0NaN9.010.0
49
+
1.02.03.04.05.06.07.08.09.010.0
50
+
1.0NaN3.0NaN5.0NaNNaN8.0NaN10.0
51
+
NaNNaNNaNNaNNaNNaNNaN8.0NaNNaN
45
52
```
46
53
47
54
### Other packages
48
55
49
-
This one plays well with [OffsetArrays.jl](https://github.com/JuliaArrays/OffsetArrays.jl),
50
-
[NamedDims.jl](https://github.com/invenia/NamedDims.jl), and
51
-
[Zygote.jl](https://github.com/FluxML/Zygote.jl).
56
+
This one plays well with [OffsetArrays.jl](https://github.com/JuliaArrays/OffsetArrays.jl), and [ChainRules.jl](https://github.com/JuliaDiff/ChainRules.jl)-compatible AD such as [Zygote.jl](https://github.com/FluxML/Zygote.jl). It's also used internally by [TensorCast.jl](https://github.com/mcabbott/TensorCast.jl).
52
57
53
58
Besides which, there are several other ways to achieve similar things:
54
59
55
60
* For an array of arrays, you can also use [`JuliennedArrays.Align`](https://bramtayl.github.io/JuliennedArrays.jl/latest/#JuliennedArrays.Align). This requires (or enables) you to specify which dimensions of the output belong to the sub-arrays, instead of writing `PermutedDimsArray(stack(...), ...)`.
56
-
* There is also [`RecursiveArrayTools.VectorOfArray`](https://github.com/JuliaDiffEq/RecursiveArrayTools.jl#vectorofarray) which as its name hints only allows a one-dimensional container. Linear indexing retreives a slice, not an element, which is sometimes surprising.
61
+
* There is also [`RecursiveArrayTools.VectorOfArray`](https://github.com/JuliaDiffEq/RecursiveArrayTools.jl#vectorofarray) which as its name hints only allows a one-dimensional container. (And unlike the package name, nothing is recursive.) Linear indexing retreives a slice, not an element, which is sometimes surprising.
57
62
* For a tuple of arrays, [`LazyArrays.Hcat`](https://github.com/JuliaArrays/LazyArrays.jl#concatenation) is at present faster to index than `stack`, but doesn't allow arbitrary dimensions.
58
-
* For a generator of arrays, the built-in `reduce(hcat,...)` may work, but it slow compared to `stack`: see [test/speed.jl](test/speed.jl) for some examples.
59
63
60
64
And a few more:
61
65
62
66
* When writing this I missed [`SplitApplyCombine.combinedimsview`](https://github.com/JuliaData/SplitApplyCombine.jl#combinedimsviewarray), which is very similar to `stack`, but doesn't handle tuples.
63
67
* Newer than this package is [StackViews.jl](https://github.com/JuliaArrays/StackViews.jl) handles both, with `StackView(A,B,dims=4) == StackView([A,B],4)` creating a 4th dimension; the container is always one-dimensional.
64
68
*[`Flux.stack`](https://fluxml.ai/Flux.jl/stable/utilities/#Flux.stack) similarly takes a dimension, but eagerly creates an `Array`.
69
+
* Finally, [CatViews.jl](https://github.com/ahwillia/CatViews.jl) offers a lazy `vcat`. But the package is old and I think not so fast.
65
70
66
71
The lazy inverse:
67
72
@@ -71,10 +76,10 @@ The lazy inverse:
71
76
72
77
* As does [`PackedVectorsOfVectors`](https://github.com/synchronoustechnologies/PackedVectorsOfVectors.jl), although only 1+1 dimensions. Also has an eager `pack` method which turns a vector of vectors into view of a single larger matrix.
73
78
74
-
*[`Base.eachslice`](https://docs.julialang.org/en/v1/base/arrays/#Base.eachslice) also views one large array as many slices. This is a generator, but [JuliaLang#32310](https://github.com/JuliaLang/julia/pull/32310)should upgrade it to a multi-dimensional container indexable container.
79
+
*[`Base.eachslice`](https://docs.julialang.org/en/v1/base/arrays/#Base.eachslice) also views one large array as many slices. This was a generator, but [JuliaLang#32310](https://github.com/JuliaLang/julia/pull/32310)upgrades it to a multi-dimensional indexable container, in Julia 1.9.
75
80
76
81
Eager:
77
82
78
83
* After writing this I learned of [JuliaLang#31644](https://github.com/JuliaLang/julia/pull/31644) which extends `reduce(hcat,...)` to work on generators.
79
84
80
-
* Later, [JuliaLang#31644](https://github.com/JuliaLang/julia/pull/43334)proposes to add the eager `stack_iter` method of this package to Base.
85
+
* Later, [JuliaLang#43334](https://github.com/JuliaLang/julia/pull/43334)has added a better version of this package's `stack_iter` method to Base.
0 commit comments