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

feat: negative constants #510

Open
JohelEGP opened this issue Oct 24, 2023 · 12 comments
Open

feat: negative constants #510

JohelEGP opened this issue Oct 24, 2023 · 12 comments
Labels
design Design-related discussion enhancement New feature or request

Comments

@JohelEGP
Copy link
Collaborator

JohelEGP commented Oct 24, 2023

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):

inline constexpr struct helion_g_factor :
  named_unit<basic_symbol_text{"𝘨ₕ", "g_h"}, mag<-ratio{4'255'250'615, 1'000'000'000}> * one> {} helion_g_factor;
<source>:7:46: error: use of invalid variable template 'mag<mp_units::ratio{-851050123, 200000000}>'
    7 |   named_unit<basic_symbol_text{"𝘨ₕ", "g_h"}, mag<-ratio{4'255'250'615, 1'000'000'000}> * one> {} helion_g_factor;
      |                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:7:46: note: constraints not satisfied
In file included from /opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/bits/expression_template.h:25,
                 from /opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/bits/dimension_concepts.h:25,
                 from /opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/quantity.h:26,
                 from /opt/compiler-explorer/libs/mp-units/trunk/src/systems/si/include/mp-units/systems/si/constants.h:25,
                 from /opt/compiler-explorer/libs/mp-units/trunk/src/systems/si/include/mp-units/systems/si/si.h:25,
                 from <source>:1:
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/bits/external/math_concepts.h: In substitution of 'template<mp_units::ratio R>  requires  gt_zero<(long int)((const mp_units::ratio)R).num> constexpr const auto [requires mp_units::Magnitude<<placeholder>, >] mp_units::mag<R> [with mp_units::ratio R = mp_units::ratio{-851050123, 200000000}]':
<source>:7:51:   required from here
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/bits/external/math_concepts.h:30:9:   required for the satisfaction of 'gt_zero<((const mp_units::ratio)R).num>' [with R = _ZTAXtlN8mp_units5ratioELln851050123ELl200000000EEE]
/opt/compiler-explorer/libs/mp-units/trunk/src/core/include/mp-units/bits/external/math_concepts.h:30:22: note: the expression 'N > 0 [with N = (long int)_ZTAXtlN8mp_units5ratioELln851050123ELl200000000EEE.mp_units::ratio::num]' evaluated to 'false'
   30 | concept gt_zero = (N > 0);
      |                   ~~~^~~~
<source>:7:93: error: template argument 2 is invalid
    7 |   named_unit<basic_symbol_text{"𝘨ₕ", "g_h"}, mag<-ratio{4'255'250'615, 1'000'000'000}> * one> {} helion_g_factor;
      |                                                                                             ^
Compiler returned: 1
@JohelEGP
Copy link
Collaborator Author

@mpusz
Copy link
Owner

mpusz commented Oct 25, 2023

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?

@mpusz
Copy link
Owner

mpusz commented Oct 25, 2023

BTW, I was not aware of CODATA. Maybe we should add most/all of those constants to the library as well?

@mpusz
Copy link
Owner

mpusz commented Oct 25, 2023

Some constants use uncertainty. We could extend #464 with those use cases.

@mpusz mpusz added enhancement New feature or request design Design-related discussion labels Oct 25, 2023
@chiphogg
Copy link
Collaborator

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.

  1. A constant is simply a unit.
  2. A unit's "size" is fully specified by its magnitude.
  3. A magnitude is a positive real number.

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.

@JohelEGP
Copy link
Collaborator Author

JohelEGP commented Oct 26, 2023

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.

@mpusz
Copy link
Owner

mpusz commented Oct 26, 2023

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.

@JohelEGP
Copy link
Collaborator Author

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.

@JohelEGP
Copy link
Collaborator Author

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.

@chiphogg
Copy link
Collaborator

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.

@JohelEGP
Copy link
Collaborator Author

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?

@chiphogg
Copy link
Collaborator

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Design-related discussion enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants