Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Mapslices for nonscalar arguments #5177

Closed
wants to merge 1 commit into from

Conversation

mschauer
Copy link
Contributor

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, the f(s) are 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 nonscalar f 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 A which is 3-dimensional,
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.

	modified:   base/abstractarray.jl
	modified:   test/arrayops.jl
@JeffBezanson
Copy link
Member

A better fix for this would probably be to fix #4048. The special cases and [:] just don't smell right.

@mschauer
Copy link
Contributor Author

Yes, one could see this problem as a hint why relaxing the assignment operation to handle dimensions of size 1 more gracefully would be a good idea. In this case, we have leading and trailing 1's at the same time, so that might still be a problem.

@mschauer mschauer deleted the pull2 branch January 5, 2014 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants