Math.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cmath>
7 #include <numeric>
8 #include <type_traits>
9 #include <vector>
10 
13 #include "Utilities/Requires.hpp"
14 #include "Utilities/TypeTraits.hpp"
15 
16 // using for overload resolution with blaze
17 // clang-tidy doesn't want these in the global namespace
18 using std::conj; //NOLINT
19 using std::imag; //NOLINT
20 using std::real; //NOLINT
21 
22 /*!
23  * \ingroup UtilitiesGroup
24  * \brief Returns the number of digits in an integer number
25  */
26 template <typename T>
28  static_assert(tt::is_integer_v<std::decay_t<T>>,
29  "Must call number_of_digits with an integer number");
30  return number == 0 ? 1 : static_cast<decltype(number)>(
31  std::ceil(std::log10(std::abs(number) + 1)));
32 }
33 
34 /*!
35  * \ingroup UtilitiesGroup
36  * \brief Evaluate a polynomial \f$\sum_{p=0}^N c_p x^p\f$ with Horner's rule
37  *
38  * \param coeffs The polynomial coefficients \f$c_p\f$ ordered from constant to
39  * largest power
40  * \param x The polynomial variable \f$x\f$
41  *
42  * \tparam U The type of the polynomial coefficients \p coeffs. Can be `double`,
43  * which means the coefficients are constant for all values in \p x. Can also be
44  * a vector type of typically the same size as `T`, which means the coefficients
45  * vary with the elements in \p x.
46  * \tparam T The type of the polynomial variable \p x. Must support
47  * `make_with_value<T, T>`, as well as (elementwise) addition with `U` and
48  * multiplication with `T`.
49  */
50 template <typename U, typename T>
51 T evaluate_polynomial(const std::vector<U>& coeffs, const T& x) noexcept {
52  return std::accumulate(
53  coeffs.rbegin(), coeffs.rend(), make_with_value<T>(x, 0.),
54  [&x](const T& state, const U& element) { return state * x + element; });
55 }
56 
57 /// \ingroup UtilitiesGroup
58 
59 /// \brief Defines the Heaviside step function \f$\Theta\f$ for arithmetic
60 /// types. \f$\Theta(0) = 1\f$.
61 template <typename T, Requires<std::is_arithmetic<T>::value> = nullptr>
62 constexpr T step_function(const T& arg) noexcept {
63  return static_cast<T>((arg >= static_cast<T>(0)) ? 1 : 0);
64 }
65 
66 /// \ingroup UtilitiesGroup
67 /// \brief Defines the inverse square-root (\f$1/\sqrt{x}\f$) for arithmetic
68 /// and complex types
69 template <typename T, Requires<std::is_arithmetic<T>::value or
70  tt::is_a_v<std::complex, T>> = nullptr>
71 auto invsqrt(const T& arg) noexcept {
72  return static_cast<T>(1.0) / sqrt(arg);
73 }
74 
75 /// \ingroup UtilitiesGroup
76 /// \brief Defines the inverse cube-root (\f$1/\sqrt[3]{x}\f$) for arithmetic
77 /// types
78 template <typename T, Requires<std::is_arithmetic<T>::value> = nullptr>
79 auto invcbrt(const T& arg) noexcept {
80  return static_cast<T>(1.0) / cbrt(arg);
81 }
82 
83 namespace sgn_detail {
84 template <typename T>
85 constexpr T sgn(const T& val, std::true_type /*is_signed*/) noexcept {
86  return static_cast<T>(static_cast<T>(0) < val) -
87  static_cast<T>(val < static_cast<T>(0));
88 }
89 
90 template <typename T>
91 constexpr T sgn(const T& val, std::false_type /*is_signed*/) noexcept {
92  return static_cast<T>(static_cast<T>(0) < val);
93 }
94 } // namespace sgn_detail
95 
96 /// \ingroup UtilitiesGroup
97 /// \brief Compute the sign function of `val` defined as `1` if `val > 0`, `0`
98 /// if `val == 0`, and `-1` if `val < 0`.
99 template <typename T>
100 constexpr T sgn(const T& val) noexcept {
101  return sgn_detail::sgn(val, std::is_signed<T>{});
102 }
constexpr T step_function(const T &arg) noexcept
Defines the Heaviside step function for arithmetic types. .
Definition: Math.hpp:62
T number_of_digits(const T number)
Returns the number of digits in an integer number.
Definition: Math.hpp:27
T evaluate_polynomial(const std::vector< U > &coeffs, const T &x) noexcept
Evaluate a polynomial with Horner&#39;s rule.
Definition: Math.hpp:51
auto invsqrt(const T &arg) noexcept
Defines the inverse square-root ( ) for arithmetic and complex types.
Definition: Math.hpp:71
constexpr bool is_integer_v
Definition: TypeTraits.hpp:1306
Defines the type alias Requires.
constexpr T sgn(const T &val) noexcept
Compute the sign function of val defined as 1 if val > 0, 0 if val == 0, and -1 if val < 0...
Definition: Math.hpp:100
#define SPECTRE_ALWAYS_INLINE
Always inline a function. Only use this if you benchmarked the code.
Definition: ForceInline.hpp:20
Defines macro to always inline a function.
auto invcbrt(const T &arg) noexcept
Defines the inverse cube-root ( ) for arithmetic types.
Definition: Math.hpp:79
constexpr T accumulate(InputIt first, InputIt last, T init)
Definition: Numeric.hpp:33
Definition: Math.hpp:83
Defines type traits, some of which are future STL type_traits header.
Defines make_with_value.