Skip to content

Commit 7eb374e

Browse files
committedJul 18, 2013
Fix #3755
Significantly simpler and shorter than what we had previously. Should be more maintainable.
1 parent c9a537a commit 7eb374e

File tree

2 files changed

+20
-26
lines changed

2 files changed

+20
-26
lines changed
 

‎base/subarray.jl

+18-26
Original file line numberDiff line numberDiff line change
@@ -205,53 +205,45 @@ function getindex{T,S<:Integer}(s::SubArray{T,1}, I::AbstractVector{S})
205205
end
206206

207207
function translate_indexes(s::SubArray, I::Union(Real,AbstractArray)...)
208-
I = indices(I)
209-
nds = ndims(s)
210208
n = length(I)
211-
if n > nds
212-
throw(BoundsError())
209+
newindexes = Any[s.indexes...]
210+
pdims = parentdims(s)
211+
havelinear = n < ndims(s)
212+
for i = 1:n-havelinear
213+
newindexes[pdims[i]] = s.indexes[pdims[i]][I[i]]
213214
end
214-
ndp = ndims(s.parent) - (nds-n)
215-
newindexes = Array(Any, ndp)
216-
sp = strides(s.parent)
217-
j = 1
218-
for i = 1:ndp
219-
t = s.indexes[i]
220-
if j <= nds && s.strides[j] == sp[i]
221-
#TODO: don't generate the dense vector indexes if they can be ranges
222-
if j==n && n < nds
223-
newindexes[i] = translate_linear_indexes(s, j, I[j])
224-
else
225-
newindexes[i] = isa(t, Int) ? t : t[I[j]]
226-
end
227-
j += 1
228-
else
229-
newindexes[i] = t
230-
end
215+
lastdim = pdims[n]
216+
if havelinear
217+
newindexes = newindexes[1:lastdim]
218+
newindexes[pdims[n]] = translate_linear_indexes(s, n, I[end], pdims)
231219
end
232220
newindexes
233221
end
234222

235223
# translate a linear index vector I for dim n to a linear index vector for
236224
# the parent array
237-
function translate_linear_indexes(s, n, I)
225+
function translate_linear_indexes(s, n, I, pdims)
238226
idx = Array(Int, length(I))
239227
ssztail = size(s)[n:]
240-
pdims = parentdims(s)
241228
psztail = size(s.parent)[pdims[n:]]
229+
taildimsoffset = 0
230+
for i = pdims[end]+1:ndims(s.parent)
231+
taildimsoffset += (s.indexes[i]-1)*stride(s.parent, i)
232+
end
242233
for j=1:length(I)
243234
su = ind2sub(ssztail,I[j])
244-
idx[j] = sub2ind(psztail, [ s.indexes[pdims[n+k-1]][su[k]] for k=1:length(su) ]...)
235+
idx[j] = sub2ind(psztail, [ s.indexes[pdims[n+k-1]][su[k]] for k=1:length(su) ]...) + taildimsoffset
245236
end
246237
idx
247238
end
248239

249240
function parentdims(s::SubArray)
250-
dimindex = Array(Int, ndims(s))
241+
nd = ndims(s)
242+
dimindex = Array(Int, nd)
251243
sp = strides(s.parent)
252244
j = 1
253245
for i = 1:ndims(s.parent)
254-
if sp[i] == s.strides[j]
246+
if j <= nd && sp[i] == s.strides[j]
255247
dimindex[j] = i
256248
j += 1
257249
end

‎test/arrayops.jl

+2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ sA[2:5:end] = -1
102102
sA = sub(A, 1:3, 1:5, 5)
103103
sA[1:3,1:5] = -2
104104
@test all(A[:,:,5] .== -2)
105+
sA[:] = -3
106+
@test all(A[:,:,5] .== -3)
105107

106108
# slice
107109
A = reshape(1:120, 3, 5, 8)

1 commit comments

Comments
 (1)

JeffBezanson commented on Jul 18, 2013

@JeffBezanson
Member

Much appreciated! Index gymnastics routinely make by brain freeze. The new code does look much nicer too.

Please sign in to comment.