Boost logo

Boost :

From: Gero Peterhoff (g.peterhoff_at_[hidden])
Date: 2023-04-14 18:39:04


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




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk