8 #ifndef META_OCEAN_MATH_NUMERIC_H
9 #define META_OCEAN_MATH_NUMERIC_H
26 template <
typename T>
class NumericT;
64 static constexpr T
pi();
70 static constexpr T
pi2();
76 static constexpr T
pi_2();
82 static constexpr T
pi_3();
88 static constexpr T
pi_4();
112 static constexpr T
e();
133 static inline T
abs(
const T value);
149 static constexpr
inline T
sqr(
const T value);
157 static inline T
sum(
const T* values,
const size_t number);
165 static inline T
summedSqr(
const T* values,
const size_t number);
173 static constexpr
inline T
sqrDistance(
const T value0,
const T value1);
180 static inline T
sqrt(
const T value);
187 static inline std::complex<T>
sqrt(
const std::complex<T>& value);
194 static inline T
sin(
const T value);
201 static inline T
cos(
const T value);
208 static inline T
tan(
const T value);
215 static inline T
asin(
const T value);
222 static inline T
acos(
const T value);
229 static inline T
atan(
const T value);
237 static inline T
atan2(
const T y,
const T x);
244 static inline T
exp(
const T value);
251 static inline T
log(
const T value);
259 static inline T
log1p(
const T value);
266 static inline T
log2(
const T value);
273 static inline T
log10(
const T value);
281 static inline T
fmod(
const T valueA,
const T valueB);
290 static inline T
dot(
const T* vectorA,
const T* vectorB,
const size_t size);
319 static inline bool angleIsEqual(
const T angleA,
const T angleB);
336 static inline bool angleIsEqual(
const T angleA,
const T angleB,
const T epsilon);
353 static inline T
angleDistance(
const T angleA,
const T angleB);
361 static inline T
pow(
const T x,
const T y);
369 static inline std::complex<T>
pow(
const std::complex<T>& x,
const T y);
377 static constexpr T
integerPow(
const T x,
const unsigned int y);
384 static constexpr
inline T
factorial(
const T& value);
400 static inline T
ceil(
const T value);
407 static inline T
floor(
const T value);
425 static constexpr
inline int32_t
round32(
const T value);
443 static constexpr
inline int64_t
round64(
const T value);
452 static constexpr
inline T
ratio(
const T nominator,
const T denominator,
const T fallback = T(1));
459 static constexpr
inline bool isEqualEps(
const T value);
466 static constexpr
inline bool isEqualEps(
const std::complex<T>& value);
480 static constexpr
inline bool isWeakEqualEps(
const std::complex<T>& value);
494 static constexpr
inline bool isNotEqualEps(
const std::complex<T>& value);
516 static inline bool isEqual(
const T first,
const T second);
524 static inline bool isEqual(
const std::complex<T>& first,
const std::complex<T>& second);
532 static inline bool isWeakEqual(
const T first,
const T second);
540 static inline bool isWeakEqual(
const std::complex<T>& first,
const std::complex<T>& second);
549 static inline bool isEqual(
const T first,
const T second,
const T epsilon);
558 static inline bool isEqual(
const std::complex<T>& first,
const std::complex<T>& second,
const T epsilon);
571 template <
int tMagnitude>
572 static inline bool isEqual(
const T first,
const T second,
const T referenceEpsilon);
580 static inline bool isNotEqual(
const T first,
const T second);
588 static inline bool isNotEqual(
const std::complex<T>& first,
const std::complex<T>& second);
604 static inline bool isNotWeakEqual(
const std::complex<T>& first,
const std::complex<T>& second);
613 static inline bool isNotEqual(
const T first,
const T second,
const T epsilon);
622 static inline bool isNotEqual(
const std::complex<T>& first,
const std::complex<T>& second,
const T epsilon);
641 static constexpr
bool isInsideWeakRange(
const T lower,
const T value,
const T upper);
665 static constexpr T
nan();
672 static inline bool isNan(
const T value);
679 static inline bool isNan(
const std::complex<T>& value);
685 static constexpr T
inf();
693 static inline bool isInf(
const T value);
701 static inline bool isInf(
const std::complex<T>& value);
725 template <
typename TValue>
733 static constexpr
inline T
deg2rad(
const T deg);
740 static constexpr
inline T
rad2deg(
const T rad);
746 static constexpr
inline T
maxValue();
752 static constexpr
inline T
minValue();
759 static constexpr
inline T
sign(
const T& value);
767 static constexpr
inline T
copySign(
const T signReceiver,
const T signProvider);
775 static constexpr
inline T
invertSign(
const T signReceiver,
const T signProvider);
842 static inline T
gaussianDistribution2(
const T x,
const T y,
const T x0,
const T y0,
const T sigmaX,
const T sigmaY);
878 static inline T
gaussianDistribution3(
const T x,
const T y,
const T z,
const T sigmaX,
const T sigmaY,
const T sigmaZ);
893 static inline T
gaussianDistribution3(
const T x,
const T y,
const T z,
const T x0,
const T y0,
const T z0,
const T sigmaX,
const T sigmaY,
const T sigmaZ);
922 static inline T
normalizedGaussianDistribution3(
const T x,
const T y,
const T z,
const T x0,
const T y0,
const T z0,
const T sigmaX,
const T sigmaY,
const T sigmaZ);
925 template <
typename T>
928 return T(3.1415926535897932384626433832795);
931 template <
typename T>
934 return T(6.283185307179586476925286766559);
937 template <
typename T>
940 return T(1.5707963267948966192313216916395);
943 template <
typename T>
946 return T(1.0471975511965977461542144610932);
949 template <
typename T>
952 return T(0.78539816339744830961566084581988);
955 template <
typename T>
958 return T(9.8696044010893586188344909998762);
961 template <
typename T>
964 return T(39.478417604357434475337963999505);
967 template <
typename T>
970 return T(2.4674011002723396547086227499667);
973 template <
typename T>
976 return T(2.71828182845904523536);
1219 template <
typename T>
1222 return ::abs(value);
1232 ocean_assert(value != std::numeric_limits<signed char>::lowest() &&
"The absolute value of -128 is 128 but then casted to -128");
1234 return (
signed char)(::abs(value));
1254 ocean_assert(value != std::numeric_limits<short>::lowest() &&
"The absolute value of -32768 is 32768 but then casted to -32768");
1256 return short(::abs(value));
1276 ocean_assert(value != std::numeric_limits<int>::lowest());
1278 return ::abs(value);
1298 ocean_assert(value != std::numeric_limits<long>::lowest());
1300 return ::labs(value);
1320 ocean_assert(value != std::numeric_limits<long long>::lowest());
1322 return ::llabs(value);
1352 return fabsf(value);
1355 template <
typename T>
1368 return (
unsigned char)(::abs(
int(value)));
1388 return (
unsigned short)::abs(
int(value));
1408 if (value == std::numeric_limits<int>::lowest())
1411 return (
unsigned int)(std::numeric_limits<int>::max()) + 1u;
1414 return (
unsigned int)(::abs(value));
1434 ocean_assert((
unsigned long)::llabs(std::numeric_limits<long>::max()) == (
unsigned long)(-(std::numeric_limits<long>::lowest() + 1l)));
1435 return (
unsigned long)::llabs(value);
1455 if (value == std::numeric_limits<long long>::lowest())
1458 return (
unsigned long long)(std::numeric_limits<long long>::max()) + 1ull;
1461 return (
unsigned long long)(::llabs(value));
1494 template <
typename T>
1497 return value * value;
1500 template <
typename T>
1505 for (
size_t n = 0; n < number; ++n)
1507 result += values[n];
1513 template <
typename T>
1518 for (
size_t n = 0; n < number; ++n)
1520 result +=
sqr(values[n]);
1526 template <
typename T>
1529 return sqr(value0 - value1);
1532 template <
typename T>
1535 ocean_assert(value >= T(0));
1536 return T(::sqrt(value));
1546 ocean_assert(value >= 0.0f);
1547 return ::sqrtf(value);
1557 ocean_assert(value >= 0);
1558 return int(::sqrtf(
float(value)));
1561 template <
typename T>
1564 return std::sqrt<T>(value);
1567 template <
typename T>
1570 return ::sin(value);
1583 template <
typename T>
1586 return ::cos(value);
1599 template <
typename T>
1602 return ::tan(value);
1615 template <
typename T>
1618 return ::atan(value);
1628 return atanf(value);
1631 template <
typename T>
1636 const T angle = ::atan2(y, x);
1642 template <
typename T>
1645 return ::exp(value);
1651 return ::expf(value);
1654 template <
typename T>
1657 ocean_assert(value > 0);
1658 return ::log(value);
1664 ocean_assert(value > 0);
1665 return ::logf(value);
1668 template <
typename T>
1671 ocean_assert(value > -1);
1672 return ::log1p(value);
1678 ocean_assert(value > -1);
1679 return ::log1pf(value);
1682 template <
typename T>
1685 ocean_assert(value > 0);
1687 #if (defined(OCEAN_COMPILER_MSC) && OCEAN_MSC_VERSION >= 1800) || (OCEAN_CLANG_VERSION >= 30300 && (!defined(__ANDROID__) || !__ANDROID__))
1688 return ::log2(value);
1690 return ::log(value) * 1.44269504088896340736;
1701 ocean_assert(value > 0);
1703 #if (defined(OCEAN_COMPILER_MSC) && OCEAN_MSC_VERSION >= 1800) || (OCEAN_CLANG_VERSION >= 30300 && (!defined(__ANDROID__) || !__ANDROID__))
1704 return ::log2f(value);
1706 return ::logf(value) * 1.44269504088896340736f;
1710 template <
typename T>
1713 ocean_assert(value > 0);
1714 return ::log10(value);
1720 ocean_assert(value > 0);
1721 return ::log10f(value);
1731 return atan2f(y, x);
1734 template <
typename T>
1737 return ::fmod(valueA, valueB);
1747 return fmodf(valueA, valueB);
1750 template <
typename T>
1755 for (
size_t n = 0; n < size; ++n)
1757 result += vectorA[n] * vectorB[n];
1763 template <
typename T>
1766 const T adjusted = fmod(angle, pi2());
1770 ocean_assert((std::is_same<T, float>::value) || (pi2() + adjusted >= 0 && pi2() + adjusted < pi2()));
1771 return pi2() + adjusted;
1774 ocean_assert(adjusted >= 0 && adjusted < pi2());
1778 template <
typename T>
1781 const T adjusted = fmod(angle, pi());
1785 ocean_assert(pi() + adjusted >= 0 && pi() + adjusted < pi());
1786 return pi() + adjusted;
1789 ocean_assert(adjusted >= 0 && adjusted < pi());
1793 template <
typename T>
1796 if (angle > -pi() && angle <= pi())
1801 const T adjusted = fmod(angle, pi2());
1803 if (isAbove(adjusted, pi()))
1805 ocean_assert(adjusted - pi2() > -pi() - eps() && adjusted - pi2() <= pi() + eps());
1806 return adjusted - pi2();
1808 else if (isBelow(adjusted, -pi()))
1810 ocean_assert(adjusted + pi2() > -pi() - eps() && adjusted + pi2() <= pi() + eps());
1811 return adjusted + pi2();
1814 ocean_assert(adjusted > -pi() && adjusted <= pi());
1818 template <
typename T>
1821 return isEqualEps(angleDistance(angleA, angleB));
1824 template <
typename T>
1827 return isWeakEqualEps(angleDistance(angleA, angleB));
1830 template <
typename T>
1833 ocean_assert(epsilon >= T(0));
1834 return isEqual(angleDistance(angleA, angleB), T(0), epsilon);
1837 template <
typename T>
1840 ocean_assert(threshold < pi());
1842 return isBelow(abs(angleAdjustNull(angleA - angleB)), threshold);
1845 template <
typename T>
1848 const T distance = abs(angleAdjustPositive(angleA) - angleAdjustPositive(angleB));
1859 template <
typename T>
1865 template <
typename T>
1868 return std::pow<T>(x, y);
1881 template <
typename T>
1884 return y == 0u ? T(1) : x * integerPow(x, y - 1u);
1887 template <
typename T>
1890 ocean_assert(value >= 0);
1891 ocean_assert(T((
long long)(value)) == value);
1900 for (
unsigned int n = 3u; n <= (
unsigned int)value; ++n)
1902 ocean_assert(std::numeric_limits<T>::max() / T(n) >= result);
1952 ocean_assert(
false &&
"Invalid factorial value!");
1956 template <
typename T>
1959 ocean_assert(n >= 0 && k >= 0);
1960 ocean_assert(T((
long long)(n)) == n);
1961 ocean_assert(T((
long long)(k)) == k);
1963 if (n <= T(1) || k == T(0) || n == k)
1968 ocean_assert(k < n);
1970 T result = n - k + T(1);
1972 for (
unsigned int i = (
unsigned int)(n - k) + 2u; i <= (
unsigned int)n; ++i)
1974 ocean_assert(std::numeric_limits<T>::max() / T(i) >= result);
1978 for (
unsigned int i = 2u; i <= (
unsigned int)k; ++i)
1980 ocean_assert((result / T(i)) * T(i) == result);
1987 template <
typename T>
1990 static_assert(std::is_floating_point<T>::value ==
false,
"Data type must not be a floating point!");
2002 return ::ceilf(value);
2012 return ::ceil(value);
2022 return ::ceill(value);
2025 template <
typename T>
2028 static_assert(std::is_floating_point<T>::value ==
false,
"Data type must not be a floating point!");
2040 return ::floorf(value);
2050 return ::floor(value);
2060 return ::floorl(value);
2063 template <
typename T>
2066 return int32_t(value + copySign(T(0.5), value));
2069 template <
typename T>
2072 return int64_t(value + copySign(T(0.5), value));
2075 template <
typename T>
2078 if (isEqualEps(denominator))
2083 return nominator / denominator;
2086 template <
typename T>
2089 ocean_assert(isNan(value) ==
false);
2090 ocean_assert((fabs(value) <= eps()) == (-eps() <= value && value <= eps()));
2092 return -eps() <= value && value <= eps();
2098 return value == (
signed char)(0);
2104 return value == (
unsigned char)(0);
2110 return value == short(0);
2116 return value == (
unsigned short)(0);
2140 return value == 0ul;
2146 return value == 0ll;
2152 return value == 0ull;
2155 template <
typename T>
2158 return isEqualEps(value.real()) && isEqualEps(value.imag());
2161 template <
typename T>
2164 ocean_assert(isNan(value) ==
false);
2165 ocean_assert((fabs(value) <= weakEps()) == (-weakEps() <= value && value <= weakEps()));
2167 return -weakEps() <= value && value <= weakEps();
2173 return value == (
signed char)(0);
2179 return value == (
unsigned char)(0);
2185 return value == short(0);
2191 return value == (
unsigned short)(0);
2215 return value == 0ul;
2221 return value == 0ll;
2227 return value == 0ull;
2230 template <
typename T>
2233 return isWeakEqualEps(value.real()) && isWeakEqualEps(value.imag());
2236 template <
typename T>
2239 ocean_assert(isNan(value) ==
false);
2240 ocean_assert((fabs(value) > eps()) == (value > eps() || value < -eps()));
2242 return value > eps() || value < -eps();
2248 return value != (
signed char)(0);
2254 return value != (
unsigned char)(0);
2260 return value != short(0);
2266 return value != (
unsigned short)(0);
2290 return value != 0ul;
2296 return value != 0ll;
2302 return value != 0ull;
2305 template <
typename T>
2308 return value.real() > eps() || value.real() < -eps() || value.imag() > eps() || value.imag() < -eps();
2311 template <
typename T>
2314 ocean_assert((fabs(value) > weakEps()) == (value > weakEps() || value < -weakEps()));
2316 return value > weakEps() || value < -weakEps();
2322 return value != (
signed char)(0);
2328 return value != (
unsigned char)(0);
2334 return value != short(0);
2340 return value != (
unsigned short)(0);
2364 return value != 0ul;
2370 return value != 0ll;
2376 return value != 0ull;
2379 template <
typename T>
2382 return value.real() > weakEps() || value.real() < -weakEps() || value.imag() > weakEps() || value.imag() < -weakEps();
2385 template <
typename T>
2388 return fabs(first - second) <= eps();
2394 return first == second;
2400 return first == second;
2406 return first == second;
2412 return first == second;
2418 return first == second;
2424 return first == second;
2430 return first == second;
2436 return first == second;
2442 return first == second;
2448 return first == second;
2451 template <
typename T>
2454 return isEqual(first.real(), second.real()) && isEqual(first.imag(), second.imag());
2457 template <
typename T>
2460 ocean_assert(epsilon >= T(0));
2467 ocean_assert(epsilon >= (
signed char)(0));
2468 return std::abs(first - second) <= epsilon;
2474 ocean_assert(epsilon >=
short(0));
2475 return std::abs(first - second) <= epsilon;
2481 ocean_assert(epsilon >= 0);
2482 return std::abs(first - second) <= epsilon;
2488 ocean_assert(epsilon >=
long(0));
2489 return std::abs(first - second) <= epsilon;
2495 ocean_assert(epsilon >= 0ll);
2496 return std::abs(first - second) <= epsilon;
2504 return first - second <= epsilon;
2508 return second - first <= epsilon;
2517 return first - second <= epsilon;
2521 return second - first <= epsilon;
2530 return first - second <= epsilon;
2534 return second - first <= epsilon;
2543 return first - second <= epsilon;
2547 return second - first <= epsilon;
2556 return first - second <= epsilon;
2560 return second - first <= epsilon;
2564 template <
typename T>
2567 ocean_assert(epsilon >= T(0));
2568 return isEqual(first.real(), second.real(), epsilon) && isEqual(first.imag(), second.imag(), epsilon);
2571 template <
typename T>
2580 return first == second;
2583 template <
typename T>
2586 return isWeakEqual(first.real(), second.real()) && isWeakEqual(first.imag(), second.imag());
2589 template <
typename T>
2590 template <
int tMagnitude>
2593 static_assert(tMagnitude >= -20 && tMagnitude <= 20,
"Invalid reference magnitude");
2594 ocean_assert(referenceEpsilon >= T(0));
2599 if (isEqualEps(maximalAbsValue))
2605 ocean_assert(offsetMagnitude >= 0);
2607 const T adjustedEpsilon = referenceEpsilon *
NumericT<T>::pow(10, T(offsetMagnitude));
2609 return isEqual(first, second, adjustedEpsilon);
2612 template <
typename T>
2615 return fabs(first - second) > eps();
2621 return first != second;
2627 return first != second;
2633 return first != second;
2639 return first != second;
2645 return first != second;
2651 return first != second;
2657 return first != second;
2663 return first != second;
2670 return first != second;
2676 return first != second;
2679 template <
typename T>
2682 return isNotEqual(first.real(), second.real()) || isNotEqual(first.imag(), second.imag());
2685 template <
typename T>
2688 return fabs(first - second) > weakEps();
2694 return first != second;
2700 return first != second;
2706 return first != second;
2712 return first != second;
2718 return first != second;
2724 return first != second;
2730 return first != second;
2736 return first != second;
2742 return first != second;
2748 return first != second;
2751 template <
typename T>
2754 return isNotWeakEqual(first.real(), second.real()) || isNotWeakEqual(first.imag(), second.imag());
2757 template <
typename T>
2760 ocean_assert(epsilon >= 0);
2761 return fabs(first - second) > epsilon;
2767 ocean_assert(epsilon >= (
signed char)(0));
2768 return std::abs(first - second) > epsilon;
2774 ocean_assert(epsilon >=
short(0));
2775 return std::abs(first - second) > epsilon;
2781 ocean_assert(epsilon >= 0);
2782 return std::abs(first - second) > epsilon;
2788 ocean_assert(epsilon >=
long(0));
2789 return std::abs(first - second) > epsilon;
2795 ocean_assert(epsilon >= 0ll);
2796 return std::abs(first - second) > epsilon;
2804 return first - second > epsilon;
2808 return second - first > epsilon;
2817 return first - second > epsilon;
2821 return second - first > epsilon;
2830 return first - second > epsilon;
2834 return second - first > epsilon;
2843 return first - second > epsilon;
2847 return second - first > epsilon;
2856 return first - second > epsilon;
2860 return second - first > epsilon;
2864 template <
typename T>
2867 ocean_assert(epsilon >= 0);
2868 return isNotEqual(first.real(), second.real(), epsilon) || isNotEqual(first.imag(), second.imag(), epsilon);
2871 template <
typename T>
2874 ocean_assert(lower <= upper);
2875 ocean_assert(epsilon >= T(0));
2877 return value >= lower - epsilon && value <= upper + epsilon;
2880 template <
typename T>
2883 return isInsideRange(lower, value, upper, weakEps());
2886 template <
typename T>
2891 return ::asin(max(T(-1), min(T(1), value)));
2903 return asinf(max(-1.0f, min(1.0f, value)));
2906 template <
typename T>
2911 return ::acos(max(T(-1), min(T(1), value)));
2923 return acosf(max(-1.0f, min(1.0f, value)));
2926 template <
typename T>
2929 static_assert(std::is_floating_point<T>::value,
"Invalid data type!");
2931 ocean_assert(epsilon >= T(0));
2933 return value <= upper + epsilon;
2936 template <
typename T>
2939 static_assert(std::is_floating_point<T>::value,
"Invalid data type!");
2941 ocean_assert(epsilon >= T(0));
2943 return lower - epsilon <= value;
2946 template <
typename T>
2949 static_assert(std::is_floating_point<T>::value,
"Data type must be a floating point data type");
2951 if constexpr (std::is_same<T, float>::value)
2953 static_assert(
sizeof(
float) ==
sizeof(uint32_t),
"Invalid data type!");
2955 constexpr uint32_t integerValue = 0x7FC00000u;
2957 float floatValue = 0.0f;
2958 memcpy(&floatValue, &integerValue,
sizeof(integerValue));
2960 return T(floatValue);
2964 static_assert(std::is_same<T, double>::value,
"Invalid data type!");
2965 static_assert(
sizeof(
double) ==
sizeof(uint64_t),
"Invalid data type!");
2967 constexpr uint64_t integerValue = 0x7FF8000000000000ull;
2969 double doubleValue = 0.0;
2970 memcpy(&doubleValue, &integerValue,
sizeof(integerValue));
2972 return T(doubleValue);
2982 static_assert(
sizeof(uint32_t) ==
sizeof(value),
"Invalid value!");
2987 memcpy(&tmpValue, &value,
sizeof(tmpValue));
2989 constexpr uint32_t exponentBitsAllOne = 0x7F800000u;
2990 constexpr uint32_t mantissaBitsAllOne = 0x007FFFFFu;
2992 const bool allExponentBitsAreOne = (tmpValue & exponentBitsAllOne) == exponentBitsAllOne;
2993 const bool mantissaIsNotZero = (tmpValue & mantissaBitsAllOne) != 0u;
2995 return allExponentBitsAreOne && mantissaIsNotZero;
3004 static_assert(
sizeof(uint64_t) ==
sizeof(value),
"Invalid value!");
3009 memcpy(&tmpValue, &value,
sizeof(tmpValue));
3011 constexpr uint64_t exponentBitsAllOne = 0x7FF0000000000000ull;
3012 constexpr uint64_t mantissaBitsAllOne = 0x000FFFFFFFFFFFFFull;
3014 const bool allExponentBitsAreOne = (tmpValue & exponentBitsAllOne) == exponentBitsAllOne;
3015 const bool mantissaIsNotZero = (tmpValue & mantissaBitsAllOne) != 0ull;
3017 return allExponentBitsAreOne && mantissaIsNotZero;
3020 template <
typename T>
3026 ocean_assert(std::is_floating_point<T>::value ==
false);
3030 template <
typename T>
3036 template <
typename T>
3039 static_assert(std::is_floating_point<T>::value,
"Data type must be a floating point data type");
3041 if constexpr (std::is_same<T, float>::value)
3043 static_assert(
sizeof(
float) ==
sizeof(uint32_t),
"Invalid data type!");
3045 constexpr uint32_t integerValue = 0x7F800000u;
3047 float floatValue = 0.0f;
3048 memcpy(&floatValue, &integerValue,
sizeof(integerValue));
3050 return T(floatValue);
3054 static_assert(std::is_same<T, double>::value,
"Invalid data type!");
3055 static_assert(
sizeof(
double) ==
sizeof(uint64_t),
"Invalid data type!");
3057 constexpr uint64_t integerValue = 0x7FF0000000000000ull;
3059 double doubleValue = 0.0;
3060 memcpy(&doubleValue, &integerValue,
sizeof(integerValue));
3062 return T(doubleValue);
3072 static_assert(
sizeof(uint32_t) ==
sizeof(value),
"Invalid value!");
3077 memcpy(&tmpValue, &value,
sizeof(tmpValue));
3079 constexpr uint32_t exponentBitsAllOne = 0x7F800000u;
3080 constexpr uint32_t mantissaBitsAllOne = 0x007FFFFFu;
3082 const bool allExponentBitsAreOne = (tmpValue & exponentBitsAllOne) == exponentBitsAllOne;
3083 const bool allMantissaBitsAreZero = (tmpValue & mantissaBitsAllOne) == 0u;
3085 return allExponentBitsAreOne && allMantissaBitsAreZero;
3094 static_assert(
sizeof(uint64_t) ==
sizeof(value),
"Invalid value!");
3099 memcpy(&tmpValue, &value,
sizeof(tmpValue));
3101 constexpr uint64_t exponentBitsAllOne = 0x7FF0000000000000ull;
3102 constexpr uint64_t mantissaBitsAllOne = 0x000FFFFFFFFFFFFFull;
3104 const bool allExponentBitsAreOne = (tmpValue & exponentBitsAllOne) == exponentBitsAllOne;
3105 const bool allMantissaBitsAreZero = (tmpValue & mantissaBitsAllOne) == 0ull;
3107 return allExponentBitsAreOne && allMantissaBitsAreZero;
3110 template <
typename T>
3116 ocean_assert(std::is_floating_point<T>::value ==
false);
3123 return std::isinf(value);
3126 template <
typename T>
3132 template <
typename T>
3133 template <
typename TValue>
3136 if constexpr (std::is_same<T, TValue>::value)
3143 if constexpr (std::is_floating_point<T>::value && std::is_floating_point<TValue>::value)
3152 if constexpr (std::is_integral<T>::value && std::is_integral<TValue>::value)
3156 if constexpr (std::is_signed<T>::value == std::is_signed<TValue>::value)
3160 if constexpr (
sizeof(TValue) <=
sizeof(T))
3168 ocean_assert(
sizeof(T) <
sizeof(TValue));
3176 if constexpr (std::is_signed<T>::value)
3178 ocean_assert(!std::is_signed<TValue>::value);
3182 if constexpr (
sizeof(TValue) <
sizeof(T))
3194 if constexpr (std::is_signed<TValue>::value)
3196 ocean_assert(!std::is_signed<T>::value);
3200 if (value < TValue(0))
3205 if constexpr (
sizeof(TValue) <
sizeof(T))
3211 else if constexpr (
sizeof(TValue) ==
sizeof(T))
3215 ocean_assert(value >= TValue(0));
3222 ocean_assert(value >= TValue(0));
3231 template <
typename T>
3234 return deg * T(0.017453292519943295769236907684886);
3237 template <
typename T>
3240 return rad * T(57.295779513082320876798154814105);
3243 template <
typename T>
3246 return std::numeric_limits<T>::max();
3249 template <
typename T>
3252 return std::numeric_limits<T>::lowest();
3255 template <
typename T>
3258 static_assert(std::numeric_limits<T>::is_signed,
"T must be a signed data type!");
3260 return T((T(0) < value) - (value < T(0)));
3263 template <
typename T>
3266 if (signProvider >= 0)
3268 return abs(signReceiver);
3271 return -abs(signReceiver);
3283 const unsigned long long value = ((*(
unsigned long long*)&first) & 0x7FFFFFFFFFFFFFFFll)
3284 | ((*(
unsigned long long*)&second) & 0x8000000000000000ll);
3288 ocean_assert(
sizeof(
unsigned long long) ==
sizeof(
double));
3290 const double result = *(
double*)&value;
3292 double testValue = 0;
3299 ocean_assert(result == testValue || second == 0.0);
3303 return *(
double*)&value;
3313 const unsigned int value = ((*(
unsigned int*)&first) & 0x7FFFFFFF) | ((*(
unsigned int*)&second) & 0x80000000);
3317 ocean_assert(
sizeof(
unsigned int) ==
sizeof(
float));
3319 const float result = *(
float*)&value;
3321 float testValue = 0;
3328 ocean_assert(result == testValue || second == 0.0);
3332 return *(
float*)&value;
3337 template <
typename T>
3340 if (signProvider < 0)
3342 return abs(signReceiver);
3345 return -abs(signReceiver);
3357 const unsigned long long value = ((*(
unsigned long long*)&first) & 0x7FFFFFFFFFFFFFFFll)
3358 | ((~*(
unsigned long long*)&second) & 0x8000000000000000ll);
3362 ocean_assert(
sizeof(
unsigned long long) ==
sizeof(
double));
3364 const double result = *(
double*)&value;
3366 double testValue = 0;
3373 ocean_assert(result == testValue);
3378 return *(
double*)&value;
3388 const unsigned int value = ((*(
unsigned int*)&first) & 0x7FFFFFFF) | ((~*(
unsigned int*)&second) & 0x80000000);
3392 ocean_assert(
sizeof(
unsigned int) ==
sizeof(
float));
3394 const float result = *(
float*)&value;
3396 double testValue = 0;
3403 ocean_assert(result == testValue);
3407 return *(
float*)&value;
3412 template <
typename T>
3420 const T factor = absB / absA;
3421 return absA * sqrt(1 + factor * factor);
3425 const T factor = absA / absB;
3426 return absB * sqrt(1 + factor * factor);
3432 template <
typename T>
3435 ocean_assert(sigma > eps());
3437 const T inverseSigma = T(1) / sigma;
3439 return inverseSigma * T(0.3989422804014326779) *
NumericT<T>::exp(T(-0.5) * x * x * inverseSigma * inverseSigma);
3442 template <
typename T>
3445 ocean_assert(sigma > eps());
3447 const T inverseSigma = T(1) / sigma;
3448 const T x_x0 = x - x0;
3450 return inverseSigma * T(0.3989422804014326779) *
NumericT<T>::exp(T(-0.5) * x_x0 * x_x0 * inverseSigma * inverseSigma);
3453 template <
typename T>
3456 ocean_assert(sigma > eps());
3458 const T inverseSigma = T(1) / sigma;
3463 template <
typename T>
3466 ocean_assert(sigma > eps());
3468 const T inverseSigma = T(1) / sigma;
3469 const T x_x0 = x - x0;
3471 return NumericT<T>::exp(T(-0.5) * x_x0 * x_x0 * inverseSigma * inverseSigma);
3474 template <
typename T>
3477 ocean_assert(sigmaX > eps() && sigmaY > eps());
3479 const T inverseSigmaX = T(1) / sigmaX;
3480 const T inverseSigmaY = T(1) / sigmaY;
3482 return inverseSigmaX * inverseSigmaY * T(0.15915494309189533576888) *
NumericT<T>::exp(T(-0.5) * (x * x * inverseSigmaX * inverseSigmaX + y * y * inverseSigmaY * inverseSigmaY));
3485 template <
typename T>
3488 ocean_assert(sigmaX > eps() && sigmaY > eps());
3490 const T inverseSigmaX = T(1) / sigmaX;
3491 const T inverseSigmaY = T(1) / sigmaY;
3493 const T x_x0 = x - x0;
3494 const T y_y0 = y - y0;
3496 return inverseSigmaX * inverseSigmaY * T(0.15915494309189533576888) *
NumericT<T>::exp(T(-0.5) * (x_x0 * x_x0 * inverseSigmaX * inverseSigmaX + y_y0 * y_y0 * inverseSigmaY * inverseSigmaY));
3499 template <
typename T>
3502 ocean_assert(sigmaX > eps() && sigmaY > eps());
3504 const T inverseSigmaX = T(1) / sigmaX;
3505 const T inverseSigmaY = T(1) / sigmaY;
3507 return NumericT<T>::exp(T(-0.5) * (x * x * inverseSigmaX * inverseSigmaX + y * y * inverseSigmaY * inverseSigmaY));
3510 template <
typename T>
3513 ocean_assert(sigmaX > eps() && sigmaY > eps());
3515 const T inverseSigmaX = T(1) / sigmaX;
3516 const T inverseSigmaY = T(1) / sigmaY;
3518 const T x_x0 = x - x0;
3519 const T y_y0 = y - y0;
3521 return NumericT<T>::exp(T(-0.5) * (x_x0 * x_x0 * inverseSigmaX * inverseSigmaX + y_y0 * y_y0 * inverseSigmaY * inverseSigmaY));
3524 template <
typename T>
3527 ocean_assert(sigmaX > eps() && sigmaY > eps() && sigmaZ > eps());
3529 const T inverseSigmaX = T(1) / sigmaX;
3530 const T inverseSigmaY = T(1) / sigmaY;
3531 const T inverseSigmaZ = T(1) / sigmaZ;
3533 return inverseSigmaX * inverseSigmaY * inverseSigmaZ * T(0.06349363593424096978576330493464)
3534 *
NumericT<T>::exp(T(-0.5) * (x * x * inverseSigmaX * inverseSigmaX + y * y * inverseSigmaY * inverseSigmaY + z * z * inverseSigmaZ * inverseSigmaZ));
3537 template <
typename T>
3540 ocean_assert(sigmaX > eps() && sigmaY > eps() && sigmaZ > eps());
3542 const T inverseSigmaX = T(1) / sigmaX;
3543 const T inverseSigmaY = T(1) / sigmaY;
3544 const T inverseSigmaZ = T(1) / sigmaZ;
3546 const T x_x0 = x - x0;
3547 const T y_y0 = y - y0;
3548 const T z_z0 = z - z0;
3550 return inverseSigmaX * inverseSigmaY * inverseSigmaZ * T(0.06349363593424096978576330493464)
3551 *
NumericT<T>::exp(T(-0.5) * (x_x0 * x_x0 * inverseSigmaX * inverseSigmaX + y_y0 * y_y0 * inverseSigmaY * inverseSigmaY + z_z0 * z_z0 * inverseSigmaZ * inverseSigmaZ));
3554 template <
typename T>
3557 ocean_assert(sigmaX > eps() && sigmaY > eps() && sigmaZ > eps());
3559 const T inverseSigmaX = T(1) / sigmaX;
3560 const T inverseSigmaY = T(1) / sigmaY;
3561 const T inverseSigmaZ = T(1) / sigmaZ;
3563 return NumericT<T>::exp(T(-0.5) * (x * x * inverseSigmaX * inverseSigmaX + y * y * inverseSigmaY * inverseSigmaY + z * z * inverseSigmaZ * inverseSigmaZ));
3566 template <
typename T>
3569 ocean_assert(sigmaX > eps() && sigmaY > eps() && sigmaZ > eps());
3571 const T inverseSigmaX = T(1) / sigmaX;
3572 const T inverseSigmaY = T(1) / sigmaY;
3573 const T inverseSigmaZ = T(1) / sigmaZ;
3575 const T x_x0 = x - x0;
3576 const T y_y0 = y - y0;
3577 const T z_z0 = z - z0;
3579 return NumericT<T>::exp(T(-0.5) * (x_x0 * x_x0 * inverseSigmaX * inverseSigmaX + y_y0 * y_y0 * inverseSigmaY * inverseSigmaY + z_z0 * z_z0 * inverseSigmaZ * inverseSigmaZ));
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static T angleAdjustPositive(const T angle)
Adjusts an arbitrary angle into the range of [0.0, 2PI).
Definition: Numeric.h:1764
static constexpr T deg2rad(const T deg)
Converts deg to rad.
Definition: Numeric.h:3232
static constexpr bool isNotWeakEqualEps(const T value)
Returns whether a value is not smaller than or equal to a weak epsilon.
Definition: Numeric.h:2312
static constexpr T minValue()
Returns the min scalar value.
Definition: Numeric.h:3250
static constexpr T pi2()
Returns 2*PI which is equivalent to 360 degree.
Definition: Numeric.h:932
static constexpr T sign(const T &value)
Returns the sign of a given value by either returning -1, 0, or +1.
Definition: Numeric.h:3256
static constexpr T weakEps()
Returns a weak epsilon.
static constexpr bool isInsideRange(const T lower, const T value, const T upper, const T epsilon=NumericT< T >::eps())
Returns whether a value lies between a given range up to a provided epsilon border.
Definition: Numeric.h:2872
static constexpr T pi_2()
Returns PI/2 which is equivalent to 90 degree.
Definition: Numeric.h:938
static T log(const T value)
Returns the natural logarithm of a given value (the logarithm to the base e).
Definition: Numeric.h:1655
static T exp(const T value)
Returns the base-e exponential function of a given value.
Definition: Numeric.h:1643
static T log1p(const T value)
Returns the natural logarithm of a given value plus 1 (the logarithm to the base e).
Definition: Numeric.h:1669
static constexpr T e()
Returns the euler's number.
Definition: Numeric.h:974
static T atan(const T value)
Returns the arctangent of a given value.
Definition: Numeric.h:1616
static T atan2(const T y, const T x)
Returns the arctangent of a given value in radian.
Definition: Numeric.h:1632
static constexpr T sqrDistance(const T value0, const T value1)
Returns the square distance between two values.
Definition: Numeric.h:1527
static T sin(const T value)
Returns the sine of a given value.
Definition: Numeric.h:1568
static bool isInf(const T value)
Returns whether a given value is positive or negative infinity.
Definition: Numeric.h:3111
static T pow(const T x, const T y)
Returns x raised to the power of y.
Definition: Numeric.h:1860
static constexpr T pi_4()
Returns PI/4 which is equivalent to 45 degree.
Definition: Numeric.h:950
static bool isNan(const T value)
Returns whether a given value is not a number.
Definition: Numeric.h:3021
static T abs(const T value)
Returns the absolute value of a given value.
Definition: Numeric.h:1220
static constexpr T factorial(const T &value)
Returns the factorial for a given value.
Definition: Numeric.h:1888
static constexpr T pi()
Returns PI which is equivalent to 180 degree.
Definition: Numeric.h:926
static T log10(const T value)
Returns the logarithm to base 10 of a given value.
Definition: Numeric.h:1711
static constexpr T squarePi2()
Returns the square of two PI i.e., (2*PI)^2.
Definition: Numeric.h:962
static constexpr bool isAbove(const T value, const T lower, const T epsilon=NumericT< T >::eps())
Returns whether a parameter lies on or above a given border tolerating a small epsilon.
Definition: Numeric.h:2937
static bool isWeakEqual(const T first, const T second)
Returns whether two values a equal up to a weak epsilon.
Definition: Numeric.h:2572
static T normalizedGaussianDistribution(const T x, const T sigma)
Returns a value of the normalized univariate Gaussian distribution centered around the origin.
Definition: Numeric.h:3454
static constexpr int32_t round32(const T value)
Returns the rounded 32 bit integer value of a given value.
Definition: Numeric.h:2064
static T sum(const T *values, const size_t number)
Returns the sum of given values.
Definition: Numeric.h:1501
static constexpr bool isWeakEqualEps(const T value)
Returns whether a value is smaller than or equal to a weak epsilon.
Definition: Numeric.h:2162
static T sqrt(const T value)
Returns the square root of a given value.
Definition: Numeric.h:1533
static T pythagoras(const T a, const T b)
Returns the length of the hypotenuse of a given right-angled triangle.
Definition: Numeric.h:3413
static T fmod(const T valueA, const T valueB)
Returns the floating-point remainder of a given value.
Definition: Numeric.h:1735
static T angleAdjustNull(const T angle)
Adjusts an arbitrary angle into the range of (-PI, PI].
Definition: Numeric.h:1794
static bool angleIsBelowThreshold(const T angleA, const T angleB, const T threshold)
Returns whether the angular difference (distance) between two angles is smaller than a specified thre...
Definition: Numeric.h:1838
static constexpr T eps()
Returns a small epsilon.
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition: Numeric.h:2386
static constexpr bool isBelow(const T value, const T upper, const T epsilon=NumericT< T >::eps())
Returns whether a parameter lies on or below a given border tolerating a small epsilon.
Definition: Numeric.h:2927
static T gaussianDistribution(const T x, const T sigma)
Returns a value of the univariate Gaussian distribution centered around the origin.
Definition: Numeric.h:3433
static T gaussianDistribution2(const T x, const T y, const T sigmaX, const T sigmaY)
Returns a value of the bivariate Gaussian distribution centered around the origin.
Definition: Numeric.h:3475
static constexpr T ratio(const T nominator, const T denominator, const T fallback=T(1))
Returns the ratio between two values if the denominator is not equal a small epsilon.
Definition: Numeric.h:2076
static constexpr T nan()
Returns a value which is not a number (nan).
Definition: Numeric.h:2947
static constexpr T squarePi_2()
Returns the square of PI half i.e., (PI/2)^2.
Definition: Numeric.h:968
static T floor(const T value)
Returns the largest integer value that is not greater than the given value.
Definition: Numeric.h:2026
static constexpr T integerPow(const T x, const unsigned int y)
Returns x raised to the power of y while y is an integer.
Definition: Numeric.h:1882
static constexpr T squarePi()
Returns the square of PI i.e., PI^2.
Definition: Numeric.h:956
static T tan(const T value)
Returns the tangent of a given value.
Definition: Numeric.h:1600
static T normalizedGaussianDistribution3(const T x, const T y, const T z, const T sigmaX, const T sigmaY, const T sigmaZ)
Returns a value of the normalized trivariate Gaussian distribution centered around the origin.
Definition: Numeric.h:3555
static UnsignedTyper< T >::Type secureAbs(const T value)
Returns the absolute value of a given value while the return value is guaranteed to be the absolute v...
Definition: Numeric.h:1356
static T ceil(const T value)
Returns the smallest integer value that is not less than the given value.
Definition: Numeric.h:1988
static constexpr int64_t round64(const T value)
Returns the rounded 64 bit integer value of a given value.
Definition: Numeric.h:2070
static bool angleIsEqual(const T angleA, const T angleB)
Returns whether two angles represent the same angle up to a small epsilon.
Definition: Numeric.h:1819
static constexpr T pi_3()
Returns PI/3 which is equivalent to 60 degree.
Definition: Numeric.h:944
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition: Numeric.h:1495
static T angleAdjustPositiveHalf(const T angle)
Adjusts an arbitrary angle into the range of [0.0, PI).
Definition: Numeric.h:1779
static constexpr bool isInsideWeakRange(const T lower, const T value, const T upper)
Returns whether a value lies between a given range up to a weak epsilon border.
Definition: Numeric.h:2881
static T normalizedGaussianDistribution2(const T x, const T y, const T sigmaX, const T sigmaY)
Returns a value of the normalized bivariate Gaussian distribution centered around the origin.
Definition: Numeric.h:3500
static bool isEqual(const T first, const T second, const T referenceEpsilon)
Returns whether two values are equal up to a dynamic epsilon which is adjusted due to the magnitude o...
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition: Numeric.h:2087
static constexpr T copySign(const T signReceiver, const T signProvider)
Copies the sign of a given value to another one.
Definition: Numeric.h:3264
static constexpr T rad2deg(const T rad)
Converts rad to deg.
Definition: Numeric.h:3238
static T cos(const T value)
Returns the cosine of a given value.
Definition: Numeric.h:1584
static T gaussianDistribution3(const T x, const T y, const T z, const T sigmaX, const T sigmaY, const T sigmaZ)
Returns a value of the trivariate Gaussian distribution centered around the origin.
Definition: Numeric.h:3525
static T dot(const T *vectorA, const T *vectorB, const size_t size)
Returns the dot product for two vectors.
Definition: Numeric.h:1751
static bool isInsideValueRange(const TValue &value)
Returns whether a given value of an arbitrary data type fits into the value range of 'T'.
Definition: Numeric.h:3134
static T acos(const T value)
Returns the arccosine of a given value.
Definition: Numeric.h:2907
static constexpr T invertSign(const T signReceiver, const T signProvider)
Copies the inverted sign of a given value to another one.
Definition: Numeric.h:3338
static constexpr T inf()
Returns a value which is positive infinity.
Definition: Numeric.h:3037
static constexpr bool isNotEqualEps(const T value)
Returns whether a value is not smaller than or equal to a small epsilon.
Definition: Numeric.h:2237
static bool angleIsWeakEqual(const T angleA, const T angleB)
Returns whether two angles represent the same angle up to a weak epsilon.
Definition: Numeric.h:1825
static T angleDistance(const T angleA, const T angleB)
Returns the angular difference (distance between two angles).
Definition: Numeric.h:1846
static bool isNotEqual(const T first, const T second)
Returns whether two values are not equal up to a small epsilon.
Definition: Numeric.h:2613
static T summedSqr(const T *values, const size_t number)
Returns the summed squares of a given values.
Definition: Numeric.h:1514
static T log2(const T value)
Returns the logarithm to base 2 of a given value.
Definition: Numeric.h:1683
static constexpr T maxValue()
Returns the max scalar value.
Definition: Numeric.h:3244
static T asin(const T value)
Returns the arcsine of a given value.
Definition: Numeric.h:2887
static bool isNotWeakEqual(const T first, const T second)
Returns whether two values are not equal up to a weak epsilon.
Definition: Numeric.h:2686
static constexpr T binomialCoefficient(const T &n, const T &k)
Returns the binomial coefficient for two binomial parameters.
Definition: Numeric.h:1957
T Type
Definition of the unsigned data type, if existing.
Definition: DataType.h:339
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition: base/Utilities.h:1029
NumericT< Scalar > Numeric
Definition of a Numeric class.
Definition: Numeric.h:26
NumericT< float > NumericF
Definition of a Numeric class with float values.
Definition: Numeric.h:47
NumericT< double > NumericD
Definition of a Numeric class with double values.
Definition: Numeric.h:40
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15