From af0cbbcd9ddf4a1d904c3f5824b9569a8d7bd1af Mon Sep 17 00:00:00 2001 From: rafaqz Date: Mon, 20 Nov 2023 12:24:49 +0100 Subject: [PATCH 1/5] test rand on stacks --- test/stack.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/stack.jl b/test/stack.jl index 0c03c5881..c25fd7da6 100644 --- a/test/stack.jl +++ b/test/stack.jl @@ -1,4 +1,4 @@ -using DimensionalData, Test, LinearAlgebra, Statistics, ConstructionBase +using DimensionalData, Test, LinearAlgebra, Statistics, ConstructionBase, Random using DimensionalData: data using DimensionalData: Sampled, Categorical, AutoLookup, NoLookup, Transformed, @@ -332,3 +332,10 @@ end @test extrema(f, s) == (one=(2.0, 12.0), two=(4.0, 24.0), three=(6.0, 36.0)) @test mean(f, s) == (one=7.0, two=14.0, three=21) end + +@testset "rand sampling" begin + @test rand(s) isa @NamedTuple{one::Float64, two::Float32, three::Int} + @test rand(Xoshiro(), s) isa @NamedTuple{one::Float64, two::Float32, three::Int} + @test rand(mixed) isa @NamedTuple{one::Float64, two::Float32, extradim::Float64} + @test rand(MersenneTwister(), mixed) isa @NamedTuple{one::Float64, two::Float32, extradim::Float64} +end From 5867b29ccd1db8683220040f934754a8173e82d3 Mon Sep 17 00:00:00 2001 From: rafaqz Date: Mon, 20 Nov 2023 12:25:02 +0100 Subject: [PATCH 2/5] add rand for stack --- Project.toml | 6 ++++-- src/stack/indexing.jl | 9 ++++++++- src/stack/methods.jl | 7 +++++++ src/stack/stack.jl | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index f9486f601..1ac97749b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DimensionalData" uuid = "0703355e-b756-11e9-17c0-8b28908087d0" authors = ["Rafael Schouten "] -version = "0.25.8" +version = "0.25.7" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" @@ -36,6 +36,7 @@ CairoMakie = "0.10, 0.11" ColorTypes = "0.11" Combinatorics = "1" ConstructionBase = "1" +Combinatorics = "1" CoordinateTransformations = "0.6" DataFrames = "1" Dates = "1" @@ -50,12 +51,13 @@ IteratorInterfaceExtensions = "1" LinearAlgebra = "1" Makie = "0.19, 0.20" OffsetArrays = "1" -Plots = "1" PrecompileTools = "1" +Plots = "1" Random = "1" RecipesBase = "0.7, 0.8, 1" SafeTestsets = "0.1" SparseArrays = "1" +StatsPlots = "0.15" Statistics = "1" StatsPlots = "0.15" TableTraits = "1" diff --git a/src/stack/indexing.jl b/src/stack/indexing.jl index cf62404b2..6b4c75c40 100644 --- a/src/stack/indexing.jl +++ b/src/stack/indexing.jl @@ -16,8 +16,15 @@ end map(A -> Base.getindex(A, i, I...), data(s)) for f in (:getindex, :view, :dotview) @eval begin + @propagate_inbounds function Base.$f(s::AbstractDimStack, I...; kw...) - newlayers = map(A -> Base.$f(A, I...; kw...), layers(s)) + indexdims = (I..., kwdims(values(kw))...) + extradims = otherdims(indexdims, dims(s)) + length(extradims) > 0 && Dimensions._extradimswarn(extradims) + newlayers = map(layers(s)) do A + layerdims = dims(indexdims, dims(A)) + Base.$f(A, layerdims...) + end if all(map(v -> v isa AbstractDimArray, newlayers)) rebuildsliced(Base.$f, s, newlayers, (dims2indices(dims(s), (I..., kwdims(values(kw))...)))) else diff --git a/src/stack/methods.jl b/src/stack/methods.jl index 52a956c2c..4b8ba7ddb 100644 --- a/src/stack/methods.jl +++ b/src/stack/methods.jl @@ -222,3 +222,10 @@ for fname in (:one, :oneunit, :zero, :copy) end Base.reverse(s::AbstractDimStack; dims=1) = map(A -> reverse(A; dims=dims), s) + +# Random +Random.Sampler(RNG::Type{<:AbstractRNG}, st::AbstractDimStack, n::Random.Repetition) = + Random.SamplerSimple(st, Random.Sampler(RNG, DimIndices(st), n)) + +Random.rand(rng::AbstractRNG, sp::Random.SamplerSimple{<:AbstractDimStack,<:Random.Sampler}) = + @inbounds return sp[][rand(rng, sp.data)...] diff --git a/src/stack/stack.jl b/src/stack/stack.jl index 815938bac..8a671b0dc 100644 --- a/src/stack/stack.jl +++ b/src/stack/stack.jl @@ -103,7 +103,7 @@ Base.axes(s::AbstractDimStack) = map(first ∘ axes, dims(s)) Base.axes(s::AbstractDimStack, dims::DimOrDimType) = axes(s, dimnum(s, dims)) Base.axes(s::AbstractDimStack, dims::Integer) = axes(s)[dims] Base.similar(s::AbstractDimStack, args...) = map(A -> similar(A, args...), s) -Base.eltype(s::AbstractDimStack, args...) = map(eltype, s) +Base.eltype(s::AbstractDimStack, args...) = NamedTuple{keys(s),Tuple{map(eltype, s)...}} Base.iterate(s::AbstractDimStack, args...) = iterate(layers(s), args...) Base.read(s::AbstractDimStack) = map(read, s) # `merge` for AbstractDimStack and NamedTuple. From 2ccc9b7be58433ae668dd0c132208bccd7bcc23e Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sat, 30 Dec 2023 13:23:17 +0100 Subject: [PATCH 3/5] f --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 1ac97749b..dc12586ca 100644 --- a/Project.toml +++ b/Project.toml @@ -51,8 +51,8 @@ IteratorInterfaceExtensions = "1" LinearAlgebra = "1" Makie = "0.19, 0.20" OffsetArrays = "1" -PrecompileTools = "1" Plots = "1" +PrecompileTools = "1" Random = "1" RecipesBase = "0.7, 0.8, 1" SafeTestsets = "0.1" From b72c7b31ea984ca1295f8756a2d19b0e7ac3a6cd Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sat, 30 Dec 2023 22:59:15 +0100 Subject: [PATCH 4/5] f --- Project.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index dc12586ca..f9486f601 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DimensionalData" uuid = "0703355e-b756-11e9-17c0-8b28908087d0" authors = ["Rafael Schouten "] -version = "0.25.7" +version = "0.25.8" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" @@ -36,7 +36,6 @@ CairoMakie = "0.10, 0.11" ColorTypes = "0.11" Combinatorics = "1" ConstructionBase = "1" -Combinatorics = "1" CoordinateTransformations = "0.6" DataFrames = "1" Dates = "1" @@ -57,7 +56,6 @@ Random = "1" RecipesBase = "0.7, 0.8, 1" SafeTestsets = "0.1" SparseArrays = "1" -StatsPlots = "0.15" Statistics = "1" StatsPlots = "0.15" TableTraits = "1" From 6e45feff8f73e3bf5eb5a37b90126fa18b3545be Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sun, 14 Jan 2024 23:36:22 +0100 Subject: [PATCH 5/5] indexing fixes --- src/stack/indexing.jl | 51 +++++++++++++++++++++++++++++++++++-------- test/stack.jl | 6 ++--- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/stack/indexing.jl b/src/stack/indexing.jl index 6b4c75c40..b7df97814 100644 --- a/src/stack/indexing.jl +++ b/src/stack/indexing.jl @@ -12,25 +12,58 @@ end end # Array-like indexing -@propagate_inbounds Base.getindex(s::AbstractDimStack, i::Int, I::Int...) = - map(A -> Base.getindex(A, i, I...), data(s)) for f in (:getindex, :view, :dotview) @eval begin - - @propagate_inbounds function Base.$f(s::AbstractDimStack, I...; kw...) - indexdims = (I..., kwdims(values(kw))...) - extradims = otherdims(indexdims, dims(s)) + @propagate_inbounds function Base.$f( + s::AbstractDimStack, i1::Union{Integer,CartesianIndex}, Is::Union{Integer,CartesianIndex}... + ) + # Convert to Dimension wrappers to handle mixed size layers + Base.$f(s, DimIndices(s)[i1, Is...]...) + end + @propagate_inbounds function Base.$f(s::AbstractDimStack, i1, Is...) + I = (i1, Is...) + if length(dims(s)) > length(I) + throw(BoundsError(dims(s), I)) + elseif length(dims(s)) < length(I) + # Allow trailing ones + if all(i -> i isa Integer && i == 1, I[length(dims(s)):end]) + I = I[1:length(dims)] + else + throw(BoundsError(dims(s), I)) + end + end + # Convert to Dimension wrappers to handle mixed size layers + Base.$f(s, map(rebuild, dims(s), I)...) + end + @propagate_inbounds function Base.$f(s::AbstractDimStack, i::AbstractArray) + # Multidimensional: return vectors of values + if length(dims(s)) > 1 + Ds = DimIndices(s)[i] + map(s) do A + map(D -> A[D...], Ds) + end + else + map(A -> A[i], s) + end + end + @propagate_inbounds function Base.$f(s::AbstractDimStack, D::Dimension...; kw...) + alldims = (D..., kwdims(values(kw))...) + extradims = otherdims(alldims, dims(s)) length(extradims) > 0 && Dimensions._extradimswarn(extradims) newlayers = map(layers(s)) do A - layerdims = dims(indexdims, dims(A)) - Base.$f(A, layerdims...) + layerdims = dims(alldims, dims(A)) + I = length(layerdims) > 0 ? layerdims : map(_ -> :, size(A)) + Base.$f(A, I...) end if all(map(v -> v isa AbstractDimArray, newlayers)) - rebuildsliced(Base.$f, s, newlayers, (dims2indices(dims(s), (I..., kwdims(values(kw))...)))) + rebuildsliced(Base.$f, s, newlayers, (dims2indices(dims(s), alldims))) else newlayers end end + @propagate_inbounds function Base.$f(s::AbstractDimStack) + map($f, s) + end end end diff --git a/test/stack.jl b/test/stack.jl index c25fd7da6..0e2796a25 100644 --- a/test/stack.jl +++ b/test/stack.jl @@ -63,7 +63,7 @@ end @testset "low level base methods" begin @test keys(data(s)) == (:one, :two, :three) @test keys(data(mixed)) == (:one, :two, :extradim) - @test eltype(mixed) === (one=Float64, two=Float32, extradim=Float64) + @test eltype(mixed) === @NamedTuple{one::Float64, two::Float32, extradim::Float64} @test haskey(s, :one) == true @test haskey(s, :zero) == false @test length(s) == 3 # length is as for NamedTuple @@ -86,11 +86,11 @@ end @test all(map(similar(mixed), mixed) do s, m dims(s) == dims(m) && dims(s) === dims(m) && eltype(s) === eltype(m) end) - @test all(map(==(Int), eltype(similar(s, Int)))) + @test eltype(similar(s, Int)) === @NamedTuple{one::Int, two::Int, three::Int} st2 = similar(mixed, Bool, x, y) @test dims(st2) === (x, y) @test dims(st2[:one]) === (x, y) - @test all(map(==(Bool), eltype(st2))) + @test eltype(st2) === @NamedTuple{one::Bool, two::Bool, extradim::Bool} end @testset "merge" begin