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

Conversion to symbolic units doesn't work

Open jkrumbiegel opened this issue 8 months ago • 8 comments

The uexpand docstring states:

Expand the symbolic units in a quantity with symbolic dimensions to their base SI form. In other words, this converts a quantity with AbstractSymbolicDimensions to one with Dimensions. The opposite of this function is uconvert, for converting to specific symbolic units, or, e.g., convert(Quantity{<:Any,<:AbstractSymbolicDimensions}, q), for assuming SI units as the output symbols.

But:

julia> convert(DQ.Quantity{<:Any,<:DQ.AbstractSymbolicDimensions}, DQ.u"kg") |> typeof
DynamicQuantities.Quantity{Float64, DynamicQuantities.Dimensions{DynamicQuantities.FixedRational{Int32, 25200}}}

So the dimensions have not become symbolic, how can I do this?

jkrumbiegel avatar Mar 25 '25 13:03 jkrumbiegel

Argh, sorry this doesn't work. It's bad that the docstring suggestion is broken.

In the meantime, the "standard" way to convert to symbolic units is to use |> us"kg". So for example:

julia> 5u"g" |> us"kg"
0.005 kg

Internally this is calling uconvert

MilesCranmer avatar Mar 25 '25 16:03 MilesCranmer

In my use case I wanted to take in both symbolic and normal quantities and convert them to symbolic. The problem then is that I don't know which symbolic unit to convert to, in your example the unit is known.

jkrumbiegel avatar Mar 25 '25 16:03 jkrumbiegel

Oh I see. I don't have a function for this, because I thought it would never be needed (symbolic units are mainly just for display). Could I ask what the use-case is? Happy to add it, I'm just curious what for

MilesCranmer avatar Mar 25 '25 17:03 MilesCranmer

Actually it seems like this works:

julia> x = 5u"kg"
5.0 kg

julia> convert(Quantity{Float64,SymbolicDimensions}, x) |> typeof
Quantity{Float64, SymbolicDimensions{FixedRational{Int32, 25200}}}

still it would be interesting to know the use-case.

Also I'd like to fix the above issue at some point.

MilesCranmer avatar Mar 25 '25 17:03 MilesCranmer

My usecase was unit support in AlgebraOfGraphics (https://github.com/MakieOrg/AlgebraOfGraphics.jl/pull/619).

Users should be able to pass in arrays with DynamicQuantity units. But they should also be able to override the unit that should be displayed, in both formats, symbolic or not. First I thought I could just uconvert to the user-defined unit, but that errors for non-symbolic units. So for simplicity I thought I'd convert all user override units into symbolic first so that I can call uconvert on them. This led me to the aforementioned problem.

jkrumbiegel avatar Mar 25 '25 18:03 jkrumbiegel

But they should also be able to override the unit that should be displayed, in both formats, symbolic or not

I think the part I'm not understanding here is why converting to symbolic would affect the display. If they are already represented with Dimensions, and you convert to SymbolicDimensions, then that would just give the same exact units but with a different data type. It would print the exact same way though. And whenever mixing it with non-symbolic, it would just immediately promote back to Dimensions.

MilesCranmer avatar Mar 25 '25 21:03 MilesCranmer

It doesn't affect the display, as you say, the non-symbolic units are all using the same base units anyway. For me it would just have been a simpler code path to first convert any override unit to symbolic and then call uconvert(override, data). Now I'm dispatching on the dimensions type parameter and handling the differences manually.

jkrumbiegel avatar Mar 26 '25 08:03 jkrumbiegel

Sorry, I think my brain is a mess this week—I still can't really understand the reasoning. Do you have a specific code example for this? It could be that the explanations are what is tripping me up, but if I see code, I would instantly get it.

MilesCranmer avatar Mar 27 '25 15:03 MilesCranmer