diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 003b09c235214..f360f2939c692 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -994,7 +994,7 @@ function repmat(a::AbstractVector, m::Int) end sub2ind(dims::Tuple{}) = 1 -sub2ind(dims::Tuple{},i1::Integer, I::Integer...) = i1==1 ? sub2ind(dims,I...) : throw(BoundsError()) +sub2ind(dims::Tuple{},I::Integer...) = sum(I) - length(I) + 1 sub2ind(dims::Tuple{Integer,Vararg{Integer}}, i1::Integer) = i1 sub2ind(dims::Tuple{Integer,Vararg{Integer}}, i1::Integer, I::Integer...) = i1 + dims[1]*(sub2ind(tail(dims),I...)-1) @@ -1010,20 +1010,38 @@ end ind2sub(a::AbstractArray, ind::Integer) = ind2sub(size(a), ind) # sub2ind(a::AbstractArray, I::Integer...) = sub2ind(size(a), I...) -sub2ind{T<:Integer}(dims::Tuple{Vararg{Integer}}, I::AbstractVector{T}...) = - [ sub2ind(dims, map(X->X[i], I)...)::Int for i=1:length(I[1]) ] +function sub2ind{T<:Integer}(dims::Tuple{Vararg{Integer}}, I::AbstractVector{T}...) + N = length(dims) + M = length(I[1]) + indices = copy(I[1]) + + s = dims[1] + for j=2:length(I) + Ij = I[j] + for i=1:M + indices[i] += s*(Ij[i]-1) + end + s*= (j <= N ? dims[j] : 1) + end + return indices +end function ind2sub{T<:Integer}(dims::Tuple{Vararg{Integer}}, ind::AbstractVector{T}) - n = length(dims) - l = length(ind) - t = ntuple(n, x->Array(Int, l)) - for i = 1:l - s = ind2sub(dims, ind[i]) - for j = 1:n - t[j][i] = s[j] + N = length(dims) + M = length(ind) + t = [Array{T}(M) for j=1:N] + copy!(t[1],ind) + for j = 1:N-1 + d = dims[j] + tj = t[j] + tj2 = t[j+1] + for i = 1:M + ind2 = div(tj[i]-1, d) + tj[i] -= d*ind2 + tj2[i] = ind2+1 end end - return t + return tuple(t...) end function ind2sub!{T<:Integer}(sub::Array{T}, dims::Tuple{Vararg{T}}, ind::T)