Skip to content

Commit 1041bb4

Browse files
committed
adding slicedim() function
adding intersect() on Ranges adding squeeze()
1 parent 00b75b7 commit 1041bb4

File tree

3 files changed

+74
-25
lines changed

3 files changed

+74
-25
lines changed

j/abstractarray.j

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,43 @@ function ref(A::AbstractArray, I::Indices...)
464464
end
465465
end
466466

467+
# index A[:,:,...,i,:,:,...] where "i" is in dimension "d"
468+
# TODO: more optimized special cases
469+
function slicedim(A::AbstractArray, d::Int, i)
470+
A[ntuple(ndims(A), n->(n==d ? i : (1:size(A,n))))...]
471+
end
472+
473+
function slicedim(A::AbstractArray, d::Int, i::Int)
474+
d_in = size(A)
475+
leading = d_in[1:(d-1)]
476+
d_out = append(leading, (1,), d_in[(d+1):end])
477+
478+
M = prod(leading)
479+
N = numel(A)
480+
stride = M * d_in[d]
481+
482+
B = similar(A, d_out)
483+
index_offset = 1 + (i-1)*M
484+
485+
l = 1
486+
487+
if M==1
488+
for j=0:stride:(N-stride)
489+
B[l] = A[j + index_offset]
490+
l += 1
491+
end
492+
else
493+
for j=0:stride:(N-stride)
494+
offs = j + index_offset
495+
for k=0:(M-1)
496+
B[l] = A[offs + k]
497+
l += 1
498+
end
499+
end
500+
end
501+
return B
502+
end
503+
467504
## Indexing: assign ##
468505

469506
# 1-d indexing is assumed defined on subtypes
@@ -1317,6 +1354,16 @@ function ind2sub(dims, ind::Int)
13171354
return tuple(ind, sub...)
13181355
end
13191356

1357+
function squeeze(A::AbstractArray)
1358+
d = ()
1359+
for i = size(A)
1360+
if i != 1
1361+
d = tuple(d..., i)
1362+
end
1363+
end
1364+
reshape(A, d)
1365+
end
1366+
13201367
## subarrays ##
13211368

13221369
type SubArray{T,N,A<:AbstractArray,I<:(RangeIndex...,)} <: AbstractArray{T,N}

j/darray.j

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -89,29 +89,14 @@ function localize(s::SubDArray)
8989
l = localize(d)
9090
if isa(sdi,Int)
9191
if lo <= sdi <= hi
92-
return l[ntuple(ndims(l), i->(i==d.distdim ? sdi-lo+1 :
93-
1:size(l,i)))...]
92+
return slicedim(l, d.distdim, sdi-lo+1)
9493
else
95-
return Array(eltype(l), ntuple(ndims(l),
96-
i->(i==d.distdim ? 0 :
97-
size(l,i))))
94+
return Array(eltype(l), ntuple(ndims(l), i->(i==d.distdim ? 0 :
95+
size(l,i))))
9896
end
9997
else
100-
sta = start(sdi)
101-
ste = step(sdi)
102-
sto = sdi[end]
103-
i0 = sta + ste*div((lo-sta), ste)
104-
i1 = sta + ste*div((hi-sta), ste)
105-
i0 = max(i0,sta)
106-
i1 = min(i1,sto)
107-
if i0 > sto || i1 < sta
108-
return Array(eltype(l), ntuple(ndims(l),
109-
i->(i==d.distdim ? 0 :
110-
size(l,i))))
111-
else
112-
return l[ntuple(ndims(l), i->(i==d.distdim ? i0:ste:i1 :
113-
1:size(l,i)))...]
114-
end
98+
r = intersect(lo:hi, sdi)
99+
return l[ntuple(ndims(l), i->(i==d.distdim ? r : 1:size(l,i)))...]
115100
end
116101
end
117102

j/range.j

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ similar(r::Range1, T::Type, dims::Dims) = Range1(convert(T, r.start), convert(T,
2424

2525
typealias Ranges Union(Range,Range1)
2626

27-
ref(r::Range, s::Range{Index}) = Range(r[s[1]],r.step*s.step,r[s[end]])
28-
ref(r::Range1, s::Range{Index}) = Range(r[s[1]],s.step,r[s[end]])
29-
ref(r::Range, s::Range1{Index}) = Range(r[s[1]],r.step,r[s[end]])
30-
ref(r::Range1, s::Range1{Index}) = Range1(r[s[1]],r[s[end]])
31-
3227
step(r::Range) = r.step
3328
step(r::Range1) = one(r.start)
3429

@@ -63,6 +58,11 @@ next{T}(r::Range{T}, st) = (r.start+st*r.step, st+1)
6358
colon(start::Real, stop::Real, step::Real) = Range(start, step, stop)
6459
colon(start::Real, stop::Real) = Range1(start, stop)
6560

61+
ref(r::Range, s::Range{Index}) = Range(r[s[1]],r.step*s.step,r[s[end]])
62+
ref(r::Range1, s::Range{Index}) = Range(r[s[1]],s.step,r[s[end]])
63+
ref(r::Range, s::Range1{Index}) = Range(r[s[1]],r.step,r[s[end]])
64+
ref(r::Range1, s::Range1{Index}) = Range1(r[s[1]],r[s[end]])
65+
6666
function ref(r::Ranges, i::Int)
6767
if i < 1; error(BoundsError); end
6868
x = r.start + (i-1)*step(r)
@@ -72,6 +72,23 @@ function ref(r::Ranges, i::Int)
7272
return x
7373
end
7474

75+
intersect(r::Range1, s::Range1) = max(r.start,s.start):min(r.stop,s.stop)
76+
77+
intersect(r::Range, s::Range1) = intersect(s, r)
78+
79+
function intersect(r::Range1, s::Range)
80+
sta = start(s)
81+
ste = step(s)
82+
sto = s[end]
83+
lo = r.start
84+
hi = r.stop
85+
i0 = max(lo, sta + ste*div((lo-sta)+ste-1, ste))
86+
i1 = min(hi, sta + ste*div((hi-sta), ste))
87+
i0 = max(i0, sta)
88+
i1 = min(i1, sto)
89+
i0:ste:i1
90+
end
91+
7592
## linear operations on 1-d ranges ##
7693

7794
-(r::Ranges) = Range(-r.start, -step(r), -r.stop)

0 commit comments

Comments
 (0)