rafaqz / DimensionalData.jl

Named dimensions and indexing for julia arrays and other data
https://rafaqz.github.io/DimensionalData.jl/stable/
MIT License
271 stars 38 forks source link

Support cat for dimensions with NoLookup #452

Closed sethaxen closed 1 year ago

sethaxen commented 1 year ago

Fixes #451

sethaxen commented 1 year ago

Seem to be a few other cases not covered:

julia> x = DimArray(randn(5), X(1:5));

julia> cat(parent(x), parent(x); dims=(1, 1))
10-element Vector{Float64}:
 -0.024470844481440174
  0.6956673544709626
 -0.7040110223985808
 -0.7119496870460033
 -0.2938321444807275
 -0.024470844481440174
  0.6956673544709626
 -0.7040110223985808
 -0.7119496870460033
 -0.2938321444807275

julia> cat(x, x; dims=(1, 1))
ERROR: DimensionMismatch: axes of Sampled of Base.OneTo(10) do not match array axis of Base.OneTo(2)
Stacktrace:
  [1] _checkaxiserror(lookup::Sampled{Int64, Vector{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}, axis::Base.OneTo{Int64})
    @ DimensionalData.Dimensions ~/projects/DimensionalData.jl/src/Dimensions/format.jl:129
  [2] checkaxis
    @ ~/projects/DimensionalData.jl/src/Dimensions/format.jl:121 [inlined]
  [3] _format
    @ ~/projects/DimensionalData.jl/src/Dimensions/format.jl:34 [inlined]
  [4] map
    @ ./tuple.jl:299 [inlined]
  [5] format
    @ ~/projects/DimensionalData.jl/src/Dimensions/format.jl:27 [inlined]
  [6] format
    @ ~/projects/DimensionalData.jl/src/Dimensions/format.jl:23 [inlined]
  [7] _cat(catdims::Tuple{X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}, X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}}, A1::DimArray{Float64, 1, Tuple{X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}}, Tuple{}, Vector{Float64}, DimensionalData.NoName, NoMetadata}, As::DimArray{Float64, 1, Tuple{X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}}, Tuple{}, Vector{Float64}, DimensionalData.NoName, NoMetadata})
    @ DimensionalData ~/projects/DimensionalData.jl/src/array/methods.jl:227
  [8] _cat
    @ ~/projects/DimensionalData.jl/src/array/methods.jl:185 [inlined]
  [9] #cat#153
    @ ./abstractarray.jl:1979 [inlined]
 [10] kwcall(::NamedTuple{(:dims,), Tuple{Tuple{Int64, Int64}}}, ::typeof(cat), ::DimArray{Float64, 1, Tuple{X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}}, Tuple{}, Vector{Float64}, DimensionalData.NoName, NoMetadata}, ::DimArray{Float64, 1, Tuple{X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}}, Tuple{}, Vector{Float64}, DimensionalData.NoName, NoMetadata})
    @ Base ./abstractarray.jl:1979
 [11] top-level scope
    @ REPL[120]:1

julia> cat(parent(x), parent(x); dims=(1, 2))
10×2 Matrix{Float64}:
 -0.0244708   0.0
  0.695667    0.0
 -0.704011    0.0
 -0.71195     0.0
 -0.293832    0.0
  0.0        -0.0244708
  0.0         0.695667
  0.0        -0.704011
  0.0        -0.71195
  0.0        -0.293832

julia> cat(x, x; dims=(1, 2))
ERROR: BoundsError: attempt to access Tuple{X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}} at index [2]
Stacktrace:
  [1] getindex
    @ ./tuple.jl:29 [inlined]
  [2] #8
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:83 [inlined]
  [3] map
    @ ./tuple.jl:273 [inlined]
  [4] _sortdims
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:83 [inlined]
  [5] _dims
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:140 [inlined]
  [6] _call_primitive1
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:592 [inlined]
  [7] _call_primitive1
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:590 [inlined]
  [8] _call_primitive1
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:584 [inlined]
  [9] _call_primitive
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:579 [inlined]
 [10] _call_primitive
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:577 [inlined]
 [11] dims
    @ ~/projects/DimensionalData.jl/src/Dimensions/primitives.jl:138 [inlined]
 [12] #463
    @ ~/projects/DimensionalData.jl/src/array/methods.jl:182 [inlined]
 [13] map
    @ ./tuple.jl:274 [inlined]
 [14] _cat
    @ ~/projects/DimensionalData.jl/src/array/methods.jl:180 [inlined]
 [15] #cat#153
    @ ./abstractarray.jl:1979 [inlined]
 [16] kwcall(::NamedTuple{(:dims,), Tuple{Tuple{Int64, Int64}}}, ::typeof(cat), ::DimArray{Float64, 1, Tuple{X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}}, Tuple{}, Vector{Float64}, DimensionalData.NoName, NoMetadata}, ::DimArray{Float64, 1, Tuple{X{Sampled{Int64, UnitRange{Int64}, ForwardOrdered, Regular{Int64}, Points, NoMetadata}}}, Tuple{}, Vector{Float64}, DimensionalData.NoName, NoMetadata})
    @ Base ./abstractarray.jl:1979
 [17] top-level scope
    @ REPL[124]:1
sethaxen commented 1 year ago

I guess the 2nd one makes sense to not support, though maybe it should instead return a not-DimArray instead of erroring. But the first should work.

rafaqz commented 1 year ago

Hmm yes cat is pretty weird with tuple dims, I'm not sure that has always been possible?

But yes I guess it could just return the parent array type. It could work as a DimArray if the lookups lined up along the diagonal? but maybe not worth writing for such an edge case.