@@ -7,12 +7,15 @@ immutable ReshapedArray{T,N,P<:AbstractArray,MI<:Tuple{Vararg{SignedMultiplicati
77end
88ReshapedArray {T,N} (parent:: AbstractArray{T} , dims:: NTuple{N,Int} , mi) = ReshapedArray {T,N,typeof(parent),typeof(mi)} (parent, dims, mi)
99
10+ # LinearFast ReshapedArray
11+ typealias ReshapedArrayLF{T,N,P<: AbstractArray } ReshapedArray{T,N,P,Tuple{}}
12+
1013# Fast iteration on ReshapedArrays: use the parent iterator
1114immutable ReshapedRange{I,M}
1215 iter:: I
1316 mi:: NTuple{M,SignedMultiplicativeInverse{Int}}
1417end
15- ReshapedRange (A:: ReshapedArray ) = reshapedrange (A . parent, A. mi)
18+ ReshapedRange (A:: ReshapedArray ) = reshapedrange (parent (A) , A. mi)
1619function reshapedrange {M} (P, mi:: NTuple{M} )
1720 iter = eachindex (P)
1821 ReshapedRange {typeof(iter),M} (iter, mi)
@@ -22,26 +25,35 @@ immutable ReshapedIndex{T}
2225 parentindex:: T
2326end
2427
25- eachindex (A:: ReshapedArray ) = ReshapedRange (A)
28+ # eachindex(A::ReshapedArray) = ReshapedRange(A) # TODO : uncomment this line
2629start (R:: ReshapedRange ) = start (R. iter)
27- done (R:: ReshapedRange , i) = done (R. iter, i)
28- function next (R:: ReshapedRange , i)
29- @_inline_meta
30+ @inline done (R:: ReshapedRange , i) = done (R. iter, i)
31+ @inline function next (R:: ReshapedRange , i)
3032 item, inext = next (R. iter, i)
3133 ReshapedIndex (item), inext
3234end
35+ length (R:: ReshapedRange ) = length (R. iter)
3336
3437function reshape (parent:: AbstractArray , dims:: Dims )
3538 prod (dims) == length (parent) || throw (DimensionMismatch (" parent has $(length (parent)) elements, which is incompatible with size $dims " ))
3639 _reshape ((parent, linearindexing (parent)), dims)
3740end
3841reshape (R:: ReshapedArray , dims:: Dims ) = reshape (R. parent, dims)
42+ reshape (a:: AbstractArray , len:: Int ) = reshape (a, (len,))
3943reshape (a:: AbstractArray , dims:: Int... ) = reshape (a, dims)
4044
45+ # When reshaping Vector->Vector, don't wrap with a ReshapedArray
46+ reshape {T} (v:: ReshapedArray{T,1} , dims:: Tuple{Int} ) = reshape (v. parent, dims[1 ])
47+ reshape (v:: AbstractVector , dims:: Tuple{Int} ) = reshape (v, dims[1 ])
48+ function reshape (v:: AbstractVector , len:: Int )
49+ len == length (v) || throw (DimensionMismatch (" parent has $(length (v)) elements, which is incompatible with length $len " ))
50+ v
51+ end
52+
4153function _reshape (p:: Tuple{AbstractArray,LinearSlow} , dims:: Dims )
4254 parent = p[1 ]
43- strds = strides ( parent)
44- mi = map (SignedMultiplicativeInverse, tail ( strds) )
55+ strds = front ( size_strides ( parent) )
56+ mi = map (SignedMultiplicativeInverse, strds)
4557 ReshapedArray (parent, dims, reverse (mi))
4658end
4759
@@ -50,24 +62,45 @@ function _reshape(p::Tuple{AbstractArray,LinearFast}, dims::Dims)
5062 ReshapedArray (parent, dims, ())
5163end
5264
65+ @inline size_strides (A:: AbstractArray ) = tail (size_strides ((1 ,), size (A)... ))
66+ size_strides (out:: Tuple ) = out
67+ @inline size_strides (out, s, sz... ) = size_strides ((out... , out[end ]* s), sz... )
68+
5369size (A:: ReshapedArray ) = A. dims
5470size (A:: ReshapedArray , d) = d <= ndims (A) ? A. dims[d] : 1
55- similar (A:: ReshapedArray , eltype:: Type , dims... ) = similar (A. parent, eltype, dims... )
56- linearindexing {T,N,P<:AbstractArray} (:: Type{ReshapedArray{T,N,P,Tuple{}}} ) = LinearFast ()
57-
58- ind2sub_rs (:: Tuple{} , i:: Int ) = i
59- ind2sub_rs (strds, i) = (@_inline_meta ; ind2sub_rs ((), strds, i- 1 ))
60- ind2sub_rs (out, :: Tuple{} , ind) = (@_inline_meta ; (ind+ 1 , out... ))
61- function ind2sub_rs (out, strds, ind)
62- @_inline_meta
71+ similar (A:: ReshapedArray , eltype:: Type ) = similar (parent (A), eltype, size (A))
72+ similar (A:: ReshapedArray , eltype:: Type , dims... ) = similar (parent (A), eltype, dims... )
73+ linearindexing {R<:ReshapedArrayLF} (:: Type{R} ) = LinearFast ()
74+ parent (A:: ReshapedArray ) = A. parent
75+ parentindexes (A:: ReshapedArray ) = map (s-> 1 : s, size (parent (A)))
76+ reinterpret {T} (:: Type{T} , A:: ReshapedArray , dims:: Dims ) = reinterpret (T, parent (A), dims)
77+
78+ @inline ind2sub_rs (:: Tuple{} , i:: Int ) = i
79+ @inline ind2sub_rs (strds, i) = ind2sub_rs ((), strds, i- 1 )
80+ @inline ind2sub_rs (out, :: Tuple{} , ind) = (ind+ 1 , out... )
81+ @inline function ind2sub_rs (out, strds, ind)
6382 d, r = divrem (ind, strds[1 ])
6483 ind2sub_rs ((d+ 1 , out... ), tail (strds), r)
6584end
6685
67- getindex (A:: ReshapedArray , index:: Int ) = A. parent[ind2sub_rs (A. mi, index)]
68- getindex (A:: ReshapedArray , indexes:: Int... ) = (@_inline_meta ; A. parent[ind2sub_rs (A. mi, sub2ind (size (A), indexes... ))... ])
69- getindex (A:: ReshapedArray , index:: ReshapedIndex ) = A. parent[index. parentindex]
86+ @inline getindex (A:: ReshapedArrayLF , index:: Int ) = (@boundscheck checkbounds (A, index); @inbounds ret = parent (A)[index]; ret)
87+ @inline getindex (A:: ReshapedArray , indexes:: Int... ) = (@boundscheck checkbounds (A, indexes... ); _unsafe_getindex (A, indexes... ))
88+ @inline getindex (A:: ReshapedArray , index:: ReshapedIndex ) = (@boundscheck checkbounds (parent (A), index. parentindex); @inbounds ret = parent (A)[index. parentindex]; ret)
89+
90+ @inline _unsafe_getindex (A:: ReshapedArray , indexes:: Int... ) = (@inbounds ret = parent (A)[ind2sub_rs (A. mi, sub2ind (size (A), indexes... ))... ]; ret)
91+ @inline _unsafe_getindex (A:: ReshapedArrayLF , indexes:: Int... ) = (@inbounds ret = parent (A)[sub2ind (size (A), indexes... )]; ret)
92+
93+ @inline setindex! (A:: ReshapedArrayLF , val, index:: Int ) = (@boundscheck checkbounds (A, index); @inbounds parent (A)[index] = val; val)
94+ @inline setindex! (A:: ReshapedArray , val, indexes:: Int... ) = (@boundscheck checkbounds (A, indexes... ); _unsafe_setindex! (A, val, indexes... ))
95+ @inline setindex! (A:: ReshapedArray , val, index:: ReshapedIndex ) = (@boundscheck checkbounds (parent (A), index. parentindex); @inbounds parent (A)[index. parentindex] = val; val)
96+
97+ @inline _unsafe_setindex! (A:: ReshapedArray , val, indexes:: Int... ) = (@inbounds parent (A)[ind2sub_rs (A. mi, sub2ind (size (A), indexes... ))... ] = val; val)
98+ @inline _unsafe_setindex! (A:: ReshapedArrayLF , val, indexes:: Int... ) = (@inbounds parent (A)[sub2ind (size (A), indexes... )] = val; val)
99+
100+ typealias ArrayT{N, T} Array{T,N}
101+ convert {T,S,N} (:: Type{Array{T,N}} , V:: ReshapedArray{S,N} ) = copy! (Array (T, size (V)), V)
102+ convert {T,N} (:: Type{ArrayT{N}} , V:: ReshapedArray{T,N} ) = copy! (Array (T, size (V)), V)
70103
71- setindex! (A :: ReshapedArray , val, index :: Int ) = ( @_inline_meta ; A . parent[ ind2sub_rs (A . mi, index) ... ] = val )
72- setindex! (A :: ReshapedArray , val, indexes :: Int... ) = ( @_inline_meta ; A . parent[ ind2sub_rs (A . mi, sub2ind ( size (A), indexes ... )) ... ] = val)
73- setindex! (A :: ReshapedArray , val, index :: ReshapedIndex ) = A . parent[index . parentindex] = val
104+ unsafe_convert {T} ( :: Type{Ptr{T}} , a :: ReshapedArray{T} ) = unsafe_convert (Ptr{T}, parent (a) )
105+ unsafe_convert{T,N,P <: ReshapedArray ,I <: Tuple{Vararg{Union{RangeIndex, NoSlice}}} }( :: Type{Ptr{T}} , V :: SubArray{T,N,P,I} ) =
106+ unsafe_convert (Ptr{T}, V . parent) + ( first_index (V) - 1 ) * sizeof (T)
0 commit comments