Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify concepts and casting rules of quantity kinds and types #567

Closed
burnpanck opened this issue May 10, 2024 · 6 comments
Closed

Clarify concepts and casting rules of quantity kinds and types #567

burnpanck opened this issue May 10, 2024 · 6 comments

Comments

@burnpanck
Copy link
Contributor

burnpanck commented May 10, 2024

I'm finally refactoring our production code to units v2. Unfortunately, I have lost track of the previous discussion over interconvertibility of quantity kinds. There were concepts "quantity kind" and "quantity type", and potential hierarchies of those, but I currently fail to understand to what rules the library has settled.

The specific case where I was wondering this was here: In our code, we mostly use untyped quantities, with the exception of two custom quantity types. One of them is an inverse duration (dimension T^-1). Our embedded system measures statistical properties of the separatioon of events happening repeatedly (not related to radionucleides), and so we invented a new quantity type for quantities related to the "frequency" of those events - as in the statistician's sense of frequency, not the one from the ISQ. However, now I'm struggling to properly cast the measured values based on a real ISQ frequency and a count to that custom quantity-type: quantity_cast refuses the cast because hertz is associated with a quantity-type of it's own, but not related to our own event "frequency" type. So basically it seems that quantity_cast currently prohibits "horizontal casts". Is this intended?

I had declared that "frequency" type to be of inverse duration, rather than a refinement of frequency, because it seems that the library currently disallows restricting units to anything else than the "root of a kind-tree" (?). It is not entirely clear to me what that would be, or why there would be a need for such a restriction. If that restriction weren't there, then those casts would be "vertical".

@mpusz
Copy link
Owner

mpusz commented May 10, 2024

@burnpanck, it is great to hear that you are moving to V2.

Unfortunately, it is hard for me to understand your use case without a concrete code example, so maybe you could provide a simplified example in the Compiler Explorer? Also, maybe this example will help you: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3045r0.html#user-defined-quantities-and-units.

@mpusz
Copy link
Owner

mpusz commented May 10, 2024

Regarding Hz, here is the rationale for constraining it to frequency:

https://mpusz.github.io/mp-units/latest/users_guide/framework_basics/systems_of_units/#constraining-a-derived-unit-to-work-only-with-a-specific-derived-quantity

Although, indeed, "periodic phenomena" might not necessarily imply frequency. However, there is no "periodic phenomena" quantity type in ISQ.

@burnpanck
Copy link
Contributor Author

burnpanck commented May 10, 2024

I'm fine with the current choice and rationale of constraining Hz to frequency. In our use-case, we have something similar to the quantity type Tempo in P3045 example (let's call it BeatRate for this discussion), with a corresponding bpm unit. The P3045 example defines Tempo in terms of a custom kind Beat, whereas we defined it directly as a custom kind of inverse time (exactly by QUANTITY_SPEC(BeatRate, inverse(duration)). I believe the difference is immaterial (though I may be wrong). Ultimately, what failed is quantity_cast<BeatRate>(q), where q is expressed in Hz. I was further suggesting that the cast would have passed through if we had done QUANTITY_SPEC(BeatRate, frequency) instead, but then the unit definition fails, apparently because BeatRate isn't "at the root of a kind hierarchy" (?):

inline constexpr struct BeatsPerMinute : named_unit<"bpm", one/minute, kind_of<BeatRate>> {} BeatsPerMinute;

As I write this however I notice the is_kind in your example's definition of Beat, which most likely is absent from our QUANTITY_SPEC(BeatRate,...).

So ultimately, I think the library users would benefit from rigorous description of the concept of "kind". Can we now use a mental model of a hierarchy of quantity types? What does the is_kind in a quantity specification do exactly in terms of that hierarchy? Which nodes of the hierarchy are allowed as an argument of kind_of<...> inside a unit definition?

@mpusz
Copy link
Owner

mpusz commented May 10, 2024

https://mpusz.github.io/mp-units/latest/users_guide/framework_basics/dimensionless_quantities/#nested-quantity-kinds ;-)

@mpusz
Copy link
Owner

mpusz commented May 13, 2024

@burnpanck, do you need any more support here, or can we close that one?

@burnpanck
Copy link
Contributor Author

I am good, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants