From 9114eb5ed8cfe0123a32f9fd56d0f7bc7125734f Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Tue, 30 Apr 2019 16:10:35 +0200 Subject: [PATCH 1/7] create labelled subsets --- README.md | 16 ++++++++++++++++ src/LabelledArrays.jl | 1 + src/larray.jl | 8 ++++++++ src/slarray.jl | 22 ++++++++++++++++++++++ test/larrays.jl | 21 +++++++++++++++++++++ 5 files changed, 68 insertions(+) diff --git a/README.md b/README.md index 1033d7d..88c579a 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,22 @@ julia> B2 = SLArray(B; c=30 ) 2 4 ``` +Creating subsets is supported by function `subset`. +It differs from slicing via `[]` by retaining the labels, instead of returning an Array. + + +```julia +julia> zs = SLVector(a=1.0,b=2.0,c=3.0); +julia> zsSub = subset(zs, (:c,:a)) +2-element SLArray{Tuple{2},Float64,1,2,(:c, :a)}: + 3.0 + 1.0 +julia> zs[[:c,:a]] +2-element Array{Float64,1}: + 3.0 + 1.0 +``` + ## LArrays The `LArrays`s are fully mutable arrays with labels. There is no performance diff --git a/src/LabelledArrays.jl b/src/LabelledArrays.jl index d145981..ec01c9a 100644 --- a/src/LabelledArrays.jl +++ b/src/LabelledArrays.jl @@ -13,5 +13,6 @@ export SLArray, LArray, SLVector, LVector, @SLVector, @LArray, @LVector, @SLArra export @SLSliced, @LSliced export symbols, dimSymbols, rowSymbols, colSymbols +export subset end # module diff --git a/src/larray.jl b/src/larray.jl index 139796d..e7d445c 100644 --- a/src/larray.jl +++ b/src/larray.jl @@ -240,3 +240,11 @@ function SLArray(v1::Union{SLArray{S,T,N,L,Syms},LArray{T,N,D,Syms}}; kwargs...) t2 = merge(convert(NamedTuple, v1), kwargs.data) SLArray{S}(t2) end + + +subset(lvec::LArray, s::Tuple) = subset(lvec, Val(s)) +function subset(lvec::LArray{T,1,D,Syms}, ::Val{SymSub}) where {T,D,Syms,SymSub} + subArr = lvec[SVector(SymSub)] + lsub = LArray{T,1,D,SymSub}(subArr) +end + diff --git a/src/slarray.jl b/src/slarray.jl index 546d9ac..6c81cae 100644 --- a/src/slarray.jl +++ b/src/slarray.jl @@ -180,3 +180,25 @@ For example: symbols(z) # Tuple{Symbol,Symbol,Symbol} == (:a, :b, :c) """ symbols(::SLArray{S,T,N,L,Syms}) where {S,T,N,L,Syms} = Syms + + +""" + subset(::SLArray, indicesTuple) + +Creates a new SLArray containing only the given indices. +The indices are given as a Tuple of symbols or a Tuple of Integer positions. + +Note, that this differs from subsetting a Labelled array by getindex or `[]` +by retaining the labels, instead of returning an Array. + +For example: + + zs = SLVector(a=1, b=2, c=3) + zsSub = subset(zs, (:c,:a)) +""" +subset(lvec::SLArray, s::Tuple) = subset(lvec, Val(s)) +function subset(lvec::SLArray{S,T,1,L,Syms}, ::Val{SymSub}) where {S,T,L,Syms,SymSub} + subArr = lvec[SVector(SymSub)] + SLVector(NamedTuple{SymSub}(subArr)) +end + \ No newline at end of file diff --git a/test/larrays.jl b/test/larrays.jl index fa770b3..be47dff 100644 --- a/test/larrays.jl +++ b/test/larrays.jl @@ -106,6 +106,27 @@ end @test zs[[:c,:a]] == [3.,1.] end +# using StaticArrays +# @testset "several indices as SVector" begin +# z = @LArray [1.,2.,3.] (:a,:b,:c); +# @test z[@SVector[3,1]] == [3.,1.] +# @test z[@SVector[:c,:a]] == [3.,1.] +# #i = LabelledArrays.symToInd(z, (:c,:a)) # also works with Tuples +# zs = SLVector(a=1.0,b=2.0,c=3.0); +# @test zs[@SVector[3,1]] == [3.,1.] +# @test zs[@SVector[:c,:a]] == [3.,1.] +# end + +@testset "subset" begin + z = @LArray [1.,2.,3.] (:a,:b,:c); + zSub = subset(z, (:c,:a)) + @test zSub == @LArray [3.,1.] (:c,:a) + zSub = subset(z, (3,1)) + @test zSub == @LArray [3.,1.] (:c,:a) + zs = SLVector(a=1.0,b=2.0,c=3.0); + zsSub = subset(zs, (:c,:a)) + @test zSub == SLVector(c=3.0,a=1.0) +end From ed3f7c849413526cc4726f2849f080fe5347ca4d Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Mon, 6 May 2019 15:25:55 +0200 Subject: [PATCH 2/7] subset with indices as SVector and SLVector --- src/larray.jl | 16 ++++++++++++++++ src/slarray.jl | 15 +++++++++++++++ test/larrays.jl | 25 +++++++++++++++++++++---- test/slarrays.jl | 28 ++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/larray.jl b/src/larray.jl index d1f463c..ee46864 100644 --- a/src/larray.jl +++ b/src/larray.jl @@ -268,4 +268,20 @@ function subset(lvec::LArray{T,1,D,Syms}, ::Val{SymSub}) where {T,D,Syms,SymSub} subArr = lvec[SVector(SymSub)] lsub = LArray{T,1,D,SymSub}(subArr) end + + +function subset(lvec::Union{SLArray,LArray}, ind::SVector{N,I}) where {N,I <: Integer} + labels = symbols(lvec)[ind] + subset(lvec,labels) +end +subset(lvec::Union{SLArray,LArray}, labels::SVector{N,T}) where {N,T <: Symbol} = + subset(lvec,Tuple(labels)) +subset(lvec::Union{SLArray,LArray}, labels::SLArray{T,Symbol,1,N,Sym}) where {T,N,Sym} = + subset(lvec,Tuple(labels)) +function subset(lvec::Union{SLArray,LArray}, ind::SLArray{T,I,1,N,Sym}) where {T,I<:Integer,N,Sym} + labels = symbols(lvec)[ind] + subset(lvec,Tuple(labels)) +end + + diff --git a/src/slarray.jl b/src/slarray.jl index bbcffea..e9585da 100644 --- a/src/slarray.jl +++ b/src/slarray.jl @@ -181,6 +181,7 @@ macro SLVector(T,syms) end end + """ symbols(::SLArray{T,N,D,Syms}) @@ -213,3 +214,17 @@ function subset(lvec::SLArray{S,T,1,L,Syms}, ::Val{SymSub}) where {S,T,L,Syms,Sy subArr = lvec[SVector(SymSub)] SLVector(NamedTuple{SymSub}(subArr)) end + +function subset(lvec::SLArray, ind::SVector{N,I}) where {N,I <: Integer} + labels = symbols(lvec)[ind] + subset(lvec,labels) +end +subset(lvec::SLArray, labels::SVector{N,T}) where {N,T <: Symbol} = + subset(lvec,Tuple(labels)) +subset(lvec::SLArray, labels::SLArray{T,Symbol,1,N,Sym}) where {T,N,Sym} = + subset(lvec,Tuple(labels)) +function subset(lvec::SLArray, ind::SLArray{T,I,1,N,Sym}) where {T,I<:Integer,N,Sym} + labels = symbols(lvec)[ind] + subset(lvec,Tuple(labels)) +end + diff --git a/test/larrays.jl b/test/larrays.jl index d3cd5ab..70ab051 100644 --- a/test/larrays.jl +++ b/test/larrays.jl @@ -129,10 +129,27 @@ end z = @LArray [1.,2.,3.] (:a,:b,:c); zSub = subset(z, (:c,:a)) @test zSub == @LArray [3.,1.] (:c,:a) - zSub = subset(z, (3,1)) - @test zSub == @LArray [3.,1.] (:c,:a) - zs = SLVector(a=1.0,b=2.0,c=3.0); - zsSub = subset(zs, (:c,:a)) + @test symbols(zSub) == (:c,:a) + # + # does not work yet + # zSub = subset(z, (3,1)) + # @test zSub == @LArray [3.,1.] (:c,:a) + # @test symbols(zSub) == (:c,:a) + # + ind = @SVector[3,1] #SVector(3,1) + zSub = subset(z, ind) + @test zSub == SLVector(c=3.0,a=1.0) + # + ind = @SVector[:c,:a] #SVector(:c,:a) + zSub = subset(z, ind) + @test zSub == SLVector(c=3.0,a=1.0) + # + ind = (@SLVector (:n1,:n2))([:c,:a]) + zSub = subset(z, ind) + @test zSub == SLVector(c=3.0,a=1.0) + # + ind = (@SLVector (:n1,:n2))([3,1]) + zSub = subset(z, ind) @test zSub == SLVector(c=3.0,a=1.0) end diff --git a/test/slarrays.jl b/test/slarrays.jl index 270f9c4..14fc1bb 100644 --- a/test/slarrays.jl +++ b/test/slarrays.jl @@ -76,3 +76,31 @@ end z = Arr(1, 2, 3, 4) @test z.a == [2, 4] end + +@testset "subset" begin + zs = SLVector(a=1.0,b=2.0,c=3.0); + zsSub = subset(zs, (:c,:a)) + @test zsSub == SLVector(c=3.0,a=1.0) + # + # does not work yet: How to distingish Tuple{Symbols} vs Tuple{Integers} + #zsSub = subset(zs, (3,1)) + #@test zsSub == SLVector(c=3.0,a=1.0) + # + ind = SVector(3,1) + zsSub = subset(zs, ind) + @test zsSub == SLVector(c=3.0,a=1.0) + # + ind = SVector(:c,:a) + zsSub = subset(zs, ind) + @test zsSub == SLVector(c=3.0,a=1.0) + # + #ind = @SLVector (:n1,:n2) (:c,:a) + zsSub = subset(zs, ind) + @test zsSub == SLVector(c=3.0,a=1.0) + # + ind = (@SLVector (:n1,:n2))(3,1) + zsSub = subset(zs, ind) + @test zsSub == SLVector(c=3.0,a=1.0) +end + + From 81c288bb8043b7ad5432880a4db9cda01b2f7533 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Mon, 6 May 2019 18:40:31 +0200 Subject: [PATCH 3/7] subset with tuple of integers --- src/larray.jl | 10 ++++++---- src/slarray.jl | 32 +++++++++++++++----------------- test/larrays.jl | 19 ++++++++++++++----- test/slarrays.jl | 15 ++++++++++----- 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/larray.jl b/src/larray.jl index ee46864..4b2cc9a 100644 --- a/src/larray.jl +++ b/src/larray.jl @@ -264,12 +264,14 @@ end subset(lvec::LArray, s::Tuple) = subset(lvec, Val(s)) -function subset(lvec::LArray{T,1,D,Syms}, ::Val{SymSub}) where {T,D,Syms,SymSub} - subArr = lvec[SVector(SymSub)] - lsub = LArray{T,1,D,SymSub}(subArr) +function subset(lvec::LArray{T,N,D,Syms}, ::Val{SymSub}) where {T,N,D,Syms,SymSub} + length(SymSub) == 0 && return(LVector()) + symb = typeof(SymSub[1]) <: Integer ? Syms[collect(SymSub)] : SymSub + #symb = SymSub + subArr = lvec[SVector(symb)] + LArray{T,1,D,symb}(subArr) end - function subset(lvec::Union{SLArray,LArray}, ind::SVector{N,I}) where {N,I <: Integer} labels = symbols(lvec)[ind] subset(lvec,labels) diff --git a/src/slarray.jl b/src/slarray.jl index e9585da..ba7f61f 100644 --- a/src/slarray.jl +++ b/src/slarray.jl @@ -101,6 +101,7 @@ function Base.getindex(x::SLArray, inds::StaticVector{<:Any, Int}) end # Note: This could in the future return an SLArray with the right names +# see issue #59 for rather using subset to return SLVector function Base.getindex(x::SLArray,s::AbstractArray{Symbol,1}) [getindex(x,si) for si in s] end @@ -204,27 +205,24 @@ The indices are given as a Tuple of symbols or a Tuple of Integer positions. Note, that this differs from subsetting a Labelled array by getindex or `[]` by retaining the labels, instead of returning an Array. +It works with vectors and arrays, where each element is labelled, but not for +complex cases, where a label refers to several items. + +For type stability provide the index-tuple inside `Val()`. + For example: zs = SLVector(a=1, b=2, c=3) zsSub = subset(zs, (:c,:a)) + zsSub = subset(zs, Val((:c,:a))) """ -subset(lvec::SLArray, s::Tuple) = subset(lvec, Val(s)) -function subset(lvec::SLArray{S,T,1,L,Syms}, ::Val{SymSub}) where {S,T,L,Syms,SymSub} - subArr = lvec[SVector(SymSub)] - SLVector(NamedTuple{SymSub}(subArr)) -end - -function subset(lvec::SLArray, ind::SVector{N,I}) where {N,I <: Integer} - labels = symbols(lvec)[ind] - subset(lvec,labels) +@inline subset(lvec::SLArray, s::Tuple) = subset(lvec, Val(s)) +function subset(lvec::SLArray{S,T,N,L,Syms}, ::Val{SymSub}) where {S,T,N,L,Syms,SymSub} + length(SymSub) == 0 && return(SLVector()) + symb = typeof(SymSub[1]) <: Integer ? Syms[collect(SymSub)] : SymSub + subArr = lvec[SVector(symb)] + #SLVector(NamedTuple{symb}(subArr)) # not type stable + SLArray{Tuple{length(SymSub)},T,1,length(SymSub),symb}(subArr) end -subset(lvec::SLArray, labels::SVector{N,T}) where {N,T <: Symbol} = - subset(lvec,Tuple(labels)) -subset(lvec::SLArray, labels::SLArray{T,Symbol,1,N,Sym}) where {T,N,Sym} = - subset(lvec,Tuple(labels)) -function subset(lvec::SLArray, ind::SLArray{T,I,1,N,Sym}) where {T,I<:Integer,N,Sym} - labels = symbols(lvec)[ind] - subset(lvec,Tuple(labels)) -end +# for providing indices as SVector or SLVector see larrays.jl diff --git a/test/larrays.jl b/test/larrays.jl index 70ab051..a48398c 100644 --- a/test/larrays.jl +++ b/test/larrays.jl @@ -1,4 +1,4 @@ -using LabelledArrays, Test, InteractiveUtils +using LabelledArrays, StaticArrays, Test, InteractiveUtils @testset "Basic interface" begin vals = [1.0,2.0,3.0] @@ -131,10 +131,11 @@ end @test zSub == @LArray [3.,1.] (:c,:a) @test symbols(zSub) == (:c,:a) # - # does not work yet - # zSub = subset(z, (3,1)) - # @test zSub == @LArray [3.,1.] (:c,:a) - # @test symbols(zSub) == (:c,:a) + # workaround with checking types in subset + zSub = subset(z, (3,1)) + #@which subset(z, Val((3,1))) + @test zSub == @LArray [3.,1.] (:c,:a) + @test symbols(zSub) == (:c,:a) # ind = @SVector[3,1] #SVector(3,1) zSub = subset(z, ind) @@ -151,5 +152,13 @@ end ind = (@SLVector (:n1,:n2))([3,1]) zSub = subset(z, ind) @test zSub == SLVector(c=3.0,a=1.0) + + #zs[SVector(:c,:a)] + #@inferred z[SVector(:c,:a)] + + #subset(z, Val((:c,:a))) + #@code_warntype subset(z, Val((:c,:a))) + @inferred subset(z, Val((:c,:a))) + end diff --git a/test/slarrays.jl b/test/slarrays.jl index 14fc1bb..cbc7494 100644 --- a/test/slarrays.jl +++ b/test/slarrays.jl @@ -78,13 +78,15 @@ end end @testset "subset" begin - zs = SLVector(a=1.0,b=2.0,c=3.0); + #zs = SLVector(a=1.0,b=2.0,c=3.0,d=4.0) + zs = SLArray{Tuple{2,2}}(a=1.0,b=2.0,c=3.0,d=4.0); zsSub = subset(zs, (:c,:a)) @test zsSub == SLVector(c=3.0,a=1.0) # - # does not work yet: How to distingish Tuple{Symbols} vs Tuple{Integers} - #zsSub = subset(zs, (3,1)) - #@test zsSub == SLVector(c=3.0,a=1.0) + # workaround with testing type inside subset + zsSub = subset(zs, (3,1)) + @test zsSub == SLVector(c=3.0,a=1.0) + @test symbols(zsSub) == (:c,:a) # ind = SVector(3,1) zsSub = subset(zs, ind) @@ -101,6 +103,9 @@ end ind = (@SLVector (:n1,:n2))(3,1) zsSub = subset(zs, ind) @test zsSub == SLVector(c=3.0,a=1.0) -end + #subset(zs, Val((:c,:a))) + #@code_warntype subset(zs, Val((:c,:a))) + @inferred subset(zs, Val((:c,:a))) +end From eb68bb60bef3c70bc02fd0c361991b779aa1a680 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Mon, 6 May 2019 18:40:31 +0200 Subject: [PATCH 4/7] dispatch subset by Tuple{N,Symbol} or Tuple{N,Int} --- src/larray.jl | 10 ++++++---- src/slarray.jl | 37 ++++++++++++++++++++++--------------- test/larrays.jl | 19 ++++++++++++++----- test/slarrays.jl | 15 ++++++++++----- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/larray.jl b/src/larray.jl index ee46864..4b2cc9a 100644 --- a/src/larray.jl +++ b/src/larray.jl @@ -264,12 +264,14 @@ end subset(lvec::LArray, s::Tuple) = subset(lvec, Val(s)) -function subset(lvec::LArray{T,1,D,Syms}, ::Val{SymSub}) where {T,D,Syms,SymSub} - subArr = lvec[SVector(SymSub)] - lsub = LArray{T,1,D,SymSub}(subArr) +function subset(lvec::LArray{T,N,D,Syms}, ::Val{SymSub}) where {T,N,D,Syms,SymSub} + length(SymSub) == 0 && return(LVector()) + symb = typeof(SymSub[1]) <: Integer ? Syms[collect(SymSub)] : SymSub + #symb = SymSub + subArr = lvec[SVector(symb)] + LArray{T,1,D,symb}(subArr) end - function subset(lvec::Union{SLArray,LArray}, ind::SVector{N,I}) where {N,I <: Integer} labels = symbols(lvec)[ind] subset(lvec,labels) diff --git a/src/slarray.jl b/src/slarray.jl index e9585da..0a7b7d6 100644 --- a/src/slarray.jl +++ b/src/slarray.jl @@ -101,6 +101,7 @@ function Base.getindex(x::SLArray, inds::StaticVector{<:Any, Int}) end # Note: This could in the future return an SLArray with the right names +# see issue #59 for rather using subset to return SLVector function Base.getindex(x::SLArray,s::AbstractArray{Symbol,1}) [getindex(x,si) for si in s] end @@ -204,27 +205,33 @@ The indices are given as a Tuple of symbols or a Tuple of Integer positions. Note, that this differs from subsetting a Labelled array by getindex or `[]` by retaining the labels, instead of returning an Array. +It works with vectors and arrays, where each element is labelled, but not for +complex cases, where a label refers to several items. + For example: zs = SLVector(a=1, b=2, c=3) zsSub = subset(zs, (:c,:a)) + zsSub = subset(zs, Val((:c,:a))) # type safe version using Val() + + zsSub = subset(zs, (3,1)) + zsSub = subset(zs, @SVector[:c,:a]) # @SVector from StaticArrays + zsSub = subset(zs, @SVector[3,1]) + zsSub = subset(zs, SLVector(i1=:c,i2=:a)) + zsSub = subset(zs, SLVector(i1=3,i2=1)) """ -subset(lvec::SLArray, s::Tuple) = subset(lvec, Val(s)) -function subset(lvec::SLArray{S,T,1,L,Syms}, ::Val{SymSub}) where {S,T,L,Syms,SymSub} - subArr = lvec[SVector(SymSub)] - SLVector(NamedTuple{SymSub}(subArr)) +@inline subset(lvec::SLArray, s::Tuple{N,Symbol}) where N = subset(lvec, Val(s)) +@inline function subset(lvec::SLArray{S,T,N,L,Syms}, ::Val{SymSub}) where {S,T,N,L,Syms,SymSub} + subArr = lvec[SVector(SymSub)] + #SLVector(NamedTuple{SymSub}(subArr)) # not type stable + SLArray{Tuple{length(SymSub)},T,1,length(SymSub),SymSub}(subArr) end -function subset(lvec::SLArray, ind::SVector{N,I}) where {N,I <: Integer} - labels = symbols(lvec)[ind] - subset(lvec,labels) +@inline subset(lvec::SLArray, s::Tuple{N,I}) where {N,I<:Integer} = subsetInt(lvec, Val(s)) +@inline function subsetInt(lvec::SLArray{S,T,N,L,Syms}, ::Val{SymSub}) where {S,T,N,L,Syms,SymSub} + symb = Syms[collect(SymSub)] + subArr = lvec[SVector(symb)] + SLArray{Tuple{length(SymSub)},T,1,length(SymSub),symb}(subArr) end -subset(lvec::SLArray, labels::SVector{N,T}) where {N,T <: Symbol} = - subset(lvec,Tuple(labels)) -subset(lvec::SLArray, labels::SLArray{T,Symbol,1,N,Sym}) where {T,N,Sym} = - subset(lvec,Tuple(labels)) -function subset(lvec::SLArray, ind::SLArray{T,I,1,N,Sym}) where {T,I<:Integer,N,Sym} - labels = symbols(lvec)[ind] - subset(lvec,Tuple(labels)) -end +# for providing indices as SVector or SLVector see larrays.jl diff --git a/test/larrays.jl b/test/larrays.jl index 70ab051..a48398c 100644 --- a/test/larrays.jl +++ b/test/larrays.jl @@ -1,4 +1,4 @@ -using LabelledArrays, Test, InteractiveUtils +using LabelledArrays, StaticArrays, Test, InteractiveUtils @testset "Basic interface" begin vals = [1.0,2.0,3.0] @@ -131,10 +131,11 @@ end @test zSub == @LArray [3.,1.] (:c,:a) @test symbols(zSub) == (:c,:a) # - # does not work yet - # zSub = subset(z, (3,1)) - # @test zSub == @LArray [3.,1.] (:c,:a) - # @test symbols(zSub) == (:c,:a) + # workaround with checking types in subset + zSub = subset(z, (3,1)) + #@which subset(z, Val((3,1))) + @test zSub == @LArray [3.,1.] (:c,:a) + @test symbols(zSub) == (:c,:a) # ind = @SVector[3,1] #SVector(3,1) zSub = subset(z, ind) @@ -151,5 +152,13 @@ end ind = (@SLVector (:n1,:n2))([3,1]) zSub = subset(z, ind) @test zSub == SLVector(c=3.0,a=1.0) + + #zs[SVector(:c,:a)] + #@inferred z[SVector(:c,:a)] + + #subset(z, Val((:c,:a))) + #@code_warntype subset(z, Val((:c,:a))) + @inferred subset(z, Val((:c,:a))) + end diff --git a/test/slarrays.jl b/test/slarrays.jl index 14fc1bb..cbc7494 100644 --- a/test/slarrays.jl +++ b/test/slarrays.jl @@ -78,13 +78,15 @@ end end @testset "subset" begin - zs = SLVector(a=1.0,b=2.0,c=3.0); + #zs = SLVector(a=1.0,b=2.0,c=3.0,d=4.0) + zs = SLArray{Tuple{2,2}}(a=1.0,b=2.0,c=3.0,d=4.0); zsSub = subset(zs, (:c,:a)) @test zsSub == SLVector(c=3.0,a=1.0) # - # does not work yet: How to distingish Tuple{Symbols} vs Tuple{Integers} - #zsSub = subset(zs, (3,1)) - #@test zsSub == SLVector(c=3.0,a=1.0) + # workaround with testing type inside subset + zsSub = subset(zs, (3,1)) + @test zsSub == SLVector(c=3.0,a=1.0) + @test symbols(zsSub) == (:c,:a) # ind = SVector(3,1) zsSub = subset(zs, ind) @@ -101,6 +103,9 @@ end ind = (@SLVector (:n1,:n2))(3,1) zsSub = subset(zs, ind) @test zsSub == SLVector(c=3.0,a=1.0) -end + #subset(zs, Val((:c,:a))) + #@code_warntype subset(zs, Val((:c,:a))) + @inferred subset(zs, Val((:c,:a))) +end From e1a1aeee7d5865c5b21ce5579709a97a11bddd47 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Mon, 6 May 2019 22:19:02 +0200 Subject: [PATCH 5/7] dispatch on Symbol or Integer LArray --- src/larray.jl | 15 ++++++++++----- test/larrays.jl | 2 -- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/larray.jl b/src/larray.jl index 4b2cc9a..553d1e2 100644 --- a/src/larray.jl +++ b/src/larray.jl @@ -263,11 +263,16 @@ function SLArray(v1::Union{SLArray{S,T,N,L,Syms},LArray{T,N,D,Syms}}; kwargs...) end -subset(lvec::LArray, s::Tuple) = subset(lvec, Val(s)) -function subset(lvec::LArray{T,N,D,Syms}, ::Val{SymSub}) where {T,N,D,Syms,SymSub} - length(SymSub) == 0 && return(LVector()) - symb = typeof(SymSub[1]) <: Integer ? Syms[collect(SymSub)] : SymSub - #symb = SymSub +@inline subset(lvec::LArray, s::Tuple{N,Symbol}) where N = subset(lvec, Val(s)) +@inline function subset(lvec::LArray{T,N,D,Syms}, ::Val{SymSub}) where {T,N,D,Syms,SymSub} + subArr = lvec[SVector(SymSub)] + #SLVector(NamedTuple{SymSub}(subArr)) # not type stable + LArray{T,1,D,SymSub}(subArr) +end + +@inline subset(lvec::LArray, s::Tuple{N,I}) where {N,I<:Integer} = subsetInt(lvec, Val(s)) +@inline function subsetInt(lvec::LArray{T,N,D,Syms}, ::Val{SymSub}) where {T,N,D,Syms,SymSub} + symb = Syms[collect(SymSub)] subArr = lvec[SVector(symb)] LArray{T,1,D,symb}(subArr) end diff --git a/test/larrays.jl b/test/larrays.jl index a48398c..f8021cc 100644 --- a/test/larrays.jl +++ b/test/larrays.jl @@ -131,9 +131,7 @@ end @test zSub == @LArray [3.,1.] (:c,:a) @test symbols(zSub) == (:c,:a) # - # workaround with checking types in subset zSub = subset(z, (3,1)) - #@which subset(z, Val((3,1))) @test zSub == @LArray [3.,1.] (:c,:a) @test symbols(zSub) == (:c,:a) # From d011140c3a56dc28e9ad0c6ccef008d565264b73 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Mon, 6 May 2019 22:39:16 +0200 Subject: [PATCH 6/7] subset with empty tuple --- src/larray.jl | 4 ++++ src/slarray.jl | 3 +++ test/larrays.jl | 3 +++ test/slarrays.jl | 3 +++ 4 files changed, 13 insertions(+) diff --git a/src/larray.jl b/src/larray.jl index 553d1e2..ab5b208 100644 --- a/src/larray.jl +++ b/src/larray.jl @@ -277,6 +277,10 @@ end LArray{T,1,D,symb}(subArr) end +@inline subset(lvec::LArray{T,N,D,Syms}, ::Tuple{}) where {T,N,D,Syms} = + LArray{T,1,D,()}(@SVector T[]) + + function subset(lvec::Union{SLArray,LArray}, ind::SVector{N,I}) where {N,I <: Integer} labels = symbols(lvec)[ind] subset(lvec,labels) diff --git a/src/slarray.jl b/src/slarray.jl index 0a7b7d6..702feab 100644 --- a/src/slarray.jl +++ b/src/slarray.jl @@ -234,4 +234,7 @@ end SLArray{Tuple{length(SymSub)},T,1,length(SymSub),symb}(subArr) end +@inline subset(lvec::SLArray, ::Tuple{}) = SLVector() + + # for providing indices as SVector or SLVector see larrays.jl diff --git a/test/larrays.jl b/test/larrays.jl index f8021cc..8739a14 100644 --- a/test/larrays.jl +++ b/test/larrays.jl @@ -151,6 +151,9 @@ end zSub = subset(z, ind) @test zSub == SLVector(c=3.0,a=1.0) + zSub = subset(z, ()) + @test zSub == @SVector eltype(z)[] + #zs[SVector(:c,:a)] #@inferred z[SVector(:c,:a)] diff --git a/test/slarrays.jl b/test/slarrays.jl index cbc7494..bfcb54a 100644 --- a/test/slarrays.jl +++ b/test/slarrays.jl @@ -104,6 +104,9 @@ end zsSub = subset(zs, ind) @test zsSub == SLVector(c=3.0,a=1.0) + zsSub = subset(zs, ()) + @test zSub == SLVector() + #subset(zs, Val((:c,:a))) #@code_warntype subset(zs, Val((:c,:a))) @inferred subset(zs, Val((:c,:a))) From b3b4ac538db2dc9c33c85d1d0fb4df8994a1d4dd Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Tue, 7 May 2019 09:12:50 +0200 Subject: [PATCH 7/7] preserve type in empty subset --- src/slarray.jl | 3 ++- test/slarrays.jl | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/slarray.jl b/src/slarray.jl index 702feab..f8d49bb 100644 --- a/src/slarray.jl +++ b/src/slarray.jl @@ -234,7 +234,8 @@ end SLArray{Tuple{length(SymSub)},T,1,length(SymSub),symb}(subArr) end -@inline subset(lvec::SLArray, ::Tuple{}) = SLVector() +@inline subset(lvec::SLArray{S,T,N,L,Syms}, ::Tuple{}) where {S,T,N,L,Syms} = + SLArray{Tuple{0},T,1,0,()}( @SVector T[] ) # for providing indices as SVector or SLVector see larrays.jl diff --git a/test/slarrays.jl b/test/slarrays.jl index bfcb54a..00bf4dd 100644 --- a/test/slarrays.jl +++ b/test/slarrays.jl @@ -105,7 +105,12 @@ end @test zsSub == SLVector(c=3.0,a=1.0) zsSub = subset(zs, ()) - @test zSub == SLVector() + #@test zsSub == SLVector() + @test length(zsSub) == 0 + @test zsSub isa SLArray + @test symbols(zsSub) == () + @test eltype(zsSub) == eltype(zs) + #subset(zs, Val((:c,:a))) #@code_warntype subset(zs, Val((:c,:a)))