JuliaLang/julia — pull request #5177 by mschauer (2013-12-16 23:38:31+00:00)
Title: Mapslices for nonscalar arguments

Because of #5140 I took a detailed look at mapslices and how it arranges the results of ``f(s)``, where ``s`` denotes the slices along dimensions ``slicedims`` of array ``A``, into a new array ``R = [f(s)]``.

I should just explain it here for anyone interested.
As stated in the documentation, concatenated along the sliced dimensions.
The new array inherits the number of dimensions of ``A``, and the length of the dimensions not sliced over stays the same. The length of the ``n`` first dimensions in ``slicedims`` get modified to accomodate the ``r``'s.
In fact, for the result ``R`` has the shape sizeR with
```
sizeR = size(A)
sizeR[slicedims] = [size(r), fill up with ones]
```

For example if ``f`` is scalar
```
julia> mapslices(sum, rand(4,5), [1])
1x5 Array{Float64,2}:
1.80329 1.98077 2.89279 1.69202 2.69841
julia> mapslices(sum, rand(4,5), [2])
4x1 Array{Float64,2}:
1.84754
2.56395
2.14556
2.23409
```
and the following centers the columns versus the rows.
```
A = mapslices(x-> x-mean(x), rand(4,5), [2])
4x5 Array{Float64,2}:
0.230468 0.0108605 -0.141878 -0.219276 0.119825
-0.106796 -0.318773 -0.147437 0.290916 0.28209
0.350075 -0.261308 -0.166023 -0.0719417 0.149197
-0.00311726 -0.352739 0.374071 0.10547 -0.123686
julia> round(sum(A,2), 8)
4x1 Array{Float64,2}:
-0.0
-0.0
0.0
0.0
```
The implementation doesn't handle f is twodimensional,
because in line https://github.com/JuliaLang/julia/blob/master/base/abstractarray.jl#L1628
the left and right side differ by dimensions of length 1
```
julia> A = mapslices(x-> x-mean(x), rand(4,3,2), [2,3])
ERROR: argument dimensions must match
in setindex! at array.jl:606
in mapslices at abstractarray.jl:1631
```

A possible fix is to assign elementwise if ndims(r) > 1.