Re: [boost] about boost::math

a) __STDCPP_FLOAT80_T__ With C++23 we get std::floatN_t-types, which are displayed by the macros __STDCPP_FLOATn_T__. However I miss __STDCPP_FLOAT80_T__, which has its justification/relevance. One could retrofit this #if defined(BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE) #define __STDCPP_FLOAT80_T__ namespace std { using float80_t = boost::float80_t; } #endif Would this be useful/wanted like this?
From the proposal the fixed width types are not allowed to be typedefs of the existing types https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html#extend.... Sections 5.3 - 5.5 also cover a whole host of conversion rules that would be unsupported. I do not believe this is something we can do at the library level.
b) complex-functions Since C++11 there are the functions abs, asin/h, acos/h, atan/h. These are also defined in boost/math/complex.hpp. But now with 1.82 boost::math is based on C++14, which makes these manual implementations obsolete -> boost/math/complex.hpp can be removed.
These functions are all explicitly marked deprecated, but we do not have a timeline for removal.
c) constexpr I want to upgrade some functions in boost::math. How should/can I handle constexpr there? My problem is: - in gcc almost all math functions are constexpr - otherwise only some math functions with C++23 are constexpr Now it would be suboptimal not to use constexpr just because it is currently not in the standard. - If I don't define the additional functions as constexpr or stick strictly to the standard, performance might be wasted, which I don't want. - Can I simply define the additional functions with constexpr/BOOST_CXX14_CONSTEXPR? In case of an error there will be the standard-error "not constexpr".
All of the cmath functions that are specified to be constexpr in C++23 can be used with C++17 here: https://github.com/boostorg/math/tree/develop/include/boost/math/ccmath. If you would like to submit PRs for additional functions they are welcome. With the transcendental functions accuracy quickly becomes an issue: https://members.loria.fr/PZimmermann/papers/accuracy.pdf
d) implementation In https://www.boost.org/doc/libs/1_82_0_beta1/libs/math/doc/html/math_toolkit/... you describe how to implement a new math function. Is this still up to date or is it necessary for simple functions? E.g. cot -> 1/tan.
That is generally correct. If this is for the implementation of constexpr cmath functions I would follow the implementations that can be found in the linked ccmath folder. Matt

Am 12.04.23 um 13:29 schrieb Matt Borland:
c) constexpr I want to upgrade some functions in boost::math. How should/can I handle constexpr there? My problem is: - in gcc almost all math functions are constexpr - otherwise only some math functions with C++23 are constexpr Now it would be suboptimal not to use constexpr just because it is currently not in the standard. - If I don't define the additional functions as constexpr or stick strictly to the standard, performance might be wasted, which I don't want. - Can I simply define the additional functions with constexpr/BOOST_CXX14_CONSTEXPR? In case of an error there will be the standard-error "not constexpr".
All of the cmath functions that are specified to be constexpr in C++23 can be used with C++17 here: https://github.com/boostorg/math/tree/develop/include/boost/math/ccmath https://github.com/boostorg/math/tree/develop/include/boost/math/ccmath. If you would like to submit PRs for additional functions they are welcome. With the transcendental functions accuracy quickly becomes an issue: https://members.loria.fr/PZimmermann/papers/accuracy.pdf https://members.loria.fr/PZimmermann/papers/accuracy.pdf
d) implementation In https://www.boost.org/doc/libs/1_82_0_beta1/libs/math/doc/html/math_toolkit/... you describe how to implement a new math function. Is this still up to date or is it necessary for simple functions? E.g. cot -> 1/tan.
That is generally correct. If this is for the implementation of constexpr cmath functions I would follow the implementations that can be found in the linked ccmath folder.
Matt
Hi Matt, Thanks for your comments. But I don't want to go that far, since the rest of the math functions will hopefully be constexpr with C++26 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1383r1.pdf). An implementation in ccmath would be very elaborate. My questions were related to how I can now provide additional math functions without much effort; to stay with the cot example (simplified): 1) without constexpr template <typename Type> inline auto cot(const Type x) noexcept { return 1/std::tan(x); } This would have the disadvantage that performance might be wasted if the compiler already provides std::tan constexpr (e.g. gcc). 2) "optimistic" with constexpr template <typename Type> inline constexpr auto cot ... constexpr auto y = cot(2); // gcc ok else error "not constexpr" This may give a CT error. The question is if this would be acceptable from your side. 3) additional macro e.g. BOOST_MATH_CONSTEXPR #if (BOOST_GCC && __cplusplus >= 201103L) || (defined(__cpp_lib_constexpr_cmath) && __cpp_lib_constexpr_cmath >= 202202L) #define BOOST_MATH_CONSTEXPR constexpr #else #define BOOST_MATH_CONSTEXPR #endif template <typename Type> inline BOOST_MATH_CONSTEXPR auto cot ... BOOST_MATH_CONSTEXPR auto y = cot(2); Disadvantage: the macro must always be kept up to date (maintenance effort). Which would be the best solution? thx Gero

Hi Matt, Thanks for your comments. But I don't want to go that far, since the rest of the math functions will hopefully be constexpr with C++26 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1383r1.pdf). An implementation in ccmath would be very elaborate. My questions were related to how I can now provide additional math functions without much effort; to stay with the cot example (simplified):
1) without constexpr template <typename Type> inline auto cot(const Type x) noexcept { return 1/std::tan(x); } This would have the disadvantage that performance might be wasted if the compiler already provides std::tan constexpr (e.g. gcc).
2) "optimistic" with constexpr template <typename Type> inline constexpr auto cot ... constexpr auto y = cot(2); // gcc ok else error "not constexpr" This may give a CT error. The question is if this would be acceptable from your side.
3) additional macro e.g. BOOST_MATH_CONSTEXPR #if (BOOST_GCC && __cplusplus >= 201103L) || (defined(__cpp_lib_constexpr_cmath) && __cpp_lib_constexpr_cmath >= 202202L) #define BOOST_MATH_CONSTEXPR constexpr #else #define BOOST_MATH_CONSTEXPR #endif template <typename Type> inline BOOST_MATH_CONSTEXPR auto cot ... BOOST_MATH_CONSTEXPR auto y = cot(2); Disadvantage: the macro must always be kept up to date (maintenance effort).
Which would be the best solution?
thx Gero
Gero, For seemingly trivial functions like cot = 1 / tan having an accurate implementation is non-trivial. You will want to implement this using a minmax polynomial instead https://en.wikipedia.org/wiki/Remez_algorithm. If you look in various standard library implementations they use these polynomials instead of trigonometric identities (e.g. sin = cos(pi/2 - theta)) for accuracy*. These are certainly more elaborate to implement. The current ccmath functions are all cross-platform so we do not have a dependency on GCC. I would recommend that if you want to proceed that you follow the way we implement functions we already ship in ccmath. Matt *https://github.com/bpowers/musl/blob/master/src/math/__sin.c and https://github.com/bpowers/musl/blob/master/src/math/__cos.c

Am 14.04.23 um 15:37 schrieb Matt Borland:
Hi Matt, Thanks for your comments. But I don't want to go that far, since the rest of the math functions will hopefully be constexpr with C++26 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1383r1.pdf). An implementation in ccmath would be very elaborate. My questions were related to how I can now provide additional math functions without much effort; to stay with the cot example (simplified):
1) without constexpr template <typename Type> inline auto cot(const Type x) noexcept { return 1/std::tan(x); } This would have the disadvantage that performance might be wasted if the compiler already provides std::tan constexpr (e.g. gcc).
2) "optimistic" with constexpr template <typename Type> inline constexpr auto cot ... constexpr auto y = cot(2); // gcc ok else error "not constexpr" This may give a CT error. The question is if this would be acceptable from your side.
3) additional macro e.g. BOOST_MATH_CONSTEXPR #if (BOOST_GCC && __cplusplus >= 201103L) || (defined(__cpp_lib_constexpr_cmath) && __cpp_lib_constexpr_cmath >= 202202L) #define BOOST_MATH_CONSTEXPR constexpr #else #define BOOST_MATH_CONSTEXPR #endif template <typename Type> inline BOOST_MATH_CONSTEXPR auto cot ... BOOST_MATH_CONSTEXPR auto y = cot(2); Disadvantage: the macro must always be kept up to date (maintenance effort).
Which would be the best solution?
thx Gero
Gero,
For seemingly trivial functions like cot = 1 / tan having an accurate implementation is non-trivial. You will want to implement this using a minmax polynomial instead https://en.wikipedia.org/wiki/Remez_algorithm https://en.wikipedia.org/wiki/Remez_algorithm. If you look in various standard library implementations they use these polynomials instead of trigonometric identities (e.g. sin = cos(pi/2 - theta)) for accuracy*. These are certainly more elaborate to implement. The current ccmath functions are all cross-platform so we do not have a dependency on GCC. I would recommend that if you want to proceed that you follow the way we implement functions we already ship in ccmath.
Matt
*https://github.com/bpowers/musl/blob/master/src/math/__sin.c https://github.com/bpowers/musl/blob/master/src/math/__sin.c and https://github.com/bpowers/musl/blob/master/src/math/__cos.c https://github.com/bpowers/musl/blob/master/src/math/__cos.c
Hi Matt, I see, and these would also have to be provided for std::complex and multiprecision+octonion+quaternion. Nevertheless, a start has to be made. For functions that are not based on series, however, your reasoning does not apply. How can/should I handle constexpr there (1, 2 or 3)? In addition your ccmath functions are buggy. The problem is that you make incomplete nan-checks. You check for isnan (limits::quiet_NaN), but not for limits::signaling_NaN. These are different values - https://godbolt.org/z/4YWMWbabz. But for e.g. copysign you have to ensure that *only* the sign is changed, which is not the case with your implementation (based on abs). Maybe it would even make sense to remove ccmath completely. cu Gero
participants (2)
-
Gero Peterhoff
-
Matt Borland