Skip to content

Commit

Permalink
throw error when trying to reduce along dim <= 0
Browse files Browse the repository at this point in the history
  • Loading branch information
jakebolewski committed Mar 11, 2015
1 parent a3afed7 commit 861603d
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 19 deletions.
93 changes: 74 additions & 19 deletions base/reducedim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,40 @@ reduced_dims(a::AbstractArray, region) = reduced_dims(size(a), region)

# for reductions that keep 0 dims as 0
reduced_dims0(a::AbstractArray, region) = reduced_dims0(size(a), region)
reduced_dims{N}(siz::NTuple{N,Int}, d::Int, rd::Int) = (d == 1 ? tuple(rd, siz[d+1:N]...) :
d == N ? tuple(siz[1:N-1]..., rd) :
1 < d < N ? tuple(siz[1:d-1]..., rd, siz[d+1:N]...) :
siz)::typeof(siz)

function reduced_dims{N}(siz::NTuple{N,Int}, d::Int, rd::Int)
if d < 1
throw(ArgumentError("dimension must be ≥ 1, got $d"))
elseif d == 1
return tuple(rd, siz[d+1:N]...)::typeof(siz)
elseif 1 < d < N
return tuple(siz[1:d-1]..., rd, siz[d+1:N]...)::typeof(siz)
elseif d == N
return tuple(siz[1:N-1]..., rd)::typeof(siz)
else
return siz
end
end
reduced_dims{N}(siz::NTuple{N,Int}, d::Int) = reduced_dims(siz, d, 1)
reduced_dims0{N}(siz::NTuple{N,Int}, d::Int) = 1 <= d <= N ? reduced_dims(siz, d, (siz[d] == 0 ? 0 : 1)) : siz

function reduced_dims0{N}(siz::NTuple{N,Int}, d::Int)
if d < 1
throw(ArgumentError("dimension must be ≥ 1, got $d"))
elseif d <= N
return reduced_dims(siz, d, (siz[d] == 0 ? 0 : 1))
else
return siz
end
end

function reduced_dims{N}(siz::NTuple{N,Int}, region)
rsiz = [siz...]
for i in region
if 1 <= i <= N
rsiz[i] = 1
d = convert(Int, i)::Int
if d < 1
throw(ArgumentError("region dimension(s) must be ≥ 1, got $d"))
elseif d <= N
rsiz[d] = 1
end
end
tuple(rsiz...)::typeof(siz)
Expand All @@ -25,8 +47,11 @@ end
function reduced_dims0{N}(siz::NTuple{N,Int}, region)
rsiz = [siz...]
for i in region
if i <= i <= N
rsiz[i] = (rsiz[i] == 0 ? 0 : 1)
d = convert(Int, i)::Int
if d < 1
throw(ArgumentError("region dimension(s) must be ≥ 1, got $d"))
elseif d <= N
rsiz[d] = (rsiz[d] == 0 ? 0 : 1)
end
end
tuple(rsiz...)::typeof(siz)
Expand Down Expand Up @@ -292,18 +317,48 @@ function gen_findreduction_body(N, f::Function)
end
end

stagedfunction _findmin!{T,N}(Rval::AbstractArray, Rind::AbstractArray, A::AbstractArray{T,N})
# findmin
stagedfunction _findmin!{T,N}(Rval::AbstractArray,
Rind::AbstractArray,
A::AbstractArray{T,N})
gen_findreduction_body(N, <)
end
findmin!{R}(rval::AbstractArray{R}, rind::AbstractArray, A::AbstractArray; init::Bool=true) = _findmin!(initarray!(rval, typemax(R), init), rind, A)
findmin{T}(A::AbstractArray{T}, region) =
isempty(A) ? (similar(A,reduced_dims0(A,region)), zeros(Int,reduced_dims0(A,region))) :
_findmin!(reducedim_initarray0(A, region, typemax(T)), zeros(Int,reduced_dims0(A,region)), A)

stagedfunction _findmax!{T,N}(Rval::AbstractArray, Rind::AbstractArray, A::AbstractArray{T,N})
function findmin!{R}(rval::AbstractArray{R},
rind::AbstractArray,
A::AbstractArray;
init::Bool=true)
_findmin!(initarray!(rval, typemax(R), init), rind, A)
end

function findmin{T}(A::AbstractArray{T}, region)
if isempty(A)
return (similar(A, reduced_dims0(A, region)),
zeros(Int, reduced_dims0(A, region)))
end
return (_findmin!(reducedim_initarray0(A, region, typemax(T)),
zeros(Int, reduced_dims0(A, region)), A))
end

# findmax
stagedfunction _findmax!{T,N}(Rval::AbstractArray,
Rind::AbstractArray,
A::AbstractArray{T,N})
gen_findreduction_body(N, >)
end
findmax!{R}(rval::AbstractArray{R}, rind::AbstractArray, A::AbstractArray; init::Bool=true) = _findmax!(initarray!(rval, typemin(R), init), rind, A)
findmax{T}(A::AbstractArray{T}, region) =
isempty(A) ? (similar(A,reduced_dims0(A,region)), zeros(Int,reduced_dims0(A,region))) :
_findmax!(reducedim_initarray0(A, region, typemin(T)), zeros(Int,reduced_dims0(A,region)), A)

function findmax!{R}(rval::AbstractArray{R},
rind::AbstractArray,
A::AbstractArray;
init::Bool=true)
_findmax!(initarray!(rval, typemin(R), init), rind, A)
end

function findmax{T}(A::AbstractArray{T}, region)
if isempty(A)
return (similar(A, reduced_dims0(A,region)),
zeros(Int, reduced_dims0(A,region)))
end
return (_findmax!(reducedim_initarray0(A, region, typemin(T)),
zeros(Int, reduced_dims0(A, region)), A))
end
14 changes: 14 additions & 0 deletions test/reducedim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,17 @@ A = [1.0 3.0 6.0;
@test std(FloatingPoint[1,2,3], 1) == [1.0]
@test sum(Any[1 2;3 4],1) == [4 6]
@test sum(Vector{Int}[[1,2],[4,3]], 1)[1] == [5,5]

# issue #10461
Areduc = rand(3, 4, 5, 6)
for region in Any[-1, 0, (-1, 2), [0, 1], (1,-2,3), [0 1;
2 3]]
@test_throws ArgumentError sum(Areduc, region)
@test_throws ArgumentError prod(Areduc, region)
@test_throws ArgumentError maximum(Areduc, region)
@test_throws ArgumentError minimum(Areduc, region)
@test_throws ArgumentError sumabs(Areduc, region)
@test_throws ArgumentError sumabs2(Areduc, region)
@test_throws ArgumentError maxabs(Areduc, region)
@test_throws ArgumentError minabs(Areduc, region)
end

0 comments on commit 861603d

Please sign in to comment.