DynamicQuantities.jl v0.7.0: efficient and type-stable physical quantities

Not that MathCad is the authoritative standard (it isn’t, in fact some of its unit handling is just plain wrong by SI standards), but because it is on my computer and I am familiar with it, I took a look at how it handles angles. If you want to try it there is a trial version available that will revert to MathCad Express after 30 days. This will not impact its units handling.

I have much more experience with its units handling than with the Julia packages and found it quite useful. For angles it has degrees, DMS, radian, revolution and steradian as angular units. The DMS is a function that converts the angle to radians and displays it unitless. So it seems it does things similar to DynamicQuantities from what I gather from this post.

The conundrum is that if I have an angle I would like to keep it as an angle but as soon as I multiply it by a radius to get the distance around a circle, I would like it to drop the angle unit and just keep the distance unit.

There is a similar problem with frequency. Frequency is normally given as Hz (cycles/s) rather than rad/s, though the later is more natural unit wise at least in the vibration world where I work.

I wish you the best in sorting this all out and think you have done a good job thinking through the issues.

There is a lot of writing on this topic. I don’t have a summary, but it seems probably worth reviewing what the specialists say.

Comment on ‘Dimensionless units in the SI’

Comment on ‘On the units radian and cycle for the quantity plane angle’

4 Likes

Did you read these, or just found some links from a google search? If you actually read them, a summary would be helpful. (I’m not actively looking to change the definition so have no reason to do a literature review myself)

My main takeaway from skimming these papers is that it’s far from a settled debate. So I’ll stick with 1 rad = 1 in Dimensions for now since it’s what the SI says. If you want to track angles you can use SymbolicDimensions (built-in) or the AngleDimensions from above.

Quick update, I just added AngleDimensions to the docs:

Obviously there’s no solution that will make everybody happy but I think it’s nice to lean into the core language features (like a plain struct for custom dimensions) to let people extend things as they see fit.

6 Likes

Eh, why not… Let’s just have statically-typed units in DynamicQuantities.jl as well!

Obviously it seems to be against the main use-case of the package, but it turned out to be very simple to add this, as you can just rely on the regular AbstractDimensions operations, but in typed space.

For example:

julia> using DynamicQuantities; using DynamicQuantities: StaticDimensions

julia> x = Quantity{Float64,StaticDimensions}(10u"km")
10000.0 m

julia> y = Quantity{Float64,StaticDimensions}(1u"h")
3600.0 s

julia> @inferred x / y
2.7777777777777777 m s⁻¹

julia> typeof(x / y)
Quantity{Float64, StaticDimensions(m s⁻¹::Dimensions{FixedRational{Int32, 25200}})}

So you can see it actually infers the m s⁻¹, just like Unitful.jl would.

It’s probably slow and not as good at inference as Unitful.jl right now. Which is why I would love people’s help in optimizing this!

Once it’s done, it should be very easy to switch back and forth between statically- and dynamically-typed units.

7 Likes

Is there any way we could register units (or even symbolic units) that have offsets, such as

@register_unit °C 1.0u"K" + 273.15

or

@register_unit kPag 1.0u"kPa" + 101.3

If I have this, I can efficiently store and apply arbitrary units in a vector/dictionary to map to any arbitrary process measurement (because a lot of process units have offsets, especially pressure and temperature).

There are no offset units, sorry. I think the maintenance burden of offset units is too high relative to the demand (you are the first to ask) for me to consider putting time into it, as it would require rewriting a lot of stuff. At its core the package is still very simple and lightweight and I’d like to keep it this way to avoid the implementation complexity of Unitful.

But do check out Examples · DynamicQuantities.jl for writing custom dimensions, that might be an option for you.

2 Likes

I definitely wouldn’t recommend having offset units as part of a core type to do actual math on, because it messes up division and even multiplication when not differenced. But would it be hard to extend something like SymbolicUnits to represent something that gets converted to the main Quantity type upon creation and then convert back if desired as output?

Happy to share that DynamicQuantities.jl v1.0.0 is now released! This release is identical to 0.14.3. The v1 simply indicates I consider the API stable.

12 Likes