Skip to content

Commit 7b1f14d

Browse files
committed
redo ind2sub / sub2ind redesign
1 parent df5f4a2 commit 7b1f14d

File tree

2 files changed

+33
-87
lines changed

2 files changed

+33
-87
lines changed

base/abstractarray.jl

Lines changed: 30 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -993,71 +993,27 @@ function repmat(a::AbstractVector, m::Int)
993993
return b
994994
end
995995

996-
sub2ind(dims) = 1
997-
sub2ind(dims, i::Integer) = Int(i)
998-
sub2ind(dims, i::Integer, j::Integer) = sub2ind(dims, Int(i), Int(j))
999-
sub2ind(dims, i::Int, j::Int) = (j-1)*dims[1] + i
1000-
sub2ind(dims, i0::Integer, i1::Integer, i2::Integer) = sub2ind(dims, Int(i0),Int(i1),Int(i2))
1001-
sub2ind(dims, i0::Int, i1::Int, i2::Int) =
1002-
i0 + dims[1]*((i1-1) + dims[2]*(i2-1))
1003-
sub2ind(dims, i0::Integer, i1::Integer, i2::Integer, i3::Integer) =
1004-
sub2ind(dims, Int(i0),Int(i1),Int(i2),Int(i3))
1005-
sub2ind(dims, i0::Int, i1::Int, i2::Int, i3::Int) =
1006-
i0 + dims[1]*((i1-1) + dims[2]*((i2-1) + dims[3]*(i3-1)))
1007-
1008-
function sub2ind(dims, I::Integer...)
1009-
ndims = length(dims)
1010-
index = Int(I[1])
1011-
stride = 1
1012-
for k=2:ndims
1013-
stride = stride * dims[k-1]
1014-
index += (Int(I[k])-1) * stride
1015-
end
1016-
return index
1017-
end
996+
sub2ind(dims::Tuple{}) = 1
997+
sub2ind(dims::Tuple{},i1::Integer, I::Integer...) = i1==1 ? sub2ind(dims,I...) : throw(BoundsError())
998+
sub2ind(dims::Tuple{Integer,Vararg{Integer}}, i1::Integer) = i1
999+
sub2ind(dims::Tuple{Integer,Vararg{Integer}}, i1::Integer, I::Integer...) = i1 + dims[1]*(sub2ind(tail(dims),I...)-1)
10181000

1019-
function sub2ind{T<:Integer}(dims::Array{T}, sub::Array{T})
1020-
ndims = length(dims)
1021-
ind = sub[1]
1022-
stride = 1
1023-
for k in 2:ndims
1024-
stride = stride * dims[k - 1]
1025-
ind += (sub[k] - 1) * stride
1026-
end
1027-
return ind
1001+
ind2sub(dims::Tuple{}, ind::Integer) = ind==1 ? () : throw(BoundsError())
1002+
ind2sub(dims::Tuple{Integer}, ind::Integer) = (ind,)
1003+
function ind2sub(dims::Tuple{Integer,Vararg{Integer}}, ind::Integer)
1004+
@_inline_meta()
1005+
ind2 = div(ind-1,dims[1])+1
1006+
tuple(ind-dims[1]*(ind2-1), ind2sub(tail(dims),ind2)...)
10281007
end
10291008

1030-
sub2ind{T<:Integer}(dims, I::AbstractVector{T}...) =
1031-
[ sub2ind(dims, map(X->X[i], I)...)::Int for i=1:length(I[1]) ]
1009+
# TODO in v0.5: either deprecate line 1 or add line 2
1010+
ind2sub(a::AbstractArray, ind::Integer) = ind2sub(size(a), ind)
1011+
# sub2ind(a::AbstractArray, I::Integer...) = sub2ind(size(a), I...)
10321012

1033-
function ind2sub(dims::Tuple{Integer,Vararg{Integer}}, ind::Int)
1034-
ndims = length(dims)
1035-
stride = dims[1]
1036-
for i=2:ndims-1
1037-
stride *= dims[i]
1038-
end
1039-
1040-
sub = ()
1041-
for i=(ndims-1):-1:1
1042-
rest = rem(ind-1, stride) + 1
1043-
sub = tuple(div(ind - rest, stride) + 1, sub...)
1044-
ind = rest
1045-
stride = div(stride, dims[i])
1046-
end
1047-
return tuple(ind, sub...)
1048-
end
1013+
sub2ind{T<:Integer}(dims::Tuple{Vararg{Integer}}, I::AbstractVector{T}...) =
1014+
[ sub2ind(dims, map(X->X[i], I)...)::Int for i=1:length(I[1]) ]
10491015

1050-
ind2sub(dims::Tuple{Vararg{Integer}}, ind::Integer) = ind2sub(dims, Int(ind))
1051-
ind2sub(dims::Tuple{}, ind::Integer) = ind==1 ? () : throw(BoundsError())
1052-
ind2sub(dims::Tuple{Integer,}, ind::Int) = (ind,)
1053-
ind2sub(dims::Tuple{Integer,Integer}, ind::Int) =
1054-
(rem(ind-1,dims[1])+1, div(ind-1,dims[1])+1)
1055-
ind2sub(dims::Tuple{Integer,Integer,Integer}, ind::Int) =
1056-
(rem(ind-1,dims[1])+1, div(rem(ind-1,dims[1]*dims[2]), dims[1])+1,
1057-
div(rem(ind-1,dims[1]*dims[2]*dims[3]), dims[1]*dims[2])+1)
1058-
ind2sub(a::AbstractArray, ind::Integer) = ind2sub(size(a), Int(ind))
1059-
1060-
function ind2sub{T<:Integer}(dims::Tuple{Integer,Vararg{Integer}}, ind::AbstractVector{T})
1016+
function ind2sub{T<:Integer}(dims::Tuple{Vararg{Integer}}, ind::AbstractVector{T})
10611017
n = length(dims)
10621018
l = length(ind)
10631019
t = ntuple(n, x->Array(Int, l))
@@ -1070,20 +1026,15 @@ function ind2sub{T<:Integer}(dims::Tuple{Integer,Vararg{Integer}}, ind::Abstract
10701026
return t
10711027
end
10721028

1073-
function ind2sub!{T<:Integer}(sub::Array{T}, dims::Array{T}, ind::T)
1029+
function ind2sub!{T<:Integer}(sub::Array{T}, dims::Tuple{Vararg{T}}, ind::T)
10741030
ndims = length(dims)
1075-
stride = dims[1]
1076-
for i in 2:(ndims - 1)
1077-
stride *= dims[i]
1078-
end
1079-
for i in (ndims - 1):-1:1
1080-
rest = rem1(ind, stride)
1081-
sub[i + 1] = div(ind - rest, stride) + 1
1082-
ind = rest
1083-
stride = div(stride, dims[i])
1031+
for i=1:ndims-1
1032+
ind2 = div(ind-1,dims[i])+1
1033+
sub[i] = ind - dims[i]*(ind2-1)
1034+
ind = ind2
10841035
end
1085-
sub[1] = ind
1086-
return
1036+
sub[ndims] = ind
1037+
return sub
10871038
end
10881039

10891040
# Generalized repmat
@@ -1099,26 +1050,18 @@ function repeat{T}(A::Array{T};
10991050
throw(ArgumentError("inner/outer repetitions must be set for all input dimensions"))
11001051
end
11011052

1102-
size_in = Array(Int, ndims_in)
1103-
size_out = Array(Int, ndims_out)
1104-
inner_size_out = Array(Int, ndims_out)
1053+
inner = vcat(inner, ones(Int,ndims_out-length_inner))
1054+
outer = vcat(outer, ones(Int,ndims_out-length_outer))
11051055

1106-
for i in 1:ndims_in
1107-
size_in[i] = size(A, i)
1108-
end
1109-
for i in 1:ndims_out
1110-
t1 = ndims_in < i ? 1 : size_in[i]
1111-
t2 = length_inner < i ? 1 : inner[i]
1112-
t3 = length_outer < i ? 1 : outer[i]
1113-
size_out[i] = t1 * t2 * t3
1114-
inner_size_out[i] = t1 * t2
1115-
end
1056+
size_in = size(A)
1057+
size_out = ntuple(i->inner[i]*size(A,i)*outer[i],ndims_out)::Dims
1058+
inner_size_out = ntuple(i->inner[i]*size(A,i),ndims_out)::Dims
11161059

11171060
indices_in = Array(Int, ndims_in)
11181061
indices_out = Array(Int, ndims_out)
11191062

11201063
length_out = prod(size_out)
1121-
R = Array(T, size_out...)
1064+
R = Array(T, size_out)
11221065

11231066
for index_out in 1:length_out
11241067
ind2sub!(indices_out, size_out, index_out)
@@ -1130,7 +1073,7 @@ function repeat{T}(A::Array{T};
11301073
indices_in[t] = fld1(indices_in[t], inner[t])
11311074
end
11321075
end
1133-
index_in = sub2ind(size_in, indices_in)
1076+
index_in = sub2ind(size_in, indices_in...)
11341077
R[index_out] = A[index_in]
11351078
end
11361079

base/deprecated.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,9 @@ end
421421
@deprecate flipud(A::AbstractArray) flipdim(A, 1)
422422
@deprecate fliplr(A::AbstractArray) flipdim(A, 2)
423423

424+
@deprecate sub2ind{T<:Integer}(dims::Array{T}, sub::Array{T}) sub2ind(tuple(dims...), sub...)
425+
@deprecate ind2sub!{T<:Integer}(sub::Array{T}, dims::Array{T}, ind::T) ind2sub!(sub, tuple(dims...), ind)
426+
424427
@deprecate strftime Libc.strftime
425428
@deprecate strptime Libc.strptime
426429
@deprecate flush_cstdio Libc.flush_cstdio

0 commit comments

Comments
 (0)