Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1825,7 +1825,7 @@ foreach(f, itrs...) = (for z in zip(itrs...); f(z...); end; nothing)
## dims specifies which dimensions will be transformed. for example
## dims==1:2 will call f on all slices A[:,:,...]
"""
mapslices(f, A, dims)
mapslices(f, A; dims)

Transform the given dimensions of array `A` using function `f`. `f` is called on each slice
of `A` of the form `A[...,:,...,:,...]`. `dims` is an integer vector specifying where the
Expand Down Expand Up @@ -1853,7 +1853,7 @@ julia> a = reshape(Vector(1:16),(2,2,2,2))
13 15
14 16

julia> mapslices(sum, a, [1,2])
julia> mapslices(sum, a, dims = [1,2])
1×1×2×2 Array{Int64,4}:
[:, :, 1, 1] =
10
Expand All @@ -1868,11 +1868,13 @@ julia> mapslices(sum, a, [1,2])
58
```
"""
mapslices(f, A::AbstractArray, dims) = mapslices(f, A, [dims...])
function mapslices(f, A::AbstractArray, dims::AbstractVector)
function mapslices(f, A::AbstractArray; dims)
if isempty(dims)
return map(f,A)
end
if !isa(dims, AbstractVector)
dims = [dims...]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduces a new instability here, but this is already an unstable "outer" function with a stable kernel, so I was hoping it wouldn't affect things too much. Unfortunately it seems to have quite a large effect (6-10x) in my cursory tests:

# Commit 948b088f17 (3 days old master)
julia> g(f, A, dims) =  mapslices(f, A, dims)
g (generic function with 1 method)

julia> A = rand(500,500);

julia> @benchmark g(sum, $A, 1)
BenchmarkTools.Trial:
  memory estimate:  111.84 KiB
  allocs estimate:  4040
  --------------
  minimum time:     713.670 μs (0.00% GC)
  median time:      729.114 μs (0.00% GC)
  mean time:        750.090 μs (2.53% GC)
  maximum time:     51.052 ms (98.37% GC)
  --------------
  samples:          6637
  evals/sample:     1

# jb/mapslicesdims/d184a46949 (fork: 1 commits, 0 days)
julia> g(f, A, dims) =  mapslices(f, A, dims=dims)
g (generic function with 1 method)

julia> A = rand(500,500);

julia> @benchmark g(sum, $A, 1)
BenchmarkTools.Trial:
  memory estimate:  345.75 KiB
  allocs estimate:  15517
  --------------
  minimum time:     4.575 ms (0.00% GC)
  median time:      4.606 ms (0.00% GC)
  mean time:        4.718 ms (1.90% GC)
  maximum time:     55.249 ms (91.39% GC)
  --------------
  samples:          1059
  evals/sample:     1

end

dimsA = [axes(A)...]
ndimsA = ndims(A)
Expand Down
1 change: 1 addition & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,7 @@ export readandwrite
@deprecate mapreducedim(f, op, A::AbstractArray, dims, v0) mapreduce(f, op, v0, A, dims=dims)
@deprecate reducedim(op, A::AbstractArray, dims) reduce(op, A, dims=dims)
@deprecate reducedim(op, A::AbstractArray, dims, v0) reduce(op, v0, A, dims=dims)
@deprecate mapslices(op, A::AbstractArray, dims) mapslices(op, A, dims=dims)

@deprecate sort(A::AbstractArray, dim::Integer; kwargs...) sort(A; kwargs..., dims=dim)

Expand Down
4 changes: 2 additions & 2 deletions base/reducedim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ function reducedim_initarray0(A::AbstractArray{T}, region, f, ops) where T
end
end

reducedim_initarray0_empty(A::AbstractArray, region, f, ops) = mapslices(x->ops(f.(x)), A, region)
reducedim_initarray0_empty(A::AbstractArray, region,::typeof(identity), ops) = mapslices(ops, A, region)
reducedim_initarray0_empty(A::AbstractArray, region, f, ops) = mapslices(x->ops(f.(x)), A, dims = region)
reducedim_initarray0_empty(A::AbstractArray, region,::typeof(identity), ops) = mapslices(ops, A, dims = region)

# TODO: better way to handle reducedim initialization
#
Expand Down
2 changes: 1 addition & 1 deletion base/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ equivalent to calculating mean of two median elements.
"""
median(v::AbstractArray; dims=:) = _median(v, dims)

_median(v::AbstractArray, dims) = mapslices(median!, v, dims)
_median(v::AbstractArray, dims) = mapslices(median!, v, dims = dims)

_median(v::AbstractArray{T}, ::Colon) where {T} = median!(copyto!(Array{T,1}(undef, _length(v)), v))

Expand Down
42 changes: 21 additions & 21 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1006,57 +1006,57 @@ end
@testset "mapslices" begin
local a, b, c, m, h, s
a = rand(5,5)
s = mapslices(sort, a, [1])
S = mapslices(sort, a, [2])
s = mapslices(sort, a, dims=[1])
S = mapslices(sort, a, dims=[2])
for i = 1:5
@test s[:,i] == sort(a[:,i])
@test vec(S[i,:]) == sort(vec(a[i,:]))
end

# issue #3613
b = mapslices(sum, fill(1.,2,3,4), [1,2])
b = mapslices(sum, fill(1.,2,3,4), dims=[1,2])
@test size(b) === (1,1,4)
@test all(b.==6)

# issue #5141
## Update Removed the version that removes the dimensions when dims==1:ndims(A)
c1 = mapslices(x-> maximum(-x), a, [])
c1 = mapslices(x-> maximum(-x), a, dims=[])
@test c1 == -a

# other types than Number
@test mapslices(prod,["1" "2"; "3" "4"],1) == ["13" "24"]
@test mapslices(prod,["1"],1) == ["1"]
@test mapslices(prod,["1" "2"; "3" "4"],dims=1) == ["13" "24"]
@test mapslices(prod,["1"],dims=1) == ["1"]

# issue #5177

c = fill(1,2,3,4)
m1 = mapslices(x-> fill(1,2,3), c, [1,2])
m2 = mapslices(x-> fill(1,2,4), c, [1,3])
m3 = mapslices(x-> fill(1,3,4), c, [2,3])
m1 = mapslices(x-> fill(1,2,3), c, dims=[1,2])
m2 = mapslices(x-> fill(1,2,4), c, dims=[1,3])
m3 = mapslices(x-> fill(1,3,4), c, dims=[2,3])
@test size(m1) == size(m2) == size(m3) == size(c)

n1 = mapslices(x-> fill(1,6), c, [1,2])
n2 = mapslices(x-> fill(1,6), c, [1,3])
n3 = mapslices(x-> fill(1,6), c, [2,3])
n1a = mapslices(x-> fill(1,1,6), c, [1,2])
n2a = mapslices(x-> fill(1,1,6), c, [1,3])
n3a = mapslices(x-> fill(1,1,6), c, [2,3])
n1 = mapslices(x-> fill(1,6), c, dims=[1,2])
n2 = mapslices(x-> fill(1,6), c, dims=[1,3])
n3 = mapslices(x-> fill(1,6), c, dims=[2,3])
n1a = mapslices(x-> fill(1,1,6), c, dims=[1,2])
n2a = mapslices(x-> fill(1,1,6), c, dims=[1,3])
n3a = mapslices(x-> fill(1,1,6), c, dims=[2,3])
@test size(n1a) == (1,6,4) && size(n2a) == (1,3,6) && size(n3a) == (2,1,6)
@test size(n1) == (6,1,4) && size(n2) == (6,3,1) && size(n3) == (2,6,1)

# mutating functions
o = fill(1, 3, 4)
m = mapslices(x->fill!(x, 0), o, 2)
m = mapslices(x->fill!(x, 0), o, dims=2)
@test m == zeros(3, 4)
@test o == fill(1, 3, 4)

# issue #18524
m = mapslices(x->tuple(x), [1 2; 3 4], 1)
m = mapslices(x->tuple(x), [1 2; 3 4], dims=1)
@test m[1,1] == ([1,3],)
@test m[1,2] == ([2,4],)

# issue #21123
@test mapslices(nnz, sparse(1.0I, 3, 3), 1) == [1 1 1]
@test mapslices(nnz, sparse(1.0I, 3, 3), dims=1) == [1 1 1]
end

@testset "single multidimensional index" begin
Expand Down Expand Up @@ -1183,7 +1183,7 @@ end

# mutating functions
o = fill(1, 3, 4)
m = mapslices(x->fill!(x, 0), o, 2)
m = mapslices(x->fill!(x, 0), o, dims=2)
@test m == zeros(3, 4)
@test o == fill(1, 3, 4)

Expand Down Expand Up @@ -1987,8 +1987,8 @@ copyto!(S, A)
@test cumsum(A, dims=1) == cumsum(B, dims=1) == cumsum(S, dims=1)
@test cumsum(A, dims=2) == cumsum(B, dims=2) == cumsum(S, dims=2)

@test mapslices(sort, A, 1) == mapslices(sort, B, 1) == mapslices(sort, S, 1)
@test mapslices(sort, A, 2) == mapslices(sort, B, 2) == mapslices(sort, S, 2)
@test mapslices(sort, A, dims=1) == mapslices(sort, B, dims=1) == mapslices(sort, S, dims=1)
@test mapslices(sort, A, dims=2) == mapslices(sort, B, dims=2) == mapslices(sort, S, dims=2)

@test reverse(A, dims=1) == reverse(B, dims=1) == reverse(S, dims=2)
@test reverse(A, dims=2) == reverse(B, dims=2) == reverse(S, dims=2)
Expand Down
4 changes: 2 additions & 2 deletions test/offsetarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,8 @@ v = OffsetArray(rand(8), (-2,))
@test sort(A, dims=1) == OffsetArray(sort(parent(A), dims=1), A.offsets)
@test sort(A, dims=2) == OffsetArray(sort(parent(A), dims=2), A.offsets)

@test mapslices(sort, A, 1) == OffsetArray(mapslices(sort, parent(A), 1), A.offsets)
@test mapslices(sort, A, 2) == OffsetArray(mapslices(sort, parent(A), 2), A.offsets)
@test mapslices(sort, A, dims=1) == OffsetArray(mapslices(sort, parent(A), dims=1), A.offsets)
@test mapslices(sort, A, dims=2) == OffsetArray(mapslices(sort, parent(A), dims=2), A.offsets)

@test rotl90(A) == OffsetArray(rotl90(parent(A)), A.offsets[[2,1]])
@test rotr90(A) == OffsetArray(rotr90(parent(A)), A.offsets[[2,1]])
Expand Down
2 changes: 1 addition & 1 deletion test/reducedim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ using Random

function safe_mapslices(op, A, region)
newregion = intersect(region, 1:ndims(A))
return isempty(newregion) ? A : mapslices(op, A, newregion)
return isempty(newregion) ? A : mapslices(op, A, dims = newregion)
end
safe_sum(A::Array{T}, region) where {T} = safe_mapslices(sum, A, region)
safe_prod(A::Array{T}, region) where {T} = safe_mapslices(prod, A, region)
Expand Down