File indexing completed on 2025-11-16 09:16:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <cmath>
0012
0013 namespace Acts {
0014
0015
0016
0017
0018
0019 template <typename T>
0020 constexpr T abs(const T n) {
0021 if (std::is_constant_evaluated()) {
0022 if constexpr (std::is_signed_v<T>) {
0023 if (n < 0) {
0024 return -n;
0025 }
0026 }
0027 return n;
0028 } else {
0029 return std::abs(n);
0030 }
0031 }
0032
0033
0034
0035
0036
0037 template <typename T, std::integral P>
0038 constexpr T pow(T x, P p) {
0039 if (std::is_constant_evaluated()) {
0040 constexpr T one = 1;
0041 if constexpr (std::is_signed_v<P>) {
0042 if (p < 0 && abs(x) > std::numeric_limits<T>::epsilon()) {
0043 x = one / x;
0044 p = -p;
0045 }
0046 }
0047 using unsigned_p = std::make_unsigned_t<P>;
0048 return p == 0 ? one : x * pow(x, static_cast<unsigned_p>(p) - 1);
0049 } else {
0050 return static_cast<T>(std::pow(x, static_cast<T>(p)));
0051 }
0052 }
0053
0054
0055
0056
0057 template <typename T>
0058 constexpr auto square(T x) {
0059 return x * x;
0060 }
0061
0062
0063
0064
0065 template <typename... T>
0066 constexpr auto hypotSquare(T... args) {
0067 return (square(args) + ...);
0068 }
0069
0070
0071
0072
0073 template <typename... T>
0074 constexpr auto fastHypot(T... args) {
0075 return std::sqrt(hypotSquare(args...));
0076 }
0077
0078
0079
0080
0081
0082 template <std::integral T>
0083 constexpr T sumUpToN(const T N) {
0084 return N * (N + 1) / 2;
0085 }
0086
0087
0088
0089
0090
0091 template <std::integral T>
0092 constexpr T factorial(const T upperN, const T lowerN = 1) {
0093 constexpr T one = 1;
0094 const T& limit = std::max(one, lowerN);
0095 return upperN >= limit ? upperN * factorial(upperN - 1, limit) : one;
0096 }
0097
0098
0099
0100
0101
0102
0103
0104 template <std::integral T>
0105 constexpr T binomial(const T n, const T k) {
0106 return factorial<T>(n, n - k + 1) / factorial<T>(k);
0107 }
0108
0109 }