JuliaPhysics / JuliaPhysics/Unitful.jl

Unexpected Errors using 'prod()' when specifying 'dims = _' argument on matrices of Unitful values

Open
#702 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
675
Forks
124
Avg merge
3h 38m
Merged PRs (30d)
1

Description

Hello,

today I observed a couple of unexpected behaviours using the `Unitful.jl` package - I'm not sure what to make of them, since it is quite easy to work around the errors as seen in the MWE below. Nevertheless, I thought it would still be worth sharing.

I have included the stack traces below the MWE for both the `DimensionError` and the `ArgumentError`.

In the case of the `DimensionError`, this seems on the surface to be similar to #585.

In the case of the `ArgumentError`, I'm confused at this behaviour and I haven't seen anything similar in the other issues (I might have missed something, though).

Thanks for your time.

J

----
MWE

```
using Unitful

A = [1 2; 3 4]

prod(A) # 24
A[1, :] .* A[2, :] # [3, 8]
prod(A; dims = 1) # [3, 8]

B = A .* u"m"

prod(B) # 24 m⁴
B[1, :] .* B[2, :] # [3 m², 8 m²]
prod(B; dims = 1) # DimensionError: and m² are not dimensionally compatible.

C = A .* [u"m" u"m"; u"kg" u"kg"]

prod(C) # 24 kg² m²
C[1, :] .* C[2, :] # [3 kg m, 8 kg m]
prod(C; dims = 1) # ArgumentError: zero(Quantity{Int64}) not defined.

```
----
Version information

Unitful:
```
Status `~/.julia/environments/v1.9/Project.toml`
[1986cc42] Unitful v1.19.0

julia> versioninfo()
Julia Version 1.9.4
Commit 8e5136fa297 (2023-11-14 08:46 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: macOS (x86_64-apple-darwin22.4.0)
CPU: 4 × Intel(R) Core(TM) i5-5250U CPU @ 1.60GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-14.0.6 (ORCJIT, broadwell)
Threads: 1 on 4 virtual cores
Environment:
JULIA_EDITOR = code
JULIA_NUM_THREADS =
```
----

Stacktraces

`DimensionError`
```
ERROR: DimensionError: and m² are not dimensionally compatible.
Stacktrace:
[1] #s103#141
@ ~/.julia/packages/Unitful/R4J37/src/conversion.jl:7 [inlined]
[2] var"#s103#141"(::Any, s::Any, t::Any)
@ Unitful ./none:0
[3] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any})
@ Core ./boot.jl:602
[4] uconvert(a::Unitful.FreeUnits{(), NoDims, nothing}, x::Quantity{Int64, 𝐋², Unitful.FreeUnits{(m²,), 𝐋², nothing}})
@ Unitful ~/.julia/packages/Unitful/R4J37/src/conversion.jl:72
[5] convert(#unused#::Type{Int64}, y::Quantity{Int64, 𝐋², Unitful.FreeUnits{(m²,), 𝐋², nothing}})
@ Unitful ~/.julia/packages/Unitful/R4J37/src/conversion.jl:139
[6] setindex!
@ ./array.jl:971 [inlined]
[7] setindex!
@ ./multidimensional.jl:670 [inlined]
[8] _mapreducedim!(f::typeof(identity), op::typeof(Base.mul_prod), R::Matrix{Int64}, A::Matrix{Quantity{Int64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}})
@ Base ./reducedim.jl:311
[9] mapreducedim!(f::Function, op::Function, R::Matrix{Int64}, A::Matrix{Quantity{Int64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}})
@ Base ./reducedim.jl:324
[10] _mapreduce_dim(f::Function, op::Function, #unused#::Base._InitialValue, A::Matrix{Quantity{Int64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}, dims::Int64)
@ Base ./reducedim.jl:371
[11] #mapreduce#801
@ ./reducedim.jl:357 [inlined]
[12] mapreduce
@ ./reducedim.jl:357 [inlined]
[13] #_prod#839
@ ./reducedim.jl:1023 [inlined]
[14] _prod
@ ./reducedim.jl:1023 [inlined]
[15] #_prod#838
@ ./reducedim.jl:1022 [inlined]
[16] _prod
@ ./reducedim.jl:1022 [inlined]
[17] #prod#812
@ ./reducedim.jl:994 [inlined]
[18] top-level scope
```

`ArgumentError`
```
ERROR: ArgumentError: zero(Quantity{Int64}) not defined.
Stacktrace:
[1] zero(x::Type{Quantity{Int64}})
@ Unitful ~/.julia/packages/Unitful/R4J37/src/quantities.jl:363
[2] _reducedim_init(f::typeof(identity), op::typeof(Base.mul_prod), fv::typeof(one), fop::typeof(prod), A::Matrix{Quantity{Int64}}, region::Int64)
@ Base ./reducedim.jl:116
[3] reducedim_init(f::Function, op::typeof(Base.mul_prod), A::Matrix{Quantity{Int64}}, region::Int64)
@ Base ./reducedim.jl:111
[4] _mapreduce_dim(f::Function, op::Function, #unused#::Base._InitialValue, A::Matrix{Quantity{Int64}}, dims::Int64)
@ Base ./reducedim.jl:371
[5] #mapreduce#801
@ ./reducedim.jl:357 [inlined]
[6] mapreduce
@ ./reducedim.jl:357 [inlined]
[7] #_prod#839
@ ./reducedim.jl:1023 [inlined]
[8] _prod
@ ./reducedim.jl:1023 [inlined]
[9] #_prod#838
@ ./reducedim.jl:1022 [inlined]
[10] _prod
@ ./reducedim.jl:1022 [inlined]
[11] #prod#812
@ ./reducedim.jl:994 [inlined]
[12] top-level scope
```
----

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by running the MWE with Julia 1.9.4 and Unitful 1.19.0. Trace the calls through Base's reducedim.jl and the Unitful locations shown in conversion.jl and quantities.jl:363. Done means the two prod(B; dims = 1) cases no longer produce the reported errors and retain the expected values and units.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.