DimensionalData.jl icon indicating copy to clipboard operation
DimensionalData.jl copied to clipboard

Methodcall on `0-dimensional DimArray`

Open haakon-e opened this issue 2 months ago • 4 comments

The following caught me by surprise as I was replacing regular vectors in my code with DD equivalents:

# Normal vectors
y = rand(ComplexF64, 5)
@views abs(y[1])  # Success!

# DD
y_dd = DimArray(y, Y)
@views abs(y_dd[1])
# MethodError: no method matching abs(::DimensionalData.DimArray{ComplexF64, 0, Tuple{}, Tuple{DimensionalData.Dimensions.Y{DimensionalData.Dimensions.Lookups.NoLookup{UnitRange{Int64}}}}, SubArray{ComplexF64, 0, Vector{ComplexF64}, Tuple{Int64}, true}, DimensionalData.NoName, DimensionalData.Dimensions.Lookups.NoMetadata})

# The function `abs` exists, but no method is defined for this combination of argument types.

Essentially, calling abs (possibly other functions too) isn't defined for zero-dimensional DimArrays. The substantial difference between the two examples is that @views y[1] just returns the scalar object, instead of a zero-dimensional vector.

Thoughts? Would I just have to rewrite my code to get around this?


I'm on DimensionalData v0.29.24 (Julia v1.11.6)

haakon-e avatar Sep 20 '25 01:09 haakon-e

~This is definitely a place where DD seems to disagree with Base. Note that integer indexing without views on a dimarray returns a value, whereas views seems to return a 0-dimensional dimarray, meaning this is inconsistent with what happens with Base arrays:~

julia> getindex(y_dd, 1)
0.13711622786404198 + 0.36781650557951606im

julia> view(y_dd, 1)
┌ 0-dimensional DimArray{ComplexF64, 0} ┐
└───────────────────────────────────────┘
0.137116+0.367817im

~Seems to me that we should just return a single value from the view, and be consistent with Base. But what do you think @rafaqz @felixcremer?~

(see next comment)

asinghvi17 avatar Sep 20 '25 07:09 asinghvi17

Come on guys this is too vague to comment on without a computer in front of me.

Please show the comparison between the parent array with view and DD with view and print the output of both.

getindex vs getindex, view vs view. Then we can comment. Probably also view vs @views

Not abs that's a red herring surely the output of indexing is the issue here

rafaqz avatar Sep 20 '25 07:09 rafaqz

The plot thickens:

julia> y = rand(ComplexF64, 5)
5-element Vector{ComplexF64}:
  0.6807954442903817 + 0.4093511152062269im
  0.5971912065930367 + 0.04105202399128616im
  0.9031423268684027 + 0.15138438946867305im
  0.3246991612483626 + 0.8012483098853918im
 0.13479944694846235 + 0.12764571950749004im

julia> getindex(y, 1)
0.6807954442903817 + 0.4093511152062269im

julia> view(y, 1)
0-dimensional view(::Vector{ComplexF64}, 1) with eltype ComplexF64:
0.6807954442903817 + 0.4093511152062269im

julia> @views y[1]
0.6807954442903817 + 0.4093511152062269im

so view seems to be doing different things than @views does.

From its docstring,

Scalar indices, non-array types, and explicit getindex calls (as opposed to
  array[...]) are unaffected.

julia> y_dd = DimArray(y, Y)
┌ 5-element DimArray{ComplexF64, 1} ┐
├───────────────────────────── dims ┤
  ↓ Y
└───────────────────────────────────┘
 0.680795+0.409351im
 0.597191+0.041052im
 0.903142+0.151384im
 0.324699+0.801248im
 0.134799+0.127646im

julia> @views y_dd[1]
┌ 0-dimensional DimArray{ComplexF64, 0} ┐
└───────────────────────────────────────┘
0.680795+0.409351im

this is the divergence from Base.

It seems the @views macro calls into Base.maybeview, for which:

julia> Base.maybeview(y, 1)
0.6807954442903817 + 0.4093511152062269im

julia> Base.maybeview(y_dd, 1)
┌ 0-dimensional DimArray{ComplexF64, 0} ┐
└───────────────────────────────────────┘
0.680795+0.409351im

This is defined in DD https://github.com/rafaqz/DimensionalData.jl/blob/f0fad4c0944c01a74f9bbe05dd8d8a3800bdbaa3/src/array/indexing.jl#L245-L249

so maybe that's just a bug and it should be forwarding to Base.maybeview (or invoking that abstract method, somehow)?

asinghvi17 avatar Sep 20 '25 07:09 asinghvi17

Perfect. Yep looks like a bug in maybeview.

Seems it should unwrap zero dimensional arrays.

rafaqz avatar Sep 21 '25 10:09 rafaqz