Open JohelEGP opened 1 year ago
Good catch @JohelEGP. It seems that negative magnitudes have sense after all :-)
@chiphogg, could you please check how to address that? Is the removal of gt_zero
constraints enough? Maybe we should leave non_zero
there?
BTW, I was not aware of CODATA. Maybe we should add most/all of those constants to the library as well?
Some constants use uncertainty. We could extend #464 with those use cases.
A magnitude (whether represented via vector spaces, or some imagined future alternative) is a positive real number. I think it's too hasty to say that negative magnitudes make sense: I'm confident they don't. For example, I expect that magnitude logarithms will be critical for implementing logarithmic units such as decibels, but negative numbers do not have logarithms.
In mp-units, a constant is just a unit. Do "negative units" make sense? Am I "-73 neginches" tall? Are we sure we want this?
Negative constants exist, and we should support them, but it's not clear to me yet how to do that without overly complicating other abstractions. If we want to support them, it seems not all of the following can be true simultaneously.
I think changing 3 would be a huge mistake. I could see some sense in changing 2 by adding a sign parameter to the unit definition, but I really don't want to rush into allowing negative units without thinking it through carefully. (Note that this caution around negative units also reinforces the desire to avoid changing 3, which would also effectively give us negative units.)
Ultimately, a constant is conceptually a quantity, and quantities can be negative if their values are negative. Many times, we can treat that quantity as a unit, but I think negative quantities complicate that idea: is the "unit" the quantity itself, or its (absolute) magnitude?
One other advantage to changing 1 would be the opportunity to represent uncertainty, which is worth pondering.
In any case... I think the main takeaway is that this seems like a significant challenge case, and one where we really don't want to rush into committing to a solution without considering very carefully.
The problem is using the unit abstraction for constants. Non-base units carry numbers in its magnitude, which must be non-negative by definition.
I can't find any provision that a chosen reference quantity, the unit, must be non-negative. https://jcgm.bipm.org/vim/en/1.9.html simply defines "measurement unit" as
real scalar quantity, defined and adopted by convention, with which any other quantity of the same kind can be compared to express the ratio of the two quantities as a number
I think that'd be a better reference for P2982R0, which says in 6.5.3 Characters donβt apply to dimensions and units,
[ISO/IEC 80000] [...] explicitly states that:
All units are scalars.
That's in the context of ISO 80000-2:2019 "18 Scalars, vectors and tensors".
Instead of treating each coordinate of a vector as a physical quantity value (i.e. a number multiplied by a unit), the vector could be written as a numerical vector multiplied by a unit. All units are scalars. EXAMPLE Force acting on a given particle, e.g. in Cartesian components (Fx; Fy; Fz) = (β31,5; 43,2; 17,0) N.
It doesn't read like a requirement, but as a fact. So it'd be better to reference the definition of unit.
I am puzzled now, and I don't really know how to proceed here. We could consider add some structural-type like quantity_constant<Quantity>
that would take a compile-time known quantity (similarly to relative_point_origin
). This could take any quantity as a constant (even a negative one) but this would not provide any automated unit simplification as this is not a unit :-(.
Please let me know if you have some ideas.
I can't find any provision that a chosen reference quantity, the unit, must be non-negative.
It must be in the definition of quantity (https://jcgm.bipm.org/vim/en/1.1.html):
property of a phenomenon, body, or substance, where the property has a magnitude that can be expressed as a number and a reference
Which would imply that units are non-negative. It checks out ISO 80000-1:2022 "4.1 The concept of quantity", which mentions
It is customary to use the same term, "quantity", to refer to both general quantities, such as length, mass, etc., and their instances, such as given lengths, given masses, etc. Accordingly, we are used to saying both that length is a quantity and that a given length is a quantity, by maintaining the specification β "general quantity, Q" or "individual quantity, Qa" β implicit and exploiting the linguistic context to remove the ambiguity.
So quantity is defined as a magnitude. And the context can imply a quantity as a vector. This is what I was assuming when I thought that units could be non-negative.
I can't find any provision that a chosen reference quantity, the unit, must be non-negative.
It must be in the definition of quantity (https://jcgm.bipm.org/vim/en/1.1.html):
property of a phenomenon, body, or substance, where the property has a magnitude that can be expressed as a number and a reference
Which would imply that units are non-negative.
It's also true that a number can be negative. And that a negative quantity has a magnitude. So I'm not totally sure that this means that units must be non-negative.
If we can't find a clear answer from the definition as to whether units can be negative, then we should reach out to leading experts in the field to clarify. It's quite possible that they never mentioned it because it never occurred to them that somebody might try defining a negative unit.
I considered that. I was hoping @mpusz would do that.
I also tried checking if some truths still hold. A quantity with a negative unit still forms a vector space. Anything else comes to mind that might not work given negative units?
Good point about the vector space.
I can't think of anything that wouldn't "work" per se, I just think from a practical perspective it's likely to be full of gotchas and surprises.
On the other hand, it probably wouldn't have any effect on people who don't use negative constants. And, it probably would be possible to replace magnitudes with something that is, essentially, "magnitude and a sign bit" (although I think we'd want to come up with a different name).
We'll probably want to tread carefully and solicit expert opinion, but who knows --- maybe this could work!
Let's provide a new thing called constant
that will still satisfy a Unit
concept but will allow negative magnitude in its definition. named_unit
will be constrained to require positive magnitude.
@chiphogg, how do you like this solution?
My initial reaction is that I like it!
Au has Constant
as a separate thing compared to "unit": a constant is templated on a unit. I like the conceptual separation. And Constant
would give us a place to "hang" a negative value (it could be a simple bool
template parameter) without forcing us to try to support "negative units".
Sure, but I think that I would prefer to be able to do mag<-1>
there over some bool flag.
I'm wary of changing the core semantics of magnitude away from "a positive real number". Making it "a nonzero real number" would put a hole in the middle (0), and contradicts how most people generally think of a "magnitude". Plus, this would automatically open the door to negative units, which I had thought was what we were trying to avoid (although re-reading your previous comment makes me think I was wrong about this).
I do see the appeal of being able to write it the same way as for other numbers, but I don't think it's worth the cost of complicating our reasoning about magnitudes.
Now that I read more carefully, I'm not sure I would want a constant to satisfy the unit concept. Maybe it's the other way around? :thinking:
What about introducing an abstraction for declaring negative constants?
inline constexpr struct helion_g_factor_magnitude :
named_unit<basic_symbol_text{"π¨β", "g_h"}, mag<ratio{4'255'250'615, 1'000'000'000}> * one> {} helion_g_factor_magnitude;
inline constexpr struct helion_g_factor : /* ??? */ {} helion_g_factor;
So doing 1 * helion_g_factor
creates a negative quantity.
So basically, "solve for /* ??? */
? I like it. We can bikeshed what the /* ??? */
would look like, but I'm sure there are many reasonable choices that would look good.
ISO 80000-1 Β§A.4 "Constants" references CODATA: https://physics.nist.gov/cuu/Constants/. It lists fundamental constants, including some negative ones. Browse to "All values (ascii)", search for
-
, and see some under the column "Value" being highlighted as negative. One such constant is helion g factor, which is rejected for being negative (https://godbolt.org/z/vao9PKv3s):