diff --git a/NEWS.md b/NEWS.md index 9999d66b6ad44..da8bf3f4f040b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,9 +12,9 @@ New language features * Default "inner" constructors now accept any arguments. Constructors that look like `MyType(a, b) = new(a, b)` can and should be removed ([#4026]). - * Expanded array type hierarchy, including ``StoredArray`` for all - container-like arrays, and ``DenseArray`` for in-memory arrays with - standard strided storage ([#987], [#2345]). + * Expanded array type hierarchy to include an abstract ``DenseArray`` for + in-memory arrays with standard strided storage ([#987], [#2345], + [#6212]). * When reloading code, types whose definitions have not changed can be ignored in some cases. diff --git a/base/abstractarray.jl b/base/abstractarray.jl index d011de923d4e5..24343feec8bef 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -143,7 +143,7 @@ function squeeze(A::AbstractArray, dims) reshape(A, d) end -function copy!(dest::StoredArray, src) +function copy!(dest::AbstractArray, src) i = 1 for x in src dest[i] = x @@ -154,7 +154,7 @@ end # copy with minimal requirements on src # if src is not an AbstractArray, moving to the offset might be O(n) -function copy!(dest::StoredArray, doffs::Integer, src, soffs::Integer=1) +function copy!(dest::AbstractArray, doffs::Integer, src, soffs::Integer=1) st = start(src) for j = 1:(soffs-1) _, st = next(src, st) @@ -171,13 +171,13 @@ end # NOTE: this is to avoid ambiguity with the deprecation of # copy!(dest::AbstractArray, src, doffs::Integer) # Remove this when that deprecation is removed. -function copy!(dest::StoredArray, doffs::Integer, src::Integer) +function copy!(dest::AbstractArray, doffs::Integer, src::Integer) dest[doffs] = src return dest end # this method must be separate from the above since src might not have a length -function copy!(dest::StoredArray, doffs::Integer, src, soffs::Integer, n::Integer) +function copy!(dest::AbstractArray, doffs::Integer, src, soffs::Integer, n::Integer) n == 0 && return dest st = start(src) for j = 1:(soffs-1) @@ -192,7 +192,7 @@ function copy!(dest::StoredArray, doffs::Integer, src, soffs::Integer, n::Intege end # if src is an AbstractArray and a source offset is passed, use indexing -function copy!(dest::StoredArray, doffs::Integer, src::AbstractArray, soffs::Integer, n::Integer=length(src)) +function copy!(dest::AbstractArray, doffs::Integer, src::AbstractArray, soffs::Integer, n::Integer=length(src)) for i = 0:(n-1) dest[doffs+i] = src[soffs+i] end @@ -202,6 +202,42 @@ end copy(a::AbstractArray) = copy!(similar(a), a) copy(a::AbstractArray{None}) = a # cannot be assigned into so is immutable +function copy!{R,S}(B::AbstractMatrix{R}, ir_dest::Ranges{Int}, jr_dest::Ranges{Int}, A::AbstractMatrix{S}, ir_src::Ranges{Int}, jr_src::Ranges{Int}) + if length(ir_dest) != length(ir_src) || length(jr_dest) != length(jr_src) + error("source and destination must have same size") + end + checkbounds(B, ir_dest, jr_dest) + checkbounds(A, ir_src, jr_src) + jdest = first(jr_dest) + for jsrc in jr_src + idest = first(ir_dest) + for isrc in ir_src + B[idest,jdest] = A[isrc,jsrc] + idest += step(ir_dest) + end + jdest += step(jr_dest) + end + return B +end + +function copy_transpose!{R,S}(B::AbstractMatrix{R}, ir_dest::Ranges{Int}, jr_dest::Ranges{Int}, A::AbstractVecOrMat{S}, ir_src::Ranges{Int}, jr_src::Ranges{Int}) + if length(ir_dest) != length(jr_src) || length(jr_dest) != length(ir_src) + error("source and destination must have same size") + end + checkbounds(B, ir_dest, jr_dest) + checkbounds(A, ir_src, jr_src) + idest = first(ir_dest) + for jsrc in jr_src + jdest = first(jr_dest) + for isrc in ir_src + B[idest,jdest] = A[isrc,jsrc] + jdest += step(jr_dest) + end + idest += step(ir_dest) + end + return B +end + zero{T}(x::AbstractArray{T}) = fill!(similar(x), zero(T)) ## iteration support for arrays as ranges ## @@ -228,9 +264,9 @@ for (f,t) in ((:char, Char), (:uint128,Uint128)) @eval begin ($f)(x::AbstractArray{$t}) = x - ($f)(x::StoredArray{$t}) = x + ($f)(x::AbstractArray{$t}) = x - function ($f)(x::StoredArray) + function ($f)(x::AbstractArray) y = similar(x,$t) i = 1 for e in x @@ -246,9 +282,9 @@ for (f,t) in ((:integer, Integer), (:unsigned, Unsigned)) @eval begin ($f){T<:$t}(x::AbstractArray{T}) = x - ($f){T<:$t}(x::StoredArray{T}) = x + ($f){T<:$t}(x::AbstractArray{T}) = x - function ($f)(x::StoredArray) + function ($f)(x::AbstractArray) y = similar(x,typeof(($f)(one(eltype(x))))) i = 1 for e in x @@ -1208,7 +1244,7 @@ end ## 1 argument -function map_to!(f::Callable, first, dest::StoredArray, A::AbstractArray) +function map_to!(f::Callable, first, dest::AbstractArray, A::AbstractArray) dest[1] = first for i=2:length(A) dest[i] = f(A[i]) @@ -1224,7 +1260,7 @@ function map(f::Callable, A::AbstractArray) end ## 2 argument -function map_to!(f::Callable, first, dest::StoredArray, A::AbstractArray, B::AbstractArray) +function map_to!(f::Callable, first, dest::AbstractArray, A::AbstractArray, B::AbstractArray) dest[1] = first for i=2:length(A) dest[i] = f(A[i], B[i]) @@ -1243,7 +1279,7 @@ function map(f::Callable, A::AbstractArray, B::AbstractArray) end ## N argument -function map_to!(f::Callable, first, dest::StoredArray, As::AbstractArray...) +function map_to!(f::Callable, first, dest::AbstractArray, As::AbstractArray...) n = length(As[1]) i = 1 ith = a->a[i] diff --git a/base/array.jl b/base/array.jl index 6a5c0f0763f96..988f5697cc9d0 100644 --- a/base/array.jl +++ b/base/array.jl @@ -8,7 +8,6 @@ typealias DenseVector{T} DenseArray{T,1} typealias DenseMatrix{T} DenseArray{T,2} typealias DenseVecOrMat{T} Union(DenseVector{T}, DenseMatrix{T}) -typealias StoredVector{T} StoredArray{T,1} typealias StridedArray{T,N,A<:DenseArray} Union(DenseArray{T,N}, SubArray{T,N,A}) typealias StridedVector{T,A<:DenseArray} Union(DenseArray{T,1}, SubArray{T,1,A}) typealias StridedMatrix{T,A<:DenseArray} Union(DenseArray{T,2}, SubArray{T,2,A}) @@ -58,53 +57,6 @@ end copy!{T}(dest::Array{T}, src::Array{T}) = copy!(dest, 1, src, 1, length(src)) -function copy!{R,S}(B::Matrix{R}, ir_dest::Range1{Int}, jr_dest::Range1{Int}, A::StridedMatrix{S}, ir_src::Range1{Int}, jr_src::Range1{Int}) - if length(ir_dest) != length(ir_src) || length(jr_dest) != length(jr_src) - error("source and destination must have same size") - end - checkbounds(B, ir_dest, jr_dest) - checkbounds(A, ir_src, jr_src) - jdest = first(jr_dest) - Askip = size(A, 1) - Bskip = size(B, 1) - if stride(A, 1) == 1 && R == S - for jsrc in jr_src - copy!(B, (jdest-1)*Bskip+first(ir_dest), A, (jsrc-1)*Askip+first(ir_src), length(ir_src)) - jdest += 1 - end - else - for jsrc in jr_src - aoffset = (jsrc-1)*Askip - boffset = (jdest-1)*Bskip - idest = first(ir_dest) - for isrc in ir_src - B[boffset+idest] = A[aoffset+isrc] - idest += 1 - end - jdest += 1 - end - end -end - -function copy_transpose!{R,S}(B::Matrix{R}, ir_dest::Range1{Int}, jr_dest::Range1{Int}, A::StridedVecOrMat{S}, ir_src::Range1{Int}, jr_src::Range1{Int}) - if length(ir_dest) != length(jr_src) || length(jr_dest) != length(ir_src) - error("source and destination must have same size") - end - checkbounds(B, ir_dest, jr_dest) - checkbounds(A, ir_src, jr_src) - idest = first(ir_dest) - Askip = size(A, 1) - for jsrc in jr_src - offset = (jsrc-1)*Askip - jdest = first(jr_dest) - for isrc in ir_src - B[idest,jdest] = A[offset+isrc] - jdest += 1 - end - idest += 1 - end -end - function reinterpret{T,S}(::Type{T}, a::Array{S,1}) nel = int(div(length(a)*sizeof(S),sizeof(T))) return reinterpret(T, a, (nel,)) @@ -689,7 +641,7 @@ end ## Unary operators ## -function conj!{T<:Number}(A::StoredArray{T}) +function conj!{T<:Number}(A::AbstractArray{T}) for i=1:length(A) A[i] = conj(A[i]) end @@ -994,7 +946,7 @@ end rotr90(A::AbstractMatrix, k::Integer) = rotl90(A,-k) rot180(A::AbstractMatrix, k::Integer) = mod(k, 2) == 1 ? rot180(A) : copy(A) -# note: probably should be StridedVector or StoredVector +# note: probably should be StridedVector or AbstractVector function reverse(A::AbstractVector, s=1, n=length(A)) B = similar(A) for i = 1:s-1 @@ -1392,7 +1344,7 @@ _cumsum_type(v) = typeof(v[1]+v[1]) for (f, fp, op) = ((:cumsum, :cumsum_pairwise, :+), (:cumprod, :cumprod_pairwise, :*) ) # in-place cumsum of c = s+v(i1:n), using pairwise summation as for sum - @eval function ($fp)(v::StoredVector, c::StoredVector, s, i1, n) + @eval function ($fp)(v::AbstractVector, c::AbstractVector, s, i1, n) if n < 128 @inbounds c[i1] = ($op)(s, v[i1]) for i = i1+1:i1+n-1 @@ -1405,7 +1357,7 @@ for (f, fp, op) = ((:cumsum, :cumsum_pairwise, :+), end end - @eval function ($f)(v::StoredVector) + @eval function ($f)(v::AbstractVector) n = length(v) c = $(op===:+ ? (:(similar(v,_cumsum_type(v)))) : (:(similar(v)))) @@ -1445,7 +1397,7 @@ for (f, fp, op) = ((:cumsum, :cumsum_pairwise, :+), end for (f, op) = ((:cummin, :min), (:cummax, :max)) - @eval function ($f)(v::StoredVector) + @eval function ($f)(v::AbstractVector) n = length(v) cur_val = v[1] res = similar(v, n) diff --git a/base/boot.jl b/base/boot.jl index 1310a735e1b36..15b11be373d54 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -46,8 +46,7 @@ #end #abstract AbstractArray{T,N} -#abstract StoredArray{T,N} <: AbstractArray{T,N} -#abstract DenseArray{T,N} <: StoredArray{T,N} +#abstract DenseArray{T,N} <: AbstractArray{T,N} #type Array{T,N} <: DenseArray{T,N} #end @@ -118,7 +117,7 @@ export # key types Any, DataType, Vararg, ANY, NTuple, None, Top, Tuple, Type, TypeConstructor, TypeName, TypeVar, Union, UnionType, Void, - AbstractArray, StoredArray, DenseArray, + AbstractArray, DenseArray, # special objects Box, Function, IntrinsicFunction, LambdaStaticData, Method, MethodTable, Module, Nothing, Symbol, Task, Array, diff --git a/base/darray.jl b/base/darray.jl index e42b0f2301adf..f4a77fb524160 100644 --- a/base/darray.jl +++ b/base/darray.jl @@ -1,4 +1,4 @@ -type DArray{T,N,A} <: StoredArray{T,N} +type DArray{T,N,A} <: AbstractArray{T,N} dims::NTuple{N,Int} chunks::Array{RemoteRef,N} diff --git a/base/linalg/diagonal.jl b/base/linalg/diagonal.jl index 8ccd36a871605..7d7cc275a4675 100644 --- a/base/linalg/diagonal.jl +++ b/base/linalg/diagonal.jl @@ -13,6 +13,13 @@ size(D::Diagonal,d::Integer) = d<1 ? error("dimension out of range") : (d<=2 ? l full(D::Diagonal) = diagm(D.diag) getindex(D::Diagonal, i::Integer, j::Integer) = i == j ? D.diag[i] : zero(eltype(D.diag)) +function getindex(D::Diagonal, i::Integer) + n = length(D.diag) + id = div(i-1, n) + id + id * n == i-1 && return D.diag[id+1] + zero(eltype(D.diag)) +end + ishermitian(D::Diagonal) = true issym(D::Diagonal) = true isposdef(D::Diagonal) = all(D.diag .> 0) diff --git a/base/linalg/matmul.jl b/base/linalg/matmul.jl index 1f6941131b1a9..0bb46ff09002a 100644 --- a/base/linalg/matmul.jl +++ b/base/linalg/matmul.jl @@ -239,9 +239,9 @@ end # blas.jl defines matmul for floats; other integer and mixed precision # cases are handled here -lapack_size(t::Char, M::StridedVecOrMat) = (size(M, t=='N' ? 1:2), size(M, t=='N' ? 2:1)) +lapack_size(t::Char, M::AbstractVecOrMat) = (size(M, t=='N' ? 1:2), size(M, t=='N' ? 2:1)) -function copy!{R,S}(B::Matrix{R}, ir_dest::Range1{Int}, jr_dest::Range1{Int}, tM::Char, M::StridedMatrix{S}, ir_src::Range1{Int}, jr_src::Range1{Int}) +function copy!{R,S}(B::AbstractMatrix{R}, ir_dest::Range1{Int}, jr_dest::Range1{Int}, tM::Char, M::AbstractMatrix{S}, ir_src::Range1{Int}, jr_src::Range1{Int}) if tM == 'N' copy!(B, ir_dest, jr_dest, M, ir_src, jr_src) else @@ -250,7 +250,7 @@ function copy!{R,S}(B::Matrix{R}, ir_dest::Range1{Int}, jr_dest::Range1{Int}, tM end end -function copy_transpose!{R,S}(B::Matrix{R}, ir_dest::Range1{Int}, jr_dest::Range1{Int}, tM::Char, M::StridedVecOrMat{S}, ir_src::Range1{Int}, jr_src::Range1{Int}) +function copy_transpose!{R,S}(B::AbstractMatrix{R}, ir_dest::Range1{Int}, jr_dest::Range1{Int}, tM::Char, M::AbstractVecOrMat{S}, ir_src::Range1{Int}, jr_src::Range1{Int}) if tM == 'N' Base.copy_transpose!(B, ir_dest, jr_dest, M, ir_src, jr_src) else @@ -264,17 +264,17 @@ end # NOTE: the generic version is also called as fallback for # strides != 1 cases in libalg_blas.jl -(*){T,S}(A::StridedMatrix{T}, B::StridedVector{S}) = generic_matvecmul('N', A, B) +(*){T,S}(A::AbstractMatrix{T}, B::AbstractVector{S}) = generic_matvecmul('N', A, B) arithtype(T) = T arithtype(::Type{Bool}) = Int -function generic_matvecmul{T,S}(tA::Char, A::StridedMatrix{T}, B::StridedVector{S}) +function generic_matvecmul{T,S}(tA::Char, A::AbstractMatrix{T}, B::AbstractVector{S}) C = similar(B, promote_type(arithtype(T),arithtype(S)), size(A, tA=='N' ? 1 : 2)) generic_matvecmul(C, tA, A, B) end -function generic_matvecmul{T,S,R}(C::StridedVector{R}, tA, A::StridedMatrix{T}, B::StridedVector{S}) +function generic_matvecmul{T,S,R}(C::AbstractVector{R}, tA, A::AbstractMatrix{T}, B::AbstractVector{S}) mB = length(B) mA, nA = lapack_size(tA, A) mB==nA || throw(DimensionMismatch("*")) @@ -318,9 +318,9 @@ end # NOTE: the generic version is also called as fallback for strides != 1 cases # in libalg_blas.jl -(*){T,S}(A::StridedVecOrMat{T}, B::StridedMatrix{S}) = generic_matmatmul('N', 'N', A, B) +(*){T,S}(A::AbstractVecOrMat{T}, B::AbstractMatrix{S}) = generic_matmatmul('N', 'N', A, B) -function generic_matmatmul{T,S}(tA, tB, A::StridedVecOrMat{T}, B::StridedMatrix{S}) +function generic_matmatmul{T,S}(tA, tB, A::AbstractVecOrMat{T}, B::AbstractMatrix{S}) mA, nA = lapack_size(tA, A) mB, nB = lapack_size(tB, B) C = similar(B, promote_type(arithtype(T),arithtype(S)), mA, nB) @@ -332,7 +332,7 @@ const Abuf = Array(Uint8, tilebufsize) const Bbuf = Array(Uint8, tilebufsize) const Cbuf = Array(Uint8, tilebufsize) -function generic_matmatmul{T,S,R}(C::StridedVecOrMat{R}, tA, tB, A::StridedVecOrMat{T}, B::StridedMatrix{S}) +function generic_matmatmul{T,S,R}(C::AbstractVecOrMat{R}, tA, tB, A::AbstractVecOrMat{T}, B::AbstractMatrix{S}) mA, nA = lapack_size(tA, A) mB, nB = lapack_size(tB, B) mB==nA || throw(DimensionMismatch("*")) @@ -482,11 +482,11 @@ end # multiply 2x2 matrices -function matmul2x2{T,S}(tA, tB, A::StridedMatrix{T}, B::StridedMatrix{S}) +function matmul2x2{T,S}(tA, tB, A::AbstractMatrix{T}, B::AbstractMatrix{S}) matmul2x2(similar(B, promote_type(T,S), 2, 2), tA, tB, A, B) end -function matmul2x2{T,S,R}(C::StridedMatrix{R}, tA, tB, A::StridedMatrix{T}, B::StridedMatrix{S}) +function matmul2x2{T,S,R}(C::AbstractMatrix{R}, tA, tB, A::AbstractMatrix{T}, B::AbstractMatrix{S}) if tA == 'T' A11 = A[1,1]; A12 = A[2,1]; A21 = A[1,2]; A22 = A[2,2] elseif tA == 'C' @@ -509,11 +509,11 @@ function matmul2x2{T,S,R}(C::StridedMatrix{R}, tA, tB, A::StridedMatrix{T}, B::S end # Multiply 3x3 matrices -function matmul3x3{T,S}(tA, tB, A::StridedMatrix{T}, B::StridedMatrix{S}) +function matmul3x3{T,S}(tA, tB, A::AbstractMatrix{T}, B::AbstractMatrix{S}) matmul3x3(similar(B, promote_type(T,S), 3, 3), tA, tB, A, B) end -function matmul3x3{T,S,R}(C::StridedMatrix{R}, tA, tB, A::StridedMatrix{T}, B::StridedMatrix{S}) +function matmul3x3{T,S,R}(C::AbstractMatrix{R}, tA, tB, A::AbstractMatrix{T}, B::AbstractMatrix{S}) if tA == 'T' A11 = A[1,1]; A12 = A[2,1]; A13 = A[3,1]; A21 = A[1,2]; A22 = A[2,2]; A23 = A[3,2]; diff --git a/base/linalg/uniformscaling.jl b/base/linalg/uniformscaling.jl index ca08d2c3398ed..c13b5934b6e6e 100644 --- a/base/linalg/uniformscaling.jl +++ b/base/linalg/uniformscaling.jl @@ -1,12 +1,14 @@ import Base: +, -, *, /, copy, ctranspose, getindex, showarray, transpose import Base.LinAlg: SingularException -immutable UniformScaling{T<:Number} <: AbstractMatrix{T} +immutable UniformScaling{T<:Number} λ::T end const I = UniformScaling(1) -getindex(J::UniformScaling, i::Integer, j::Integer) = ifelse(i==j, J.λ, zero(J.λ)) +eltype{T}(J::UniformScaling{T}) = T +ndims(J::UniformScaling) = 2 +getindex(J::UniformScaling, i::Integer,j::Integer) = ifelse(i==j,J.λ,zero(J.λ)) showarray(io::IO, J::UniformScaling; kw...) = print(io, "$(typeof(J))\n$(J.λ)*I") copy(J::UniformScaling) = UniformScaling(J.λ) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index f7ffcf7a18b3e..95a24cfca25fe 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -139,14 +139,14 @@ eval(ngenerate(:N, nothing, :(setindex!{T}(s::SubArray{T,N}, v, ind::Integer)), ### from abstractarray.jl -@ngenerate N typeof(A) function fill!{T,N}(A::StoredArray{T,N}, x) +@ngenerate N typeof(A) function fill!{T,N}(A::AbstractArray{T,N}, x) @nloops N i A begin @inbounds (@nref N A i) = x end A end -@ngenerate N typeof(dest) function copy!{T,N}(dest::StoredArray{T,N}, src::StoredArray{T,N}) +@ngenerate N typeof(dest) function copy!{T,N}(dest::AbstractArray{T,N}, src::AbstractArray{T,N}) if @nall N d->(size(dest,d) == size(src,d)) @nloops N i dest begin @inbounds (@nref N dest i) = (@nref N src i) diff --git a/base/statistics.jl b/base/statistics.jl index 379e5f4ac2e34..7f693248e5772 100644 --- a/base/statistics.jl +++ b/base/statistics.jl @@ -434,7 +434,7 @@ function sturges(n) # Sturges' formula iceil(log2(n))+1 end -function hist!{HT}(h::StoredArray{HT}, v::AbstractVector, edg::AbstractVector; init::Bool=true) +function hist!{HT}(h::AbstractArray{HT}, v::AbstractVector, edg::AbstractVector; init::Bool=true) n = length(edg) - 1 length(h) == n || error("length(h) must equal length(edg) - 1.") if init @@ -453,7 +453,7 @@ hist(v::AbstractVector, edg::AbstractVector) = hist!(Array(Int, length(edg)-1), hist(v::AbstractVector, n::Integer) = hist(v,histrange(v,n)) hist(v::AbstractVector) = hist(v,sturges(length(v))) -function hist!{HT}(H::StoredArray{HT,2}, A::AbstractMatrix, edg::AbstractVector; init::Bool=true) +function hist!{HT}(H::AbstractArray{HT,2}, A::AbstractMatrix, edg::AbstractVector; init::Bool=true) m, n = size(A) size(H) == (length(edg)-1, n) || error("Incorrect size of H.") if init @@ -471,7 +471,7 @@ hist(A::AbstractMatrix) = hist(A,sturges(size(A,1))) ## hist2d -function hist2d!{HT}(H::StoredArray{HT,2}, v::AbstractMatrix, +function hist2d!{HT}(H::AbstractArray{HT,2}, v::AbstractMatrix, edg1::AbstractVector, edg2::AbstractVector; init::Bool=true) size(v,2) == 2 || error("hist2d requires an Nx2 matrix.") n = length(edg1) - 1 diff --git a/base/subarray.jl b/base/subarray.jl index 8aaeeb96b36cf..8e05b30907189 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -2,7 +2,7 @@ typealias RangeIndex Union(Int, Range{Int}, Range1{Int}) -type SubArray{T,N,A<:StoredArray,I<:(RangeIndex...,)} <: StoredArray{T,N} +type SubArray{T,N,A<:AbstractArray,I<:(RangeIndex...,)} <: AbstractArray{T,N} parent::A indexes::I dims::NTuple{N,Int} diff --git a/base/test.jl b/base/test.jl index 205930d583386..7fa18fbc58ae8 100644 --- a/base/test.jl +++ b/base/test.jl @@ -61,7 +61,7 @@ macro test_fails(ex) :(@test_throws $ex) end -approx_full(x::StoredArray) = x +approx_full(x::AbstractArray) = x approx_full(x::Number) = x approx_full(x) = full(x) diff --git a/contrib/julia-mode.el b/contrib/julia-mode.el index f8e6e2adfc4f8..63419282fd555 100644 --- a/contrib/julia-mode.el +++ b/contrib/julia-mode.el @@ -77,7 +77,7 @@ ].* \\(in\\)\\(\\s-\\|$\\)+") (defconst julia-font-lock-keywords - (list '("\\<\\(\\|Uint\\(8\\|16\\|32\\|64\\|128\\)\\|Int\\(8\\|16\\|32\\|64\\|128\\)\\|BigInt\\|Integer\\|BigFloat\\|FloatingPoint\\|Float16\\|Float32\\|Float64\\|Complex128\\|Complex64\\|ComplexPair\\|Bool\\|Char\\|DataType\\|Number\\|Real\\|Int\\|Uint\\|Array\\|DArray\\|AbstractArray\\|AbstractVector\\|AbstractMatrix\\|AbstractSparseMatrix\\|SubArray\\|StridedArray\\|StridedVector\\|StridedMatrix\\|VecOrMat\\|StridedVecOrMat\\|StoredArray\\|DenseArray\\|Range\\|Range1\\|SparseMatrixCSC\\|Tuple\\|NTuple\\|Symbol\\|Function\\|Vector\\|Matrix\\|Union\\|Type\\|Any\\|Complex\\|None\\|String\\|Ptr\\|Void\\|Exception\\|Task\\|Signed\\|Unsigned\\|Associative\\|Dict\\|IO\\|IOStream\\|Ranges\\|Rational\\|Regex\\|RegexMatch\\|Set\\|IntSet\\|ASCIIString\\|UTF8String\\|ByteString\\|Expr\\|WeakRef\\|Nothing\\|ObjectIdDict\\|SubString\\)\\>" . + (list '("\\<\\(\\|Uint\\(8\\|16\\|32\\|64\\|128\\)\\|Int\\(8\\|16\\|32\\|64\\|128\\)\\|BigInt\\|Integer\\|BigFloat\\|FloatingPoint\\|Float16\\|Float32\\|Float64\\|Complex128\\|Complex64\\|ComplexPair\\|Bool\\|Char\\|DataType\\|Number\\|Real\\|Int\\|Uint\\|Array\\|DArray\\|AbstractArray\\|AbstractVector\\|AbstractMatrix\\|AbstractSparseMatrix\\|SubArray\\|StridedArray\\|StridedVector\\|StridedMatrix\\|VecOrMat\\|StridedVecOrMat\\|DenseArray\\|Range\\|Range1\\|SparseMatrixCSC\\|Tuple\\|NTuple\\|Symbol\\|Function\\|Vector\\|Matrix\\|Union\\|Type\\|Any\\|Complex\\|None\\|String\\|Ptr\\|Void\\|Exception\\|Task\\|Signed\\|Unsigned\\|Associative\\|Dict\\|IO\\|IOStream\\|Ranges\\|Rational\\|Regex\\|RegexMatch\\|Set\\|IntSet\\|ASCIIString\\|UTF8String\\|ByteString\\|Expr\\|WeakRef\\|Nothing\\|ObjectIdDict\\|SubString\\)\\>" . font-lock-type-face) (cons (concat "\\<\\(" diff --git a/doc/manual/arrays.rst b/doc/manual/arrays.rst index 111454d90e5a7..ee3bc98dc7e06 100644 --- a/doc/manual/arrays.rst +++ b/doc/manual/arrays.rst @@ -391,8 +391,8 @@ Implementation -------------- The base array type in Julia is the abstract type -``AbstractArray{T,n}``. It is parametrized by the number of dimensions -``n`` and the element type ``T``. ``AbstractVector`` and +``AbstractArray{T,N}``. It is parametrized by the number of dimensions +``N`` and the element type ``T``. ``AbstractVector`` and ``AbstractMatrix`` are aliases for the 1-d and 2-d cases. Operations on ``AbstractArray`` objects are defined using higher level operators and functions, in a way that is independent of the underlying storage. @@ -402,17 +402,27 @@ specific array implementation. The ``AbstractArray`` type includes anything vaguely array-like, and implementations of it might be quite different from conventional arrays. For example, elements might be computed on request rather than -stored. Or, it might not be possible to assign or access every array -location. - -``StoredArray`` is an abstract subtype of ``AbstractArray`` intended to -include all arrays that behave like memories: all elements are independent, -can be accessed, and (for mutable arrays) all elements can be assigned. -``DenseArray`` is a further abstract subtype of ``StoredArray``. Arrays of -this type have storage for every possible index, and provide uniform access -performance for all elements. - -The ``Array{T,n}`` type is a specific instance of ``DenseArray`` +stored. However, any concrete ``AbstractArray{T,N}`` type should +generally implement at least ``size(A)`` (returing an ``Int`` tuple), +``getindex(A,i)`` and ``getindex(A,i1,...,iN)`` (returning an element +of type ``T``); mutable arrays should also implement ``setindex!``. It +is recommended that these operations have nearly constant time complexity, +or technically Õ(1) complexity, as otherwise some array functions may +be unexpectedly slow. Concrete types should also typically provide +a `similar(A,T=eltype(A),dims=size(A))` method, which is used to allocate +a similar array for `copy` and other out-of-place operations. + +``DenseArray`` is an abstract subtype of ``AbstractArray`` intended +to include all arrays that are laid out at regular offsets in memory, +and which can therefore be passed to external C and Fortran functions +expecting this memory layout. Subtypes should provide a method +``stride(A,k)`` that returns the "stride" of dimension ``k``: +increasing the index of dimension ``k`` by ``1`` should increase the +index ``i`` of ``getindex(A,i)`` by ``stride(A,k)``. If a +pointer conversion method ``convert(Ptr{T}, A)`` is provided, the +memory layout should correspond in the same way to these strides. + +The ``Array{T,N}`` type is a specific instance of ``DenseArray`` where elements are stored in column-major order (see additional notes in :ref:`man-performance-tips`). ``Vector`` and ``Matrix`` are aliases for the 1-d and 2-d cases. Specific operations such as scalar indexing, @@ -420,7 +430,7 @@ assignment, and a few other basic storage-specific operations are all that have to be implemented for ``Array``, so that the rest of the array library can be implemented in a generic manner. -``SubArray`` is a specialization of ``StoredArray`` that performs +``SubArray`` is a specialization of ``AbstractArray`` that performs indexing by reference rather than by copying. A ``SubArray`` is created with the ``sub`` function, which is called the same way as ``getindex`` (with an array and a series of index arguments). The result of ``sub`` looks diff --git a/src/builtins.c b/src/builtins.c index 72bbb7ffdf983..63c83d7fdb798 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1057,7 +1057,6 @@ void jl_init_primitives(void) add_builtin("Task", (jl_value_t*)jl_task_type); add_builtin("AbstractArray", (jl_value_t*)jl_abstractarray_type); - add_builtin("StoredArray", (jl_value_t*)jl_storedarray_type); add_builtin("DenseArray", (jl_value_t*)jl_densearray_type); add_builtin("Array", (jl_value_t*)jl_array_type); diff --git a/src/dump.c b/src/dump.c index d6a8fe25fc302..fccd85cd6ee65 100644 --- a/src/dump.c +++ b/src/dump.c @@ -661,7 +661,7 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos) dt->fptr = jl_deserialize_fptr(s); if (dt->name == jl_array_type->name || dt->name == jl_pointer_type->name || dt->name == jl_type_type->name || dt->name == jl_vararg_type->name || - dt->name == jl_abstractarray_type->name || dt->name == jl_storedarray_type->name || + dt->name == jl_abstractarray_type->name || dt->name == jl_densearray_type->name) { // builtin types are not serialized, so their caches aren't // explicitly saved. so we reconstruct the caches of builtin @@ -1285,7 +1285,7 @@ void jl_init_serializer(void) jl_gotonode_type, jl_quotenode_type, jl_topnode_type, jl_type_type, jl_bottom_type, jl_pointer_type, jl_vararg_type, jl_ntuple_type, jl_abstractarray_type, - jl_storedarray_type, jl_densearray_type, jl_box_type, + jl_densearray_type, jl_box_type, jl_typector_type, jl_undef_type, jl_top_type, jl_typename_type, jl_task_type, jl_uniontype_type, jl_typetype_type, jl_typetype_tvar, jl_ANY_flag, jl_array_any_type, jl_intrinsic_type, jl_method_type, @@ -1297,7 +1297,7 @@ void jl_init_serializer(void) jl_typename_type->name, jl_type_type->name, jl_methtable_type->name, jl_method_type->name, jl_tvar_type->name, jl_vararg_type->name, jl_ntuple_type->name, jl_abstractarray_type->name, - jl_storedarray_type->name, jl_densearray_type->name, + jl_densearray_type->name, jl_lambda_info_type->name, jl_module_type->name, jl_box_type->name, jl_function_type->name, jl_typector_type->name, jl_intrinsic_type->name, jl_undef_type->name, jl_task_type->name, diff --git a/src/jltypes.c b/src/jltypes.c index d5aabecdece4a..60b525769118f 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -35,7 +35,6 @@ jl_value_t *jl_bottom_type; jl_value_t *jl_top_type; jl_datatype_t *jl_vararg_type; jl_datatype_t *jl_abstractarray_type; -jl_datatype_t *jl_storedarray_type; jl_datatype_t *jl_densearray_type; jl_datatype_t *jl_bool_type; @@ -2901,15 +2900,11 @@ void jl_init_types(void) jl_any_type, tv); tv = jl_tuple2(tvar("T"), tvar("N")); - jl_storedarray_type = - jl_new_abstracttype((jl_value_t*)jl_symbol("StoredArray"), - (jl_datatype_t*)jl_apply_type((jl_value_t*)jl_abstractarray_type, tv), - tv); tv = jl_tuple2(tvar("T"), tvar("N")); jl_densearray_type = jl_new_abstracttype((jl_value_t*)jl_symbol("DenseArray"), - (jl_datatype_t*)jl_apply_type((jl_value_t*)jl_storedarray_type, tv), + (jl_datatype_t*)jl_apply_type((jl_value_t*)jl_abstractarray_type, tv), tv); tv = jl_tuple2(tvar("T"), tvar("N")); diff --git a/src/julia.h b/src/julia.h index 3449e1ce033f2..ed9a22b982bd6 100644 --- a/src/julia.h +++ b/src/julia.h @@ -327,7 +327,6 @@ extern DLLEXPORT jl_datatype_t *jl_module_type; extern DLLEXPORT jl_datatype_t *jl_vararg_type; extern DLLEXPORT jl_datatype_t *jl_function_type; extern DLLEXPORT jl_datatype_t *jl_abstractarray_type; -extern DLLEXPORT jl_datatype_t *jl_storedarray_type; extern DLLEXPORT jl_datatype_t *jl_densearray_type; extern DLLEXPORT jl_datatype_t *jl_array_type; extern DLLEXPORT jl_typename_t *jl_array_typename;