https://github.com/mcabbott/starslice.jl
🥒
https://github.com/mcabbott/starslice.jl
Last synced: 4 months ago
JSON representation
🥒
- Host: GitHub
- URL: https://github.com/mcabbott/starslice.jl
- Owner: mcabbott
- Created: 2020-03-14T04:02:15.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2020-03-16T21:20:51.000Z (over 6 years ago)
- Last Synced: 2024-10-13T19:28:30.830Z (over 1 year ago)
- Language: Julia
- Homepage:
- Size: 11.7 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# StarSlice.jl
This package overloads `getindex` and friends to make slices.
Inserting `*` means that a given index will label the position in the outer container.
`view` makes views, and `eachslice` makes a generator:
```julia
julia> ones(Int, 2,3,4)[:, *, 4]
3-element Array{Array{Int64,1},1}:
[1, 1]
[1, 1]
[1, 1]
julia> @view ones(Int, 2,3)[*, :]
2-element Array{SubArray{Int64,1,Array{Int64,2},Tuple{Int64,Base.Slice{Base.OneTo{Int64}}},true},1}:
[1, 1, 1]
[1, 1, 1]
julia> eachslice(ones(Int, 2,3,4,5), *, :, 4, *) |> typeof
Base.Generator{Base.Iterators.ProductIterator{Tuple{Base.OneTo{Int64},Base.RefValue{Colon},
Base.RefValue{Int64},Base.OneTo{Int64}}},StarSlice.var"#75#76"{Array{Int64,4}}}
```
While dimensions marked `*` belong only to the outer container,
and those marked `:` belong only to the inner array,
those marked `&` or `!` belong to both,
surviving as trivial dimensions of either the slices, or the container.
```julia
julia> ones(Int, 2,3,4)[!, *, 4] # with `!` in place of `:`, outer array keeps 1st dimension
1×3 Array{Array{Int64,1},2}:
[1, 1] [1, 1] [1, 1]
julia> ones(Int, 2,3,4)[:, &, 4] # with `&` in place of `*`, inner arrays keep 2nd dimension
3-element Array{Array{Int64,2},1}:
[1; 1]
[1; 1]
[1; 1]
julia> size(first(ans))
(2, 1)
```
One use of this is for `mapslices`-like operations. It goes well with [LazyStack.jl](https://github.com/mcabbott/LazyStack.jl):
```julia
julia> using StarSlice, LazyStack
julia> info(x) = [ndims(x), size(x)...]
info (generic function with 1 method)
julia> mapslices(info, rand(10,20,30), dims=(1,3))
3×20×1 Array{Int64,3}:
[:, :, 1] =
2 2 2 2 2 2 2 2 … 2 2 2 2 2 2 2
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
julia> stack(info, @view rand(10,20,30)[:,*,:])
3×20 Array{Int64,2}:
2 2 2 2 2 2 2 2 … 2 2 2 2 2 2 2
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
```
Another is to explore reductions...
```julia
mat = rand(1:99, 3, 4)
prod.(mat[!,*]) == prod(mat, dims=1)
prod.(mat[:,*]) == dropdims(prod(mat, dims=1), dims=1)
sum(mat[:,&]) == sum(mat, dims=2) # but this won't work for prod
sum(mat[:,*]) == dropdims(sum(mat, dims=2), dims=2)
```
Right now the `eachslice` generator returns an `Array` not a view, and re-uses the same one. But this appears to provide few benefits.
### See also
* [JuliennedArrays.jl](https://github.com/bramtayl/JuliennedArrays.jl)
* [LazyStack.jl](https://github.com/mcabbott/LazyStack.jl)
* [SliceMap.jl](https://github.com/mcabbott/SliceMap.jl), differentiable mapslices.
* [JuliaLang/julia#32310](https://github.com/JuliaLang/julia/pull/32310) about `EachSlice` type
* [tkf/ReduceDims.jl](https://github.com/tkf/ReduceDims.jl) from [JuliaLang/julia#16606](https://github.com/JuliaLang/julia/issues/16606). Compare:
```julia
using ReduceDims, StarSlice
mat = rand(1:99, 3, 4)
s1 = sum(along(mat, &, :)) # lazy mapreduce along "&" directions
sum(mat, dims=1) .== s1 # all equal
sum(mat[&, :]) == sum.(mat[:, &]) == copy(s1)
p1 = prod(along(mat, &, :)) |> copy
prod(mat, dims=1) == p1
prod.(mat[:, *]) == vec(p1) # and prod(mat[*, :]) is an error
```