diff --git a/src/arithmetic.jl b/src/arithmetic.jl index db1bbfc..de69108 100644 --- a/src/arithmetic.jl +++ b/src/arithmetic.jl @@ -188,7 +188,7 @@ function lufact!{T}(n::NamedArray{T}, pivot::Union{Type{Val{false}}, Type{Val{tr end ## after lu.jl, this could be merged at Base. -function Base.getindex(A::LU{T,NamedArray{T,2,AT,DT,IS}}, d::Symbol) where {T, AT, DT, IS} +function Base.getindex(A::LU{T,NamedArray{T,2,AT,DT}}, d::Symbol) where {T, AT, DT} m, n = size(A) if d == :L L = tril!(A.factors[1:m, 1:min(m,n)]) diff --git a/src/index.jl b/src/index.jl index 352ea4a..ff2789f 100644 --- a/src/index.jl +++ b/src/index.jl @@ -7,16 +7,16 @@ import Base: getindex, setindex! ## AbstractArray Interface, integers have precedence over everything else -getindex(n::NamedArray{T, N, AT, DT, IndexLinear()}, i::Int) where {T, N, AT, DT} = getindex(n.array, i) -getindex(n::NamedArray{T, N, AT, DT, IndexCartesian()}, I::Vararg{Int, N}) where {T, N, AT, DT} = getindex(n.array, I) -setindex!(n::NamedArray{T, N, AT, DT, IndexLinear()}, v, i::Int) where {T, N, AT, DT} = setindex!(n.array, v, i::Int) -setindex!(n::NamedArray{T, N, AT, DT, IndexCartesian()}, v, I::Vararg{Int, N}) where {T, N, AT, DT} = setindex!(n.array, v, I) +getindex(n::NamedArray{T, N, AT, DT}, i::Int) where {T, N, AT, DT} = getindex(n.array, i) +getindex(n::NamedArray{T, N, AT, DT}, I::Vararg{Int, N}) where {T, N, AT, DT} = getindex(n.array, I...) +setindex!(n::NamedArray{T, N, AT, DT}, v, i::Int) where {T, N, AT, DT} = setindex!(n.array, v, i::Int) +setindex!(n::NamedArray{T, N, AT, DT}, v, I::Vararg{Int, N}) where {T, N, AT, DT} = setindex!(n.array, v, I...) ## optional methods -Base.IndexStyle(::NamedArray{T,N,AT,DT,IS}) where {T, N, AT, DT, IS} = IS +Base.IndexStyle(n::NamedArray) = IndexStyle(n.array) ## Ambiguity -getindex(n::NamedArray{T, 1, AT, DT, IndexLinear()}, i::Int64) where {T, AT, DT} = getindex(n.array, i) -setindex!(n::NamedArray{T, 1, AT, DT, IndexLinear()}, v::Any, i::Int64) where {T, AT, DT} = setindex!(n.array, v, i) +#getindex(n::NamedArray{T, 1, AT, DT}, i::Int64) where {T, AT, DT} = getindex(n.array, i) +setindex!(n::NamedArray{T, 1, AT, DT}, v::Any, i::Int64) where {T, AT, DT} = setindex!(n.array, v, i) function flattenednames(n::NamedArray) L = length(n) # elements in array @@ -39,9 +39,8 @@ getindex(n::NamedArray, ::Colon) = NamedArray(n.array[:], [flattenednames(n)] , ## special 0-dimensional case ## getindex{T}(n::NamedArray{T,0}, i::Real) = getindex(n.array, i) -@inline function getindex(n::NamedArray{T, N, AT, DT, IS}, I::Vararg{Any,N}) where {T, N, AT, DT, IS} - namedgetindex(n, map((d,i)->indices(d, i), n.dicts, I)...) -end +getindex(n::NamedArray{T, N, AT, DT}, I::Vararg{Any,N}) where {T, N, AT, DT} = namedgetindex(n, map((d,i)->indices(d, i), n.dicts, I)...) + Base.view{T,N}(n::NamedArray{T,N}, I::Vararg{Union{AbstractArray,Colon,Real},N}) = namedgetindex(n, map((d,i)->indices(d, i), n.dicts, I)...; useview=true) Base.view{T,N}(n::NamedArray{T,N}, I::Vararg{Any,N}) = namedgetindex(n, map((d,i)->indices(d, i), n.dicts, I)...; useview=true) @@ -66,9 +65,10 @@ indices(dict::Associative, ci::CartesianIndex) = ci #indices(dict::Associative{T,V}, i::AbstractArray{T}) where {T<:Integer,V<:Integer} = [dict[k] for k in i] #indices(dict::Associative{T,V}, i::AbstractArray{T}) where {T<:Real,V<:Integer} = [dict[k] for k in i] -indices(dict::Associative{K,V}, i::AbstractArray{T}) where {T<:Integer,K,V<:Integer} = i -indices(dict::Associative{K,V}, i::AbstractArray{K}) where {K,V<:Integer} = [dict[k] for k in i] -indices(dict::Associative{K,V}, i::AbstractArray{Name{K}}) where {K, V<:Integer} = [dict[k.name] for k in i] +indices(dict::Associative{K,V}, i::AbstractArray) where {K,V<:Integer} = [indices(dict, k) for k in i] +#indices(dict::Associative{K,V}, i::AbstractArray{T}) where {T<:Integer,K,V<:Integer} = i +#indices(dict::Associative{K,V}, i::AbstractArray{K}) where {K,V<:Integer} = [dict[k] for k in i] +#indices(dict::Associative{K,V}, i::AbstractArray{Name{K}}) where {K, V<:Integer} = [dict[k.name] for k in i] ## in 0.4, we need to take care of : ourselves it seems indices{K,V<:Integer}(dict::Associative{K,V}, ::Colon) = collect(1:length(dict)) diff --git a/src/namedarraytypes.jl b/src/namedarraytypes.jl index 36bbee5..8ca45f7 100644 --- a/src/namedarraytypes.jl +++ b/src/namedarraytypes.jl @@ -9,22 +9,47 @@ ## DT is a tuple of Dicts, characterized by the types of the keys. ## This way NamedArray is dependent on the dictionary type of each dimensions. ## The inner constructor checks for consistency, the values must all be 1:d + +using DataStructures: OrderedDict + if !isdefined(:NamedArray) -mutable struct NamedArray{T,N,AT,DT,IS} <: AbstractArray{T,N} +struct Name{T} + name::T +end + +Base.show(io::IO, name::Name) = print(io, name.name) + +function checkdict(dict::Associative) + pairs = Pair[] + union = Union{} + n = length(dict) + covered = falses(n) + for (key, value) in dict + if isa(key, Integer) + key = Name(key) + end + union = Union{union, typeof(key)} + push!(pairs, key => value) + if isa(value, Integer) && 1 ≤ value ≤ n + covered[value] = true + end + end + all(covered) || error("Not all target indices are covered") + return OrderedDict{union, Int}(pairs) +end + +mutable struct NamedArray{T,N,AT,DT} <: AbstractArray{T,N} array::AT dicts::DT dimnames::NTuple{N, Any} function (::Type{S}){S<:NamedArray, T, N}(array::AbstractArray{T, N}, dicts::NTuple{N, OrderedDict}, dimnames::NTuple{N, Any}) size(array) == map(length, dicts) || error("Inconsistent dictionary sizes") - new{T, N, typeof(array), typeof(dicts), IndexStyle(array)}(array, dicts, dimnames) + ## dicts = map(dict -> checkdict(dict), dicts) + new{T, N, typeof(array), typeof(dicts)}(array, dicts, dimnames) end end -struct Name{T} - name::T -end - ## a type that negates any index struct Not{T} index::T