@@ -1009,97 +1009,81 @@ function repmat(a::AbstractVector, m::Int)
1009
1009
return b
1010
1010
end
1011
1011
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
1031
1023
end
1032
- return index
1024
+ Expr ( :block , meta,:( $ ex + 1 ))
1033
1025
end
1034
1026
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))
1042
1035
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]. .. ))
1044
1038
end
1045
1039
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...)
1048
1043
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
1084
1073
end
1085
1074
end
1086
1075
return t
1087
1076
end
1088
1077
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 )
1090
1079
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
1100
1084
end
1101
- sub[1 ] = ind
1102
- return
1085
+ sub[ndims ] = ind
1086
+ return sub
1103
1087
end
1104
1088
1105
1089
# Generalized repmat
@@ -1115,26 +1099,18 @@ function repeat{T}(A::Array{T};
1115
1099
throw (ArgumentError (" inner/outer repetitions must be set for all input dimensions" ))
1116
1100
end
1117
1101
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))
1121
1104
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
1132
1108
1133
1109
indices_in = Array (Int, ndims_in)
1134
1110
indices_out = Array (Int, ndims_out)
1135
1111
1136
1112
length_out = prod (size_out)
1137
- R = Array (T, size_out... )
1113
+ R = Array (T, size_out)
1138
1114
1139
1115
for index_out in 1 : length_out
1140
1116
ind2sub! (indices_out, size_out, index_out)
@@ -1146,7 +1122,7 @@ function repeat{T}(A::Array{T};
1146
1122
indices_in[t] = fld1 (indices_in[t], inner[t])
1147
1123
end
1148
1124
end
1149
- index_in = sub2ind (size_in, indices_in)
1125
+ index_in = sub2ind (size_in, indices_in... )
1150
1126
R[index_out] = A[index_in]
1151
1127
end
1152
1128
0 commit comments