SymbolicML / DynamicQuantities.jl

Efficient and type-stable physical quantities in Julia
https://symbolicml.org/DynamicQuantities.jl/dev/
Apache License 2.0
132 stars 17 forks source link

`reduce(vcat` returns corrupted result #93

Closed jkrumbiegel closed 10 months ago

jkrumbiegel commented 10 months ago

Something weird happens to the units in the reduce(vcat version, you can see already in the printout that the values differ. 1.0 hr vs (1.0 ) hr. I only noticed this later though, because uexpand then throws an error on these values.

julia> using DynamicQuantities

julia> arr1 = QuantityArray([us"hr"])
1-element QuantityArray(::Vector{Float64}, ::DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}):
 1.0 hr

julia> arr2 = QuantityArray([us"hr"])
1-element QuantityArray(::Vector{Float64}, ::DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}):
 1.0 hr

julia> arr3 = vcat(arr1, arr2)
2-element QuantityArray(::Vector{Float64}, ::DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}):
 1.0 hr
 1.0 hr

julia> DynamicQuantities.uexpand(arr3)
2-element QuantityArray(::Vector{Float64}, ::DynamicQuantities.Quantity{Float64, Dimensions{DynamicQuantities.FixedRational{Int32, 25200}}}):
 3600.0 s
 3600.0 s

julia> arr4 = reduce(vcat, [arr1, arr2])
2-element QuantityArray(::Vector{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}}, ::DynamicQuantities.Quantity{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}):
 (1.0 ) hr
 (1.0 ) hr

julia> DynamicQuantities.uexpand(arr4)
ERROR: MethodError: no method matching unsafe_fixed_rational(::DynamicQuantities.Quantity{Int32, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, ::Type{Int32}, ::Val{25200})

Closest candidates are:
  unsafe_fixed_rational(::Integer, ::Type{T}, ::Val{den}) where {T, den}
   @ DynamicQuantities ~/.julia/packages/DynamicQuantities/kwSjp/src/fixed_rational.jl:15

Stacktrace:
  [1] tryrationalize(#unused#::Type{DynamicQuantities.FixedRational{Int32, 25200}}, x::DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}})
    @ DynamicQuantities ~/.julia/packages/DynamicQuantities/kwSjp/src/fixed_rational.jl:116
  [2] _pow(l::DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, r::DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}})
    @ DynamicQuantities ~/.julia/packages/DynamicQuantities/kwSjp/src/math.jl:119
  [3] ^(l::DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, r::DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}})
    @ DynamicQuantities ~/.julia/packages/DynamicQuantities/kwSjp/src/math.jl:127
  [4] _pow(l::DynamicQuantities.Quantity{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, Dimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, r::DynamicQuantities.FixedRational{Int32, 25200})
    @ DynamicQuantities ~/.julia/packages/DynamicQuantities/kwSjp/src/math.jl:122
  [5] ^(l::DynamicQuantities.Quantity{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, Dimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, r::DynamicQuantities.FixedRational{Int32, 25200})
    @ DynamicQuantities ~/.julia/packages/DynamicQuantities/kwSjp/src/math.jl:127
  [6] convert(#unused#::Type{DynamicQuantities.Quantity{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, Dimensions{DynamicQuantities.FixedRational{Int32, 25200}}}}, q::DynamicQuantities.Quantity{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}})
    @ DynamicQuantities ~/.julia/packages/DynamicQuantities/kwSjp/src/symbolic_dimensions.jl:94
  [7] uexpand
    @ ~/.julia/packages/DynamicQuantities/kwSjp/src/symbolic_dimensions.jl:113 [inlined]
  [8] materialize_first
    @ ~/.julia/packages/DynamicQuantities/kwSjp/src/arrays.jl:177 [inlined]
  [9] similar
    @ ~/.julia/packages/DynamicQuantities/kwSjp/src/arrays.jl:161 [inlined]
 [10] similar
    @ ~/.julia/packages/DynamicQuantities/kwSjp/src/arrays.jl:160 [inlined]
 [11] copy
    @ ./broadcast.jl:898 [inlined]
 [12] materialize
    @ ./broadcast.jl:873 [inlined]
 [13] uexpand(q::QuantityArray{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, 1, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}, DynamicQuantities.Quantity{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}, Vector{DynamicQuantities.Quantity{Float64, SymbolicDimensions{DynamicQuantities.FixedRational{Int32, 25200}}}}})
    @ DynamicQuantities ~/.julia/packages/DynamicQuantities/kwSjp/src/symbolic_dimensions.jl:115
 [14] top-level scope
    @ REPL[63]:1

This was run on [06fc5a27] DynamicQuantities v0.10.0

MilesCranmer commented 10 months ago

Weird. I think we need an automatic way to go from

QuantityArray(::Vector{<:DynamicQuantities.Quantity})

back to a regular quantity array. Which should happen but for some reason it's not.