Skip to content

Commit

Permalink
Add ReshapedArrays
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Mar 21, 2016
1 parent c18bc53 commit c575df4
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 49 deletions.
8 changes: 0 additions & 8 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,6 @@ similar( a::AbstractArray, T::Type, dims::Integer...) = similar(a, T, dims)
similar( a::AbstractArray, T::Type, dims::DimsInteger) = Array(T, dims...)
similar( a::AbstractArray, T::Type, dims::Dims) = Array(T, dims)

function reshape(a::AbstractArray, dims::Dims)
if prod(dims) != length(a)
throw(ArgumentError("dimensions must be consistent with array size (expected $(length(a)), got $(prod(dims)))"))
end
copy!(similar(a, dims), a)
end
reshape(a::AbstractArray, dims::Int...) = reshape(a, dims)

## from general iterable to any array

function copy!(dest::AbstractArray, src)
Expand Down
19 changes: 0 additions & 19 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,25 +96,6 @@ function reinterpret{T,S,N}(::Type{T}, a::Array{S}, dims::NTuple{N,Int})
ccall(:jl_reshape_array, Array{T,N}, (Any, Any, Any), Array{T,N}, a, dims)
end

# reshaping to same # of dimensions
function reshape{T,N}(a::Array{T,N}, dims::NTuple{N,Int})
if prod(dims) != length(a)
throw(DimensionMismatch("new dimensions $(dims) must be consistent with array size $(length(a))"))
end
if dims == size(a)
return a
end
ccall(:jl_reshape_array, Array{T,N}, (Any, Any, Any), Array{T,N}, a, dims)
end

# reshaping to different # of dimensions
function reshape{T,N}(a::Array{T}, dims::NTuple{N,Int})
if prod(dims) != length(a)
throw(DimensionMismatch("new dimensions $(dims) must be consistent with array size $(length(a))"))
end
ccall(:jl_reshape_array, Array{T,N}, (Any, Any, Any), Array{T,N}, a, dims)
end

## Constructors ##

similar(a::Array, T, dims::Dims) = Array(T, dims)
Expand Down
73 changes: 73 additions & 0 deletions base/reshapedarray.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using Base.MultiplicativeInverses: SignedMultiplicativeInverse

immutable ReshapedArray{T,N,P<:AbstractArray,MI<:Tuple{Vararg{SignedMultiplicativeInverse{Int}}}} <: AbstractArray{T,N}
parent::P
dims::NTuple{N,Int}
mi::MI
end
ReshapedArray{T,N}(parent::AbstractArray{T}, dims::NTuple{N,Int}, mi) = ReshapedArray{T,N,typeof(parent),typeof(mi)}(parent, dims, mi)

# Fast iteration on ReshapedArrays: use the parent iterator
immutable ReshapedRange{I,M}
iter::I
mi::NTuple{M,SignedMultiplicativeInverse{Int}}
end
ReshapedRange(A::ReshapedArray) = reshapedrange(A.parent, A.mi)
function reshapedrange{M}(P, mi::NTuple{M})
iter = eachindex(P)
ReshapedRange{typeof(iter),M}(iter, mi)
end

immutable ReshapedIndex{T}
parentindex::T
end

eachindex(A::ReshapedArray) = ReshapedRange(A)
start(R::ReshapedRange) = start(R.iter)
done(R::ReshapedRange, i) = done(R.iter, i)
function next(R::ReshapedRange, i)
@_inline_meta
item, inext = next(R.iter, i)
ReshapedIndex(item), inext
end

function reshape(parent::AbstractArray, dims::Dims)
prod(dims) == length(parent) || throw(DimensionMismatch("parent has $(length(parent)) elements, which is incompatible with size $dims"))
_reshape((parent, linearindexing(parent)), dims)
end
reshape(R::ReshapedArray, dims::Dims) = reshape(R.parent, dims)
reshape(a::AbstractArray, dims::Int...) = reshape(a, dims)

function _reshape(p::Tuple{AbstractArray,LinearSlow}, dims::Dims)
parent = p[1]
strds = strides(parent)
mi = map(SignedMultiplicativeInverse, tail(strds))
ReshapedArray(parent, dims, reverse(mi))
end

function _reshape(p::Tuple{AbstractArray,LinearFast}, dims::Dims)
parent = p[1]
ReshapedArray(parent, dims, ())
end

size(A::ReshapedArray) = A.dims
size(A::ReshapedArray, d) = d <= ndims(A) ? A.dims[d] : 1
similar(A::ReshapedArray, eltype::Type, dims...) = similar(A.parent, eltype, dims...)
linearindexing{T,N,P<:AbstractArray}(::Type{ReshapedArray{T,N,P,Tuple{}}}) = LinearFast()

ind2sub_rs(::Tuple{}, i::Int) = i
ind2sub_rs(strds, i) = (@_inline_meta; ind2sub_rs((), strds, i-1))
ind2sub_rs(out, ::Tuple{}, ind) = (@_inline_meta; (ind+1, out...))
function ind2sub_rs(out, strds, ind)
@_inline_meta
d, r = divrem(ind, strds[1])
ind2sub_rs((d+1, out...), tail(strds), r)
end

getindex(A::ReshapedArray, index::Int) = A.parent[ind2sub_rs(A.mi, index)]
getindex(A::ReshapedArray, indexes::Int...) = (@_inline_meta; A.parent[ind2sub_rs(A.mi, sub2ind(size(A), indexes...))...])
getindex(A::ReshapedArray, index::ReshapedIndex) = A.parent[index.parentindex]

setindex!(A::ReshapedArray, val, index::Int) = (@_inline_meta; A.parent[ind2sub_rs(A.mi, index)...] = val)
setindex!(A::ReshapedArray, val, indexes::Int...) = (@_inline_meta; A.parent[ind2sub_rs(A.mi, sub2ind(size(A), indexes...))...] = val)
setindex!(A::ReshapedArray, val, index::ReshapedIndex) = A.parent[index.parentindex] = val
16 changes: 0 additions & 16 deletions base/sparse/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,22 +172,6 @@ function reinterpret{T,Tv,Ti,N}(::Type{T}, a::SparseMatrixCSC{Tv,Ti}, dims::NTup
return SparseMatrixCSC(mS, nS, colptr, rowval, nzval)
end

function reshape{Tv,Ti}(a::SparseMatrixCSC{Tv,Ti}, dims::NTuple{2,Int})
if prod(dims) != length(a)
throw(DimensionMismatch("new dimensions $(dims) must be consistent with array size $(length(a))"))
end
mS,nS = dims
mA,nA = size(a)
numnz = nnz(a)
colptr = Array(Ti, nS+1)
rowval = similar(a.rowval)
nzval = copy(a.nzval)

sparse_compute_reshaped_colptr_and_rowval(colptr, rowval, mS, nS, a.colptr, a.rowval, mA, nA)

return SparseMatrixCSC(mS, nS, colptr, rowval, nzval)
end

## Constructors

copy(S::SparseMatrixCSC) =
Expand Down
3 changes: 1 addition & 2 deletions base/subarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

typealias NonSliceIndex Union{Colon, AbstractVector}
typealias ViewIndex Union{Real, NonSliceIndex}
abstract AbstractCartesianIndex{N} # This is a hacky forward declaration for CartesianIndex

# L is true if the view itself supports fast linear indexing
immutable SubArray{T,N,P,I,L} <: AbstractArray{T,N}
Expand Down Expand Up @@ -47,8 +48,6 @@ function getindex(N::NoSlice, r::Range{Int})
N
end

abstract AbstractCartesianIndex{N} # This is a hacky forward declaration for CartesianIndex

# This computes the linear indexing compatability for a given tuple of indices
viewindexing() = LinearFast()
# Leading scalar indexes simply increase the stride
Expand Down
9 changes: 5 additions & 4 deletions base/sysimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,17 @@ importall .SimdLoop
include("reduce.jl")

## core structures
include("reshapedarray.jl")
include("bitarray.jl")
include("intset.jl")
include("dict.jl")
include("set.jl")
include("iterator.jl")

# StridedArrays
typealias StridedArray{T,N,A<:DenseArray,I<:Tuple{Vararg{Union{RangeIndex, NoSlice, AbstractCartesianIndex}}}} Union{DenseArray{T,N}, SubArray{T,N,A,I}}
typealias StridedVector{T,A<:DenseArray,I<:Tuple{Vararg{Union{RangeIndex, NoSlice, AbstractCartesianIndex}}}} Union{DenseArray{T,1}, SubArray{T,1,A,I}}
typealias StridedMatrix{T,A<:DenseArray,I<:Tuple{Vararg{Union{RangeIndex, NoSlice, AbstractCartesianIndex}}}} Union{DenseArray{T,2}, SubArray{T,2,A,I}}
# Definition of StridedArray
typealias StridedArray{T,N,A<:DenseArray,I<:Tuple{Vararg{Union{RangeIndex, NoSlice, AbstractCartesianIndex}}},MI} Union{DenseArray{T,N}, SubArray{T,N,A,I}, ReshapedArray{T,N,A,MI}}
typealias StridedVector{T,A<:DenseArray,I<:Tuple{Vararg{Union{RangeIndex, NoSlice, AbstractCartesianIndex}}},MI} Union{DenseArray{T,1}, SubArray{T,1,A,I}, ReshapedArray{T,1,A,MI}}
typealias StridedMatrix{T,A<:DenseArray,I<:Tuple{Vararg{Union{RangeIndex, NoSlice, AbstractCartesianIndex}}},MI} Union{DenseArray{T,2}, SubArray{T,2,A,I}, ReshapedArray{T,2,A,MI}}
typealias StridedVecOrMat{T} Union{StridedVector{T}, StridedMatrix{T}}

# For OS specific stuff
Expand Down

0 comments on commit c575df4

Please sign in to comment.