@@ -1009,97 +1009,81 @@ function repmat(a::AbstractVector, m::Int)
10091009 return b
10101010end
10111011
1012- sub2ind (dims) = 1
1013- sub2ind (dims, i:: Integer ) = Int (i)
1014- sub2ind (dims, i:: Integer , j:: Integer ) = sub2ind (dims, Int (i), Int (j))
1015- sub2ind (dims, i:: Int , j:: Int ) = (j- 1 )* dims[1 ] + i
1016- sub2ind (dims, i0:: Integer , i1:: Integer , i2:: Integer ) = sub2ind (dims, Int (i0),Int (i1),Int (i2))
1017- sub2ind (dims, i0:: Int , i1:: Int , i2:: Int ) =
1018- i0 + dims[1 ]* ((i1- 1 ) + dims[2 ]* (i2- 1 ))
1019- sub2ind (dims, i0:: Integer , i1:: Integer , i2:: Integer , i3:: Integer ) =
1020- sub2ind (dims, Int (i0),Int (i1),Int (i2),Int (i3))
1021- sub2ind (dims, i0:: Int , i1:: Int , i2:: Int , i3:: Int ) =
1022- i0 + dims[1 ]* ((i1- 1 ) + dims[2 ]* ((i2- 1 ) + dims[3 ]* (i3- 1 )))
1023-
1024- function sub2ind (dims, I:: Integer... )
1025- ndims = length (dims)
1026- index = Int (I[1 ])
1027- stride = 1
1028- for k= 2 : ndims
1029- stride = stride * dims[k- 1 ]
1030- index += (Int (I[k])- 1 ) * stride
1012+ sub2ind (dims:: Tuple{Vararg{Integer}} ) = 1
1013+ sub2ind (dims:: Tuple{Vararg{Integer}} , I:: Integer... ) = _sub2ind (dims,I)
1014+ @generated function _sub2ind {N,M} (dims:: NTuple{N,Integer} , I:: NTuple{M,Integer} )
1015+ meta = Expr (:meta ,:inline )
1016+ ex = :(I[$ M] - 1 )
1017+ for i = M- 1 : - 1 : 1
1018+ if i > N
1019+ ex = :(I[$ i] - 1 + $ ex)
1020+ else
1021+ ex = :(I[$ i] - 1 + dims[$ i]* $ ex)
1022+ end
10311023 end
1032- return index
1024+ Expr ( :block , meta,:( $ ex + 1 ))
10331025end
10341026
1035- function sub2ind {T<:Integer} (dims:: Array{T} , sub:: Array{T} )
1036- ndims = length (dims)
1037- ind = sub[1 ]
1038- stride = 1
1039- for k in 2 : ndims
1040- stride = stride * dims[k - 1 ]
1041- ind += (sub[k] - 1 ) * stride
1027+ @generated function ind2sub {N} (dims:: NTuple{N,Integer} , ind:: Integer )
1028+ meta = Expr (:meta ,:inline )
1029+ N== 0 && return :($ meta; ind== 1 ? () : throw (BoundsError ()))
1030+ exprs = Expr[:(ind = ind- 1 )]
1031+ for i = 1 : N- 1
1032+ push! (exprs,:(ind2 = div (ind,dims[$ i])))
1033+ push! (exprs,Expr (:(= ),symbol (:s ,i),:(ind- dims[$ i]* ind2+ 1 )))
1034+ push! (exprs,:(ind= ind2))
10421035 end
1043- return ind
1036+ push! (exprs,Expr (:(= ),symbol (:s ,N),:(ind+ 1 )))
1037+ Expr (:block ,meta,exprs... ,Expr (:tuple ,[symbol (:s ,i) for i= 1 : N]. .. ))
10441038end
10451039
1046- sub2ind {T<:Integer} (dims, I:: AbstractVector{T} ...) =
1047- [ sub2ind (dims, map (X-> X[i], I)... ):: Int for i= 1 : length (I[1 ]) ]
1040+ # TODO in v0.5: either deprecate line 1 or add line 2
1041+ ind2sub (a:: AbstractArray , ind:: Integer ) = ind2sub (size (a), ind)
1042+ # sub2ind(a::AbstractArray, I::Integer...) = sub2ind(size(a), I...)
10481043
1049- function ind2sub (dims:: Tuple{Integer,Vararg{Integer}} , ind:: Int )
1050- ndims = length (dims)
1051- stride = dims[1 ]
1052- for i= 2 : ndims- 1
1053- stride *= dims[i]
1054- end
1055-
1056- sub = ()
1057- for i= (ndims- 1 ): - 1 : 1
1058- rest = rem (ind- 1 , stride) + 1
1059- sub = tuple (div (ind - rest, stride) + 1 , sub... )
1060- ind = rest
1061- stride = div (stride, dims[i])
1062- end
1063- return tuple (ind, sub... )
1064- end
1065-
1066- ind2sub (dims:: Tuple{Vararg{Integer}} , ind:: Integer ) = ind2sub (dims, Int (ind))
1067- ind2sub (dims:: Tuple{} , ind:: Integer ) = ind== 1 ? () : throw (BoundsError ())
1068- ind2sub (dims:: Tuple{Integer,} , ind:: Int ) = (ind,)
1069- ind2sub (dims:: Tuple{Integer,Integer} , ind:: Int ) =
1070- (rem (ind- 1 ,dims[1 ])+ 1 , div (ind- 1 ,dims[1 ])+ 1 )
1071- ind2sub (dims:: Tuple{Integer,Integer,Integer} , ind:: Int ) =
1072- (rem (ind- 1 ,dims[1 ])+ 1 , div (rem (ind- 1 ,dims[1 ]* dims[2 ]), dims[1 ])+ 1 ,
1073- div (rem (ind- 1 ,dims[1 ]* dims[2 ]* dims[3 ]), dims[1 ]* dims[2 ])+ 1 )
1074- ind2sub (a:: AbstractArray , ind:: Integer ) = ind2sub (size (a), Int (ind))
1075-
1076- function ind2sub {T<:Integer} (dims:: Tuple{Integer,Vararg{Integer}} , ind:: AbstractVector{T} )
1077- n = length (dims)
1078- l = length (ind)
1079- t = ntuple (n, x-> Array (Int, l))
1080- for i = 1 : l
1081- s = ind2sub (dims, ind[i])
1082- for j = 1 : n
1083- t[j][i] = s[j]
1044+ function sub2ind {T<:Integer} (dims:: Tuple{Vararg{Integer}} , I:: AbstractVector{T} ...)
1045+ N = length (dims)
1046+ M = length (I[1 ])
1047+ indices = Array {T} (length (I[1 ]))
1048+ copy! (indices,I[1 ])
1049+
1050+ s = dims[1 ]
1051+ for j= 2 : length (I)
1052+ Ij = I[j]
1053+ for i= 1 : M
1054+ indices[i] += s* (Ij[i]- 1 )
1055+ end
1056+ s*= (j <= N ? dims[j] : 1 )
1057+ end
1058+ return indices
1059+ end
1060+
1061+ function ind2sub {N,T<:Integer} (dims:: NTuple{N,Integer} , ind:: AbstractVector{T} )
1062+ M = length (ind)
1063+ t = NTuple {N,Vector{T}} (ntuple (N,n-> Array {T} (M)))
1064+ copy! (t[1 ],ind)
1065+ for j = 1 : N- 1
1066+ d = dims[j]
1067+ tj = t[j]
1068+ tj2 = t[j+ 1 ]
1069+ for i = 1 : M
1070+ ind2 = div (tj[i]- 1 , d)
1071+ tj[i] -= d* ind2
1072+ tj2[i] = ind2+ 1
10841073 end
10851074 end
10861075 return t
10871076end
10881077
1089- function ind2sub! {T<:Integer} (sub:: Array{T} , dims:: Array{T } , ind:: T )
1078+ function ind2sub! {T<:Integer} (sub:: Array{T} , dims:: Tuple{Vararg{T} } , ind:: T )
10901079 ndims = length (dims)
1091- stride = dims[1 ]
1092- for i in 2 : (ndims - 1 )
1093- stride *= dims[i]
1094- end
1095- for i in (ndims - 1 ): - 1 : 1
1096- rest = rem1 (ind, stride)
1097- sub[i + 1 ] = div (ind - rest, stride) + 1
1098- ind = rest
1099- stride = div (stride, dims[i])
1080+ for i= 1 : ndims- 1
1081+ ind2 = div (ind- 1 ,dims[i])+ 1
1082+ sub[i] = ind - dims[i]* (ind2- 1 )
1083+ ind = ind2
11001084 end
1101- sub[1 ] = ind
1102- return
1085+ sub[ndims ] = ind
1086+ return sub
11031087end
11041088
11051089# Generalized repmat
@@ -1115,26 +1099,18 @@ function repeat{T}(A::Array{T};
11151099 throw (ArgumentError (" inner/outer repetitions must be set for all input dimensions" ))
11161100 end
11171101
1118- size_in = Array (Int, ndims_in)
1119- size_out = Array (Int, ndims_out)
1120- inner_size_out = Array (Int, ndims_out)
1102+ inner = vcat (inner, ones (Int,ndims_out- length_inner))
1103+ outer = vcat (outer, ones (Int,ndims_out- length_outer))
11211104
1122- for i in 1 : ndims_in
1123- size_in[i] = size (A, i)
1124- end
1125- for i in 1 : ndims_out
1126- t1 = ndims_in < i ? 1 : size_in[i]
1127- t2 = length_inner < i ? 1 : inner[i]
1128- t3 = length_outer < i ? 1 : outer[i]
1129- size_out[i] = t1 * t2 * t3
1130- inner_size_out[i] = t1 * t2
1131- end
1105+ size_in = size (A)
1106+ size_out = ntuple (i-> inner[i]* size (A,i)* outer[i],ndims_out):: Dims
1107+ inner_size_out = ntuple (i-> inner[i]* size (A,i),ndims_out):: Dims
11321108
11331109 indices_in = Array (Int, ndims_in)
11341110 indices_out = Array (Int, ndims_out)
11351111
11361112 length_out = prod (size_out)
1137- R = Array (T, size_out... )
1113+ R = Array (T, size_out)
11381114
11391115 for index_out in 1 : length_out
11401116 ind2sub! (indices_out, size_out, index_out)
@@ -1146,7 +1122,7 @@ function repeat{T}(A::Array{T};
11461122 indices_in[t] = fld1 (indices_in[t], inner[t])
11471123 end
11481124 end
1149- index_in = sub2ind (size_in, indices_in)
1125+ index_in = sub2ind (size_in, indices_in... )
11501126 R[index_out] = A[index_in]
11511127 end
11521128
0 commit comments