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

Write a paper on a "number" concept #28

Closed
mpusz opened this issue Nov 8, 2019 · 7 comments
Closed

Write a paper on a "number" concept #28

mpusz opened this issue Nov 8, 2019 · 7 comments
Labels
help wanted Extra attention is needed iso The ISO C++ Committee related work
Milestone

Comments

@mpusz
Copy link
Owner

mpusz commented Nov 8, 2019

As a dependency to this project we need a "number" concept. By this I do not mean exactly this name or a concept that have all the constraints in one place. It might be divided to smaller concepts but as an aggregate should at least satisfy something along:

template<typename T>
concept number-ish = std::regular<T> &&
    std::totally_ordered<T> &&
    requires(T a, T b) {
      { a + b } -> std::same_as<T>;
      { a - b } -> std::same_as<T>;
      { a * b } -> std::same_as<T>;
      { a / b } -> std::same_as<T>;
      { +a } -> std::same_as<T>;
      { -a } -> std::same_as<T>;
      { a += b } -> std::same_as<T&>;
      { a -= b } -> std::same_as<T&>;
      { a *= b } -> std::same_as<T&>;
      { a /= b } -> std::same_as<T&>;
      { T{0} };
};

The above definition is probably wrong. For some operations we should not verify the return type (a * b might yield a different type than a / b). We also did not account here for %, ++v, v++ operations that work on integral types but not on a floating-point.

@mpusz mpusz added help wanted Extra attention is needed iso The ISO C++ Committee related work labels Nov 8, 2019
@mpusz mpusz added this to the ISO C++ Prague 2019 milestone Nov 8, 2019
@johnmcfarlane
Copy link

johnmcfarlane commented Nov 8, 2019 via email

@mpusz
Copy link
Owner Author

mpusz commented Nov 9, 2019

Thanks John, this an interesting idea. However, I wouldn't like users to be forced to partially specialize std::numeric_limits for their types to add this support. Even if they will do that, numeric_limits does not guarantee us the availability of arithmetic operators so things like:

quantity<metre, MyRep> d1(MyRep{1});
quantity<metre, MyRep> d2(MyRep{2});
auto d = d1 + d2;

may not compile with instantiation errors inside the library implementation rather than by constraints check for template arguments.

This is why I believe that we should try with the above idea for a concept. It does not have to be named Number. It might be any of:

  • std::number
  • std::arithmetic
  • std::integral
  • std::floating_point
  • std::integral_arithmetic
  • std::floating_point_arithmetic

or whatever SG6 experts will decide to be viable here.

Please also note that Physical Units Library is not the only customer for such a concept. Many other libraries and utilities might benefit from it (i.e. Linear Algebra).

I am really open for feedback and am actively looking for experts' help here.

@mpusz
Copy link
Owner Author

mpusz commented Nov 9, 2019

BTW, before someone will raise it, please do not discuss here if it is sane for it to be a concept or not as the need for it does not come directly for algorithms. I will provide a dedicated policy paper on this and we will discuss this in Prague.

Please, just scope help to make this concept(s) as good and as good for the generic usage as only possible.

@mpusz mpusz changed the title Write a paper on a std::number concept Write a paper on a "number" concept Nov 9, 2019
@mpusz
Copy link
Owner Author

mpusz commented Nov 9, 2019

One more important design point to mention here. The C++ concepts are able to verify syntactic requirements only. They cannot verify semantics by themselves. This is why we should include all possible operations in requires expression constraints. Things like numeric_limits and other traits are more about semantic requirements and I am not sure if they should be included in concepts. If yes, then only as an addition to a full set of syntactic ones.

@kwikius
Copy link
Contributor

kwikius commented Nov 23, 2019

Here are some thoughts on a Number concept for a physical quantity valuetype of type T

In quantity<u,T>

https://en.wikipedia.org/wiki/Magnitude_(mathematics)
Magnitude of the quantity

https://en.wikipedia.org/wiki/Scalar
Scalar<T>

https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics)
not Vector<T>

https://en.wikipedia.org/wiki/Real_number
RealNumber<T>

https://en.wikipedia.org/wiki/Dimensionless_quantity
Dimensionless_Quantity<T>

A related issue is where one might want to use physical quantity as valuetype:

complex<Quantity> or Quantity<unit,complex>
quaternion<Quantity> or Quantity<unit,quaternion>

(Personally prefer complex<Quantity> , quaternion<\Quantity>
https://github.com/kwikius/quan-trunk/blob/master/quan/complex/complex.hpp
https://github.com/kwikius/quan-trunk/blob/master/quan/three_d/quat_def.hpp
https://github.com/kwikius/quan-trunk/blob/master/quan/three_d/quat.hpp

Have also found Quantity<unit, Angle> useful mainly for per_second per_second_squared type quantities

eg
radians per second
degrees per second
revolutions per minute

https://github.com/kwikius/quan-trunk/blob/master/quan_matters/examples/angles2.cpp#L32

@kwikius
Copy link
Contributor

kwikius commented Dec 13, 2019

Some thoughts related to ops on Quantities with other types
Want generic as possible binary operations but avoiding ambiguous overloads

Take 2 types Q1, T2 where for example Q1 is a Quantity

Usual issue is multiplicative op { *, /}

Q1 op T2

I think there are specifically 3 cases generally in multiplication/division

  1. T2 is in same universe . eg T2 is a Quantity. ( Same universe but maybe different dimension)

  2. T2 is in lower universe e.g T2 is a Numeric

  3. T2 is in higher universe eg T2 is a 3dvector, matrix etc.

Maybe there is an order that Universe<T1> <= Universe<T2> ?
N.B If there is no ordering between the universes then the operation is not possible
N.B that the result Type is irrelevant for overload resolution ( e.g if result Q/Q is dimensionlesss etc)

@mpusz
Copy link
Owner Author

mpusz commented Dec 17, 2019

It seems it is impossible to define one number concept. This is why I decided to go with P1813.

Maybe only something like this will be discussed in the SG6 numerics group:

template<typename T, typename U = T>
concept basic_arithmetic =
    std::magma<std::ranges::plus, T, U> &&
    std::magma<std::ranges::minus, T, U> &&
    std::magma<std::ranges::times, T, U> &&
    std::magma<std::ranges::divided_by, T, U>;

but time will tell...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed iso The ISO C++ Committee related work
Projects
None yet
Development

No branches or pull requests

3 participants