additional math-functions
Hello, I would like to add several missing math functions in boost or specialize/overload existing ones for more types. These should be constexpr if possible. My problems with the concrete implementations are: - Which C++ standard to use C++11/14/17/20/23 ? - Should these be implemented in ccmath and math ? a) ccmath requires C++17 (eg "if constexpr"), so it is not possible to simply call the ccmath version in math, since math requires C++11. b) On the other hand, the math functions are already included in the standard (since C++11), so it wouldn't be necessary to continue to provide them (especially since they are not constexpr). Where and how exactly and with which C++ standard can I add the functions ? thx Gero
On 10/08/2022 18:09, Gero Peterhoff via Boost wrote:
Hello, I would like to add several missing math functions in boost or specialize/overload existing ones for more types. Which functions? These should be constexpr if possible.
My problems with the concrete implementations are: - Which C++ standard to use C++11/14/17/20/23 ? - Should these be implemented in ccmath and math ? a) ccmath requires C++17 (eg "if constexpr"), so it is not possible to simply call the ccmath version in math, since math requires C++11.
Maybe, but we have announced a move to C++14, and in any case new additions can use whatever std version they require, as long as that requirement is documented and actually needed (ie not just using cool new features "just because"). I do note however, that the constexpr function may not be as efficient *at runtime* as they could be due to the need not to use compiler intrinsics / std lib functions and such (so they should probably be marked as consteval in C++20). So yes, possibly two versions. But it depends what the functions are? Best, John.
b) On the other hand, the math functions are already included in the standard (since C++11), so it wouldn't be necessary to continue to provide them (especially since they are not constexpr).
Where and how exactly and with which C++ standard can I add the functions ?
thx Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Am 10.08.22 um 20:23 schrieb John Maddock via Boost: > On 10/08/2022 18:09, Gero Peterhoff via Boost wrote: >> Hello, >> I would like to add several missing math functions in boost or specialize/overload existing ones for more types. > Which functions? 1) scalar types - isdenormal - trigonometric cot/sec/csc, acot/asec/acsc, acoth/asech/acsch, acot2(like atan2) -> the problem is not the implementation as such, but a standardized error handling - abs/div for unsigned types -> useful/need in templates - inv - sgn (support nan/inf, ±0) - rounding https://en.wikipedia.org/wiki/Rounding#Comparison_of_approaches_for_rounding_to_an_integer 2) std::complex - complete all std-functions for complex - complete all special-functions for complex for the future 3) complex types - dual numbers https://en.wikipedia.org/wiki/Dual_number - split-complex numbers https://en.wikipedia.org/wiki/Split-complex_number 4) logic - a modern constexpr implementation for tribool -> bool3 - bool4 https://en.wikipedia.org/wiki/Four-valued_logic Best, Gero >> These should be constexpr if possible. >> >> My problems with the concrete implementations are: >> - Which C++ standard to use C++11/14/17/20/23 ? >> - Should these be implemented in ccmath and math ? >> a) ccmath requires C++17 (eg "if constexpr"), so it is not possible to simply call the ccmath version in math, since math requires C++11. > > Maybe, but we have announced a move to C++14, and in any case new additions can use whatever std version they require, as long as that requirement is documented and actually needed (ie not just using cool new features "just because"). > > I do note however, that the constexpr function may not be as efficient *at runtime* as they could be due to the need not to use compiler intrinsics / std lib functions and such (so they should probably be marked as consteval in C++20). So yes, possibly two versions. But it depends what the functions are? > > Best, John. > >> b) On the other hand, the math functions are already included in the standard (since C++11), so it wouldn't be necessary to continue to provide them (especially since they are not constexpr). >> >> Where and how exactly and with which C++ standard can I add the functions ? >> >> thx >> Gero >> >> _______________________________________________ >> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost > > > > _______________________________________________ > Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 10/08/2022 21:17, Gero Peterhoff via Boost wrote: > Am 10.08.22 um 20:23 schrieb John Maddock via Boost: >> On 10/08/2022 18:09, Gero Peterhoff via Boost wrote: >>> Hello, >>> I would like to add several missing math functions in boost or >>> specialize/overload existing ones for more types. >> Which functions? > 1) scalar types > - isdenormal OK > - trigonometric cot/sec/csc, acot/asec/acsc, acoth/asech/acsch, > acot2(like atan2) -> the problem is not the implementation as such, > but a standardized error handling Yep, I have wondered about those in the past. > - abs/div for unsigned types -> useful/need in templates Yep. I had to add an "unsigned_abs" function to multiprecision to handle generic abs calls. > - inv > - sgn (support nan/inf, ±0) boost::math::sign should do what you want already. > - rounding > https://en.wikipedia.org/wiki/Rounding#Comparison_of_approaches_for_rounding_to_an_integer Almost a library in it's own right ;) But OK. > > 2) std::complex > - complete all std-functions for complex > - complete all special-functions for complex That's a heck of a lot of work - certainly to get them reliable. Do you want to make a start with some PR's for the low-hanging fruit? Best, John. > > for the future > > 3) complex types > - dual numbers https://en.wikipedia.org/wiki/Dual_number > - split-complex numbers > https://en.wikipedia.org/wiki/Split-complex_number > > 4) logic > - a modern constexpr implementation for tribool -> bool3 > - bool4 https://en.wikipedia.org/wiki/Four-valued_logic > > Best, Gero > >>> These should be constexpr if possible. >>> >>> My problems with the concrete implementations are: >>> - Which C++ standard to use C++11/14/17/20/23 ? >>> - Should these be implemented in ccmath and math ? >>> a) ccmath requires C++17 (eg "if constexpr"), so it is not >>> possible to simply call the ccmath version in math, since math >>> requires C++11. >> >> Maybe, but we have announced a move to C++14, and in any case new >> additions can use whatever std version they require, as long as that >> requirement is documented and actually needed (ie not just using cool >> new features "just because"). >> >> I do note however, that the constexpr function may not be as >> efficient *at runtime* as they could be due to the need not to use >> compiler intrinsics / std lib functions and such (so they should >> probably be marked as consteval in C++20). So yes, possibly two >> versions. But it depends what the functions are? >> >> Best, John. >> >>> b) On the other hand, the math functions are already included in >>> the standard (since C++11), so it wouldn't be necessary to continue >>> to provide them (especially since they are not constexpr). >>> >>> Where and how exactly and with which C++ standard can I add the >>> functions ? >>> >>> thx >>> Gero >>> >>> _______________________________________________ >>> Unsubscribe & other changes: >>> http://lists.boost.org/mailman/listinfo.cgi/boost >> >> >> >> _______________________________________________ >> Unsubscribe & other changes: >> http://lists.boost.org/mailman/listinfo.cgi/boost > > > _______________________________________________ > Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Am 13.08.22 um 10:12 schrieb John Maddock via Boost: > On 10/08/2022 21:17, Gero Peterhoff via Boost wrote: >> Am 10.08.22 um 20:23 schrieb John Maddock via Boost: >>> On 10/08/2022 18:09, Gero Peterhoff via Boost wrote: >>>> Hello, >>>> I would like to add several missing math functions in boost or specialize/overload existing ones for more types. >>> Which functions? >> 1) scalar types >> - isdenormal > > OK > >> - trigonometric cot/sec/csc, acot/asec/acsc, acoth/asech/acsch, acot2(like atan2) -> the problem is not the implementation as such, but a standardized error handling > Yep, I have wondered about those in the past. >> - abs/div for unsigned types -> useful/need in templates > Yep. I had to add an "unsigned_abs" function to multiprecision to handle generic abs calls. >> - inv >> - sgn (support nan/inf, ±0) > boost::math::sign should do what you want already. >> - rounding https://en.wikipedia.org/wiki/Rounding#Comparison_of_approaches_for_rounding_to_an_integer > Almost a library in it's own right ;) But OK. >> >> 2) std::complex >> - complete all std-functions for complex >> - complete all special-functions for complex > > That's a heck of a lot of work - certainly to get them reliable. > > Do you want to make a start with some PR's for the low-hanging fruit? > Yes, that's why I asked which C++ standard can be used. Can I use e.g. - concepts - lambdas - constexpr if ? Best, Gero > Best, John. > >> >> for the future >> >> 3) complex types >> - dual numbers https://en.wikipedia.org/wiki/Dual_number >> - split-complex numbers https://en.wikipedia.org/wiki/Split-complex_number >> >> 4) logic >> - a modern constexpr implementation for tribool -> bool3 >> - bool4 https://en.wikipedia.org/wiki/Four-valued_logic >> >> Best, Gero >> >>>> These should be constexpr if possible. >>>> >>>> My problems with the concrete implementations are: >>>> - Which C++ standard to use C++11/14/17/20/23 ? >>>> - Should these be implemented in ccmath and math ? >>>> a) ccmath requires C++17 (eg "if constexpr"), so it is not possible to simply call the ccmath version in math, since math requires C++11. >>> >>> Maybe, but we have announced a move to C++14, and in any case new additions can use whatever std version they require, as long as that requirement is documented and actually needed (ie not just using cool new features "just because"). >>> >>> I do note however, that the constexpr function may not be as efficient *at runtime* as they could be due to the need not to use compiler intrinsics / std lib functions and such (so they should probably be marked as consteval in C++20). So yes, possibly two versions. But it depends what the functions are? >>> >>> Best, John. >>> >>>> b) On the other hand, the math functions are already included in the standard (since C++11), so it wouldn't be necessary to continue to provide them (especially since they are not constexpr). >>>> >>>> Where and how exactly and with which C++ standard can I add the functions ? >>>> >>>> thx >>>> Gero >>>> >>>> _______________________________________________ >>>> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost >>> >>> >>> >>> _______________________________________________ >>> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost >> >> >> _______________________________________________ >> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost > > > > _______________________________________________ > Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Yes, that's why I asked which C++ standard can be used. Can I use e.g. C++14 unless you can make a really good case why the code needs something else. - concepts I'd prefer not to. - lambdas Yes absolutely. - constexpr if
In constexpr versions of functions yes - the existing ccmath code requires C++17, so you're on safe ground there. For general runtime special functions I'd prefer it if we can all keep to C++14 for the moment so there's not too much divergence between different functions. John.
Hi John, Unfortunately, I encountered a very practical problem when implementing the additional math functions: ccmath cannot be compiled with C++11/14 because C++17 features are used. But this could easily be fixed by just using C++11/14 features and/or BOOST-macros. Example isinf: Original code: template <typename T> inline constexpr bool isinf(T x) { if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) { return x == std::numeric_limits<T>::infinity() || -x == std::numeric_limits<T>::infinity(); } else { using std::isinf; if constexpr (!std::is_integral_v<T>) { return isinf(x); } else { return isinf(static_cast<double>(x)); } } } "std::is_integral_v<T>" and "if constexpr" doesn't work with C++11/14 - Change 1: template <typename T> inline constexpr bool isinf_v1(const T x) noexcept { if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using std::isinf; BOOST_IF_CONSTEXPR (std::is_integral<T>::value) return isinf(static_cast<double>(x)); else return isinf(x); } } But now it is not necessary to check for "std::is_integral<T>", since you can immediately request the Float-type via decltype - change 2: template <typename T> inline constexpr bool isinf_v2(const T x) noexcept { if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using type = decltype(std::sin(T{})); return std::isinf(type(x)); } } But isinf only makes sense with float types, so you only have to check in this case - change 3a: template <typename T> inline constexpr bool isinf_v3a(const T x) noexcept { BOOST_IF_CONSTEXPR (std::is_floating_point<T>::value) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else return false; } However, you may want to explicitly check integer types only after conversion to float - change 3b: template <typename T> inline constexpr bool isinf_v3b(const T x) noexcept { BOOST_IF_CONSTEXPR (std::is_floating_point<T>::value) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using type = decltype(std::sin(T{})); return isinf_v3b(type(x)); } } Which of these variants makes the most sense and can you adapt the other ccmath functions for them? My favorite is 3a; but it must be compilable with C++11/14. I could work around the problem, but that's really ugly and buggy. thx Gero PS with a correctly working ccmath::abs you can also save yourself the check x/-x == limits::infinity(). Am 13.08.22 um 13:58 schrieb John Maddock via Boost:
Yes, that's why I asked which C++ standard can be used. Can I use e.g. C++14 unless you can make a really good case why the code needs something else. - concepts I'd prefer not to. - lambdas Yes absolutely. - constexpr if
In constexpr versions of functions yes - the existing ccmath code requires C++17, so you're on safe ground there. For general runtime special functions I'd prefer it if we can all keep to C++14 for the moment so there's not too much divergence between different functions.
John.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Aug 15, 2022, at 11:12 AM, Gero Peterhoff via Boost
wrote: Hi John, Unfortunately, I encountered a very practical problem when implementing the additional math functions: ccmath cannot be compiled with C++11/14 because C++17 features are used. But this could easily be fixed by just using C++11/14 features and/or BOOST-macros. Example isinf:
Original code:
template <typename T> inline constexpr bool isinf(T x) { if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) { return x == std::numeric_limits<T>::infinity() || -x == std::numeric_limits<T>::infinity(); } else { using std::isinf;
if constexpr (!std::is_integral_v<T>) { return isinf(x); } else { return isinf(static_cast<double>(x)); } } }
"std::is_integral_v<T>" and "if constexpr" doesn't work with C++11/14 - Change 1:
template <typename T> inline constexpr bool isinf_v1(const T x) noexcept { if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using std::isinf;
BOOST_IF_CONSTEXPR (std::is_integral<T>::value) return isinf(static_cast<double>(x)); else return isinf(x); } }
But now it is not necessary to check for "std::is_integral<T>", since you can immediately request the Float-type via decltype - change 2:
template <typename T> inline constexpr bool isinf_v2(const T x) noexcept { if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using type = decltype(std::sin(T{})); return std::isinf(type(x)); } }
But isinf only makes sense with float types, so you only have to check in this case - change 3a:
template <typename T> inline constexpr bool isinf_v3a(const T x) noexcept { BOOST_IF_CONSTEXPR (std::is_floating_point<T>::value) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else return false; }
However, you may want to explicitly check integer types only after conversion to float - change 3b:
template <typename T> inline constexpr bool isinf_v3b(const T x) noexcept { BOOST_IF_CONSTEXPR (std::is_floating_point<T>::value) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using type = decltype(std::sin(T{})); return isinf_v3b(type(x)); } }
Which of these variants makes the most sense and can you adapt the other ccmath functions for them? My favorite is 3a; but it must be compilable with C++11/14. I could work around the problem, but that's really ugly and buggy.
thx Gero
PS with a correctly working ccmath::abs you can also save yourself the check x/-x == limits::infinity().
Am 13.08.22 um 13:58 schrieb John Maddock via Boost:
Yes, that's why I asked which C++ standard can be used. Can I use e.g. C++14 unless you can make a really good case why the code needs something else. - concepts I'd prefer not to. - lambdas Yes absolutely. - constexpr if
In constexpr versions of functions yes - the existing ccmath code requires C++17, so you're on safe ground there. For general runtime special functions I'd prefer it if we can all keep to C++14 for the moment so there's not too much divergence between different functions.
John.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Gero, Some of the checks you will find in the ccmath library seem common sense, but it is implemented to match the C++23 proposal (now standard) for constexpr cmath and cstdlib functionality. We used C++17 throughout to provide a clean solution with a reasonable language standard. If you look at the definition of BOOST_MATH_IS_CONSTANT_EVALUATED we are already using compiler intrinsics to allow this to be used without C++20s std::is_constant_evaluated. For non-trivial functionality C++11 would become extremely difficult to implement. C++14 would require code bloat that we can get around with if constexpr. Feel free to open up PRs and I will review your solutions. Matt
Gero,
Some of the checks you will find in the ccmath library seem common sense, but it is implemented to match the C++23 proposal (now standard) for constexpr cmath and cstdlib functionality. We used C++17 throughout to provide a clean solution with a reasonable language standard. If you look at the definition of BOOST_MATH_IS_CONSTANT_EVALUATED we are already using compiler intrinsics to allow this to be used without C++20s std::is_constant_evaluated. For non-trivial functionality C++11 would become extremely difficult to implement. C++14 would require code bloat that we can get around with if constexpr. Feel free to open up PRs and I will review your solutions.
Matt
Hello Matt, Hello John, I wrote that it is possible to define workarounds. This even works with C++11 without having to fiddle on ccmath. But for that I need a few #define and the code has to be C++11-compatible (single return statement). In this way, constexpr boost::math functions can already be implemented if the compiler supports it. I have implemented a few functions for testing and would like to ask whether I can implement the remaining functions in this way. If this is not ok, please let me know exactly under which conditions this would have to be done. https://godbolt.org/z/oM8eT5qoj thx Gero
On Aug 17, 2022, at 12:29 PM, Gero Peterhoff via Boost
wrote: Gero,
Some of the checks you will find in the ccmath library seem common sense, but it is implemented to match the C++23 proposal (now standard) for constexpr cmath and cstdlib functionality. We used C++17 throughout to provide a clean solution with a reasonable language standard. If you look at the definition of BOOST_MATH_IS_CONSTANT_EVALUATED we are already using compiler intrinsics to allow this to be used without C++20s std::is_constant_evaluated. For non-trivial functionality C++11 would become extremely difficult to implement. C++14 would require code bloat that we can get around with if constexpr. Feel free to open up PRs and I will review your solutions.
Matt
Hello Matt, Hello John, I wrote that it is possible to define workarounds. This even works with C++11 without having to fiddle on ccmath. But for that I need a few #define and the code has to be C++11-compatible (single return statement). In this way, constexpr boost::math functions can already be implemented if the compiler supports it. I have implemented a few functions for testing and would like to ask whether I can implement the remaining functions in this way. If this is not ok, please let me know exactly under which conditions this would have to be done. https://godbolt.org/z/oM8eT5qoj
thx Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Gero, No issues with any improvement that would allow any of the functions to be used in a constexpr context if available. Feel free to submit your PRs here: https://github.com/boostorg/math/pulls. One thing to note in your example is the inclusion of several other boost headers. About a year ago we first introduced a standalone math module that has zero internal boost dependencies. MSVC has since incorporated this into their implementation of the STL for the math special functions. I can help you workaround the need for boost components. Matt
On 8/10/22 22:17, Gero Peterhoff via Boost wrote:
3) complex types - dual numbers https://en.wikipedia.org/wiki/Dual_number
Something like this already exists as fvar in the math::differentiation namespace. However, dual numbers can also be used for other purposes, so a dedicated dual number class could be an advantage.
participants (4)
-
Bjorn Reese
-
Gero Peterhoff
-
John Maddock
-
Proton