8#ifndef META_OCEAN_MATH_NUMERIC_H
9#define META_OCEAN_MATH_NUMERIC_H
26template <
typename T>
class NumericT;
64 [[nodiscard]]
static constexpr T
pi();
70 [[nodiscard]]
static constexpr T
pi2();
76 [[nodiscard]]
static constexpr T
pi_2();
82 [[nodiscard]]
static constexpr T
pi_3();
88 [[nodiscard]]
static constexpr T
pi_4();
94 [[nodiscard]]
static constexpr T
squarePi();
100 [[nodiscard]]
static constexpr T
squarePi2();
106 [[nodiscard]]
static constexpr T
squarePi_2();
112 [[nodiscard]]
static constexpr T
e();
118 [[nodiscard]]
static constexpr T
eps();
133 [[nodiscard]]
static inline T
abs(
const T value);
149 [[nodiscard]]
static constexpr inline T
sqr(
const T value);
157 [[nodiscard]]
static inline T
sum(
const T* values,
const size_t number);
165 [[nodiscard]]
static inline T
summedSqr(
const T* values,
const size_t number);
173 [[nodiscard]]
static constexpr inline T
sqrDistance(
const T value0,
const T value1);
180 [[nodiscard]]
static inline T
sqrt(
const T value);
187 [[nodiscard]]
static inline std::complex<T>
sqrt(
const std::complex<T>& value);
194 [[nodiscard]]
static inline T
sin(
const T value);
201 [[nodiscard]]
static inline T
cos(
const T value);
208 [[nodiscard]]
static inline T
tan(
const T value);
215 [[nodiscard]]
static inline T
asin(
const T value);
222 [[nodiscard]]
static inline T
acos(
const T value);
229 [[nodiscard]]
static inline T
atan(
const T value);
237 [[nodiscard]]
static inline T
atan2(
const T y,
const T x);
244 [[nodiscard]]
static inline T
exp(
const T value);
251 [[nodiscard]]
static inline T
log(
const T value);
259 [[nodiscard]]
static inline T
log1p(
const T value);
266 [[nodiscard]]
static inline T
log2(
const T value);
273 [[nodiscard]]
static inline T
log10(
const T value);
281 [[nodiscard]]
static inline T
fmod(
const T valueA,
const T valueB);
290 [[nodiscard]]
static inline T
dot(
const T* vectorA,
const T* vectorB,
const size_t size);
319 [[nodiscard]]
static inline bool angleIsEqual(
const T angleA,
const T angleB);
327 [[nodiscard]]
static inline bool angleIsWeakEqual(
const T angleA,
const T angleB);
336 [[nodiscard]]
static inline bool angleIsEqual(
const T angleA,
const T angleB,
const T epsilon);
345 [[nodiscard]]
static inline bool angleIsBelowThreshold(
const T angleA,
const T angleB,
const T threshold);
353 [[nodiscard]]
static inline T
angleDistance(
const T angleA,
const T angleB);
361 [[nodiscard]]
static inline T
pow(
const T x,
const T y);
369 [[nodiscard]]
static inline std::complex<T>
pow(
const std::complex<T>& x,
const T y);
377 [[nodiscard]]
static constexpr T
integerPow(
const T x,
const unsigned int y);
384 [[nodiscard]]
static constexpr inline T
factorial(
const T& value);
400 [[nodiscard]]
static inline T
ceil(
const T value);
407 [[nodiscard]]
static inline T
floor(
const T value);
425 [[nodiscard]]
static constexpr inline int32_t
round32(
const T value);
443 [[nodiscard]]
static constexpr inline int64_t
round64(
const T value);
452 [[nodiscard]]
static constexpr inline T
ratio(
const T nominator,
const T denominator,
const T fallback = T(1));
459 [[nodiscard]]
static constexpr inline bool isEqualEps(
const T value);
466 [[nodiscard]]
static constexpr inline bool isEqualEps(
const std::complex<T>& value);
473 [[nodiscard]]
static constexpr inline bool isWeakEqualEps(
const T value);
480 [[nodiscard]]
static constexpr inline bool isWeakEqualEps(
const std::complex<T>& value);
487 [[nodiscard]]
static constexpr inline bool isNotEqualEps(
const T value);
494 [[nodiscard]]
static constexpr inline bool isNotEqualEps(
const std::complex<T>& value);
508 [[nodiscard]]
static constexpr inline bool isNotWeakEqualEps(
const std::complex<T>& value);
516 [[nodiscard]]
static inline bool isEqual(
const T first,
const T second);
524 [[nodiscard]]
static inline bool isEqual(
const std::complex<T>& first,
const std::complex<T>& second);
532 [[nodiscard]]
static inline bool isWeakEqual(
const T first,
const T second);
540 [[nodiscard]]
static inline bool isWeakEqual(
const std::complex<T>& first,
const std::complex<T>& second);
549 [[nodiscard]]
static inline bool isEqual(
const T first,
const T second,
const T epsilon);
558 [[nodiscard]]
static inline bool isEqual(
const std::complex<T>& first,
const std::complex<T>& second,
const T epsilon);
571 template <
int tMagnitude>
572 [[nodiscard]]
static inline bool isEqual(
const T first,
const T second,
const T referenceEpsilon);
580 [[nodiscard]]
static inline bool isNotEqual(
const T first,
const T second);
588 [[nodiscard]]
static inline bool isNotEqual(
const std::complex<T>& first,
const std::complex<T>& second);
596 [[nodiscard]]
static inline bool isNotWeakEqual(
const T first,
const T second);
604 [[nodiscard]]
static inline bool isNotWeakEqual(
const std::complex<T>& first,
const std::complex<T>& second);
613 [[nodiscard]]
static inline bool isNotEqual(
const T first,
const T second,
const T epsilon);
622 [[nodiscard]]
static inline bool isNotEqual(
const std::complex<T>& first,
const std::complex<T>& second,
const T epsilon);
641 [[nodiscard]]
static constexpr bool isInsideWeakRange(
const T lower,
const T value,
const T upper);
650 [[nodiscard]]
static constexpr bool isBelow(
const T value,
const T upper,
const T epsilon =
NumericT<T>::eps());
659 [[nodiscard]]
static constexpr bool isAbove(
const T value,
const T lower,
const T epsilon =
NumericT<T>::eps());
665 [[nodiscard]]
static constexpr T
nan();
672 [[nodiscard]]
static inline bool isNan(
const T value);
679 [[nodiscard]]
static inline bool isNan(
const std::complex<T>& value);
685 [[nodiscard]]
static constexpr T
inf();
693 [[nodiscard]]
static inline bool isInf(
const T value);
701 [[nodiscard]]
static inline bool isInf(
const std::complex<T>& value);
725 template <
typename TValue>
733 [[nodiscard]]
static constexpr inline T
deg2rad(
const T deg);
740 [[nodiscard]]
static constexpr inline T
rad2deg(
const T rad);
746 [[nodiscard]]
static constexpr inline T
maxValue();
752 [[nodiscard]]
static constexpr inline T
minValue();
759 [[nodiscard]]
static constexpr inline T
sign(
const T& value);
767 [[nodiscard]]
static constexpr inline T
copySign(
const T signReceiver,
const T signProvider);
775 [[nodiscard]]
static constexpr inline T
invertSign(
const T signReceiver,
const T signProvider);
784 [[nodiscard]]
static T
pythagoras(
const T a,
const T b);
830 [[nodiscard]]
static inline T
gaussianDistribution2(
const T x,
const T y,
const T sigmaX,
const T sigmaY);
842 [[nodiscard]]
static inline T
gaussianDistribution2(
const T x,
const T y,
const T x0,
const T y0,
const T sigmaX,
const T sigmaY);
878 [[nodiscard]]
static inline T
gaussianDistribution3(
const T x,
const T y,
const T z,
const T sigmaX,
const T sigmaY,
const T sigmaZ);
893 [[nodiscard]]
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 [[nodiscard]]
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);
928 return T(3.1415926535897932384626433832795);
934 return T(6.283185307179586476925286766559);
940 return T(1.5707963267948966192313216916395);
946 return T(1.0471975511965977461542144610932);
952 return T(0.78539816339744830961566084581988);
958 return T(9.8696044010893586188344909998762);
964 return T(39.478417604357434475337963999505);
970 return T(2.4674011002723396547086227499667);
976 return T(2.71828182845904523536);
1219template <
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);
1355template <
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 if (value == std::numeric_limits<long>::lowest())
1436 return (
unsigned long)(std::numeric_limits<long>::max()) + 1ul;
1439 return (
unsigned long)(::llabs(value));
1459 if (value == std::numeric_limits<long long>::lowest())
1462 return (
unsigned long long)(std::numeric_limits<long long>::max()) + 1ull;
1465 return (
unsigned long long)(::llabs(value));
1498template <
typename T>
1501 return value * value;
1504template <
typename T>
1509 for (
size_t n = 0; n < number; ++n)
1511 result += values[n];
1517template <
typename T>
1522 for (
size_t n = 0; n < number; ++n)
1524 result +=
sqr(values[n]);
1530template <
typename T>
1533 return sqr(value0 - value1);
1536template <
typename T>
1539 ocean_assert(value >= T(0));
1540 return T(::sqrt(value));
1550 ocean_assert(value >= 0.0f);
1551 return ::sqrtf(value);
1561 ocean_assert(value >= 0);
1562 return int(::sqrtf(
float(value)));
1565template <
typename T>
1568 return std::sqrt<T>(value);
1571template <
typename T>
1574 return ::sin(value);
1587template <
typename T>
1590 return ::cos(value);
1603template <
typename T>
1606 return ::tan(value);
1619template <
typename T>
1622 return ::atan(value);
1632 return atanf(value);
1635template <
typename T>
1640 const T angle = ::atan2(y, x);
1646template <
typename T>
1649 return ::exp(value);
1655 return ::expf(value);
1658template <
typename T>
1661 ocean_assert(value > 0);
1662 return ::log(value);
1668 ocean_assert(value > 0);
1669 return ::logf(value);
1672template <
typename T>
1675 ocean_assert(value > -1);
1676 return ::log1p(value);
1682 ocean_assert(value > -1);
1683 return ::log1pf(value);
1686template <
typename T>
1689 ocean_assert(value > 0);
1691#if (defined(OCEAN_COMPILER_MSC) && OCEAN_MSC_VERSION >= 1800) || (OCEAN_CLANG_VERSION >= 30300 && (!defined(__ANDROID__) || !__ANDROID__))
1692 return ::log2(value);
1694 return ::log(value) * 1.44269504088896340736;
1705 ocean_assert(value > 0);
1707#if (defined(OCEAN_COMPILER_MSC) && OCEAN_MSC_VERSION >= 1800) || (OCEAN_CLANG_VERSION >= 30300 && (!defined(__ANDROID__) || !__ANDROID__))
1708 return ::log2f(value);
1710 return ::logf(value) * 1.44269504088896340736f;
1714template <
typename T>
1717 ocean_assert(value > 0);
1718 return ::log10(value);
1724 ocean_assert(value > 0);
1725 return ::log10f(value);
1737 return atan2f(y, x);
1740template <
typename T>
1743 return ::fmod(valueA, valueB);
1753 return fmodf(valueA, valueB);
1756template <
typename T>
1761 for (
size_t n = 0; n < size; ++n)
1763 result += vectorA[n] * vectorB[n];
1769template <
typename T>
1772 const T adjusted = fmod(angle, pi2());
1776 ocean_assert((std::is_same<T, float>::value) || (pi2() + adjusted >= 0 && pi2() + adjusted < pi2()));
1777 return pi2() + adjusted;
1780 ocean_assert(adjusted >= 0 && adjusted < pi2());
1784template <
typename T>
1787 const T adjusted = fmod(angle, pi());
1791 ocean_assert(pi() + adjusted >= 0 && pi() + adjusted < pi());
1792 return pi() + adjusted;
1795 ocean_assert(adjusted >= 0 && adjusted < pi());
1799template <
typename T>
1802 if (angle > -pi() && angle <= pi())
1807 const T adjusted = fmod(angle, pi2());
1809 if (isAbove(adjusted, pi()))
1811 ocean_assert(adjusted - pi2() > -pi() - eps() && adjusted - pi2() <= pi() + eps());
1812 return adjusted - pi2();
1814 else if (isBelow(adjusted, -pi()))
1816 ocean_assert(adjusted + pi2() > -pi() - eps() && adjusted + pi2() <= pi() + eps());
1817 return adjusted + pi2();
1820 ocean_assert(adjusted > -pi() && adjusted <= pi());
1824template <
typename T>
1827 return isEqualEps(angleDistance(angleA, angleB));
1830template <
typename T>
1833 return isWeakEqualEps(angleDistance(angleA, angleB));
1836template <
typename T>
1839 ocean_assert(epsilon >= T(0));
1840 return isEqual(angleDistance(angleA, angleB), T(0), epsilon);
1843template <
typename T>
1846 ocean_assert(threshold < pi());
1848 return isBelow(abs(angleAdjustNull(angleA - angleB)), threshold);
1851template <
typename T>
1854 const T distance = abs(angleAdjustPositive(angleA) - angleAdjustPositive(angleB));
1865template <
typename T>
1871template <
typename T>
1874 return std::pow<T>(x, y);
1887template <
typename T>
1890 return y == 0u ? T(1) : x * integerPow(x, y - 1u);
1893template <
typename T>
1896 ocean_assert(value >= 0);
1897 ocean_assert(T(int64_t(value)) == value);
1906 for (
unsigned int n = 3u; n <= (
unsigned int)value; ++n)
1908 ocean_assert(maxValue() / T(n) >= result);
1961 ocean_assert(
false &&
"Invalid factorial value!");
1965template <
typename T>
1968 ocean_assert(n >= 0 && k >= 0);
1969 ocean_assert(T(int64_t(n)) == n);
1970 ocean_assert(T(int64_t(k)) == k);
1972 if (n <= T(1) || k == T(0) || n == k)
1977 ocean_assert(k < n);
1979 T result = n - k + T(1);
1981 for (
unsigned int i = (
unsigned int)(n - k) + 2u; i <= (
unsigned int)(n); ++i)
1983 ocean_assert(maxValue() / T(i) >= result);
1987 for (
unsigned int i = 2u; i <= (
unsigned int)(k); ++i)
1989 ocean_assert((result / T(i)) * T(i) == result);
1996template <
typename T>
1999 static_assert(std::is_floating_point<T>::value ==
false,
"Data type must not be a floating point!");
2011 return ::ceilf(value);
2021 return ::ceil(value);
2031 return ::ceill(value);
2034template <
typename T>
2037 static_assert(std::is_floating_point<T>::value ==
false,
"Data type must not be a floating point!");
2049 return ::floorf(value);
2059 return ::floor(value);
2069 return ::floorl(value);
2072template <
typename T>
2075 return int32_t(value + copySign(T(0.5), value));
2078template <
typename T>
2081 return int64_t(value + copySign(T(0.5), value));
2084template <
typename T>
2087 if (isEqualEps(denominator))
2092 return nominator / denominator;
2095template <
typename T>
2098 ocean_assert(isNan(value) ==
false);
2099 ocean_assert((fabs(value) <= eps()) == (-eps() <= value && value <= eps()));
2101 return -eps() <= value && value <= eps();
2107 return value == (
signed char)(0);
2113 return value == (
unsigned char)(0);
2119 return value == short(0);
2125 return value == (
unsigned short)(0);
2149 return value == 0ul;
2155 return value == 0ll;
2161 return value == 0ull;
2164template <
typename T>
2167 return isEqualEps(value.real()) && isEqualEps(value.imag());
2170template <
typename T>
2173 ocean_assert(isNan(value) ==
false);
2174 ocean_assert((fabs(value) <= weakEps()) == (-weakEps() <= value && value <= weakEps()));
2176 return -weakEps() <= value && value <= weakEps();
2182 return value == (
signed char)(0);
2188 return value == (
unsigned char)(0);
2194 return value == short(0);
2200 return value == (
unsigned short)(0);
2224 return value == 0ul;
2230 return value == 0ll;
2236 return value == 0ull;
2239template <
typename T>
2242 return isWeakEqualEps(value.real()) && isWeakEqualEps(value.imag());
2245template <
typename T>
2248 ocean_assert(isNan(value) ==
false);
2249 ocean_assert((fabs(value) > eps()) == (value > eps() || value < -eps()));
2251 return value > eps() || value < -eps();
2257 return value != (
signed char)(0);
2263 return value != (
unsigned char)(0);
2269 return value != short(0);
2275 return value != (
unsigned short)(0);
2299 return value != 0ul;
2305 return value != 0ll;
2311 return value != 0ull;
2314template <
typename T>
2317 return value.real() > eps() || value.real() < -eps() || value.imag() > eps() || value.imag() < -eps();
2320template <
typename T>
2323 ocean_assert((fabs(value) > weakEps()) == (value > weakEps() || value < -weakEps()));
2325 return value > weakEps() || value < -weakEps();
2331 return value != (
signed char)(0);
2337 return value != (
unsigned char)(0);
2343 return value != short(0);
2349 return value != (
unsigned short)(0);
2373 return value != 0ul;
2379 return value != 0ll;
2385 return value != 0ull;
2388template <
typename T>
2391 return value.real() > weakEps() || value.real() < -weakEps() || value.imag() > weakEps() || value.imag() < -weakEps();
2394template <
typename T>
2397 return fabs(first - second) <= eps();
2403 return first == second;
2409 return first == second;
2415 return first == second;
2421 return first == second;
2427 return first == second;
2433 return first == second;
2439 return first == second;
2445 return first == second;
2451 return first == second;
2457 return first == second;
2460template <
typename T>
2463 return isEqual(first.real(), second.real()) && isEqual(first.imag(), second.imag());
2466template <
typename T>
2469 ocean_assert(epsilon >= T(0));
2476 ocean_assert(epsilon >= (
signed char)(0));
2477 return std::abs(first - second) <= epsilon;
2483 ocean_assert(epsilon >=
short(0));
2484 return std::abs(first - second) <= epsilon;
2490 ocean_assert(epsilon >= 0);
2491 return std::abs(first - second) <= epsilon;
2497 ocean_assert(epsilon >=
long(0));
2498 return std::abs(first - second) <= epsilon;
2504 ocean_assert(epsilon >= 0ll);
2505 return std::abs(first - second) <= epsilon;
2513 return first - second <= epsilon;
2517 return second - first <= epsilon;
2526 return first - second <= epsilon;
2530 return second - first <= epsilon;
2539 return first - second <= epsilon;
2543 return second - first <= epsilon;
2552 return first - second <= epsilon;
2556 return second - first <= epsilon;
2565 return first - second <= epsilon;
2569 return second - first <= epsilon;
2573template <
typename T>
2576 ocean_assert(epsilon >= T(0));
2577 return isEqual(first.real(), second.real(), epsilon) && isEqual(first.imag(), second.imag(), epsilon);
2580template <
typename T>
2589 return first == second;
2592template <
typename T>
2595 return isWeakEqual(first.real(), second.real()) && isWeakEqual(first.imag(), second.imag());
2598template <
typename T>
2599template <
int tMagnitude>
2602 static_assert(tMagnitude >= -20 && tMagnitude <= 20,
"Invalid reference magnitude");
2603 ocean_assert(referenceEpsilon >= T(0));
2608 if (isEqualEps(maximalAbsValue))
2614 ocean_assert(offsetMagnitude >= 0);
2616 const T adjustedEpsilon = referenceEpsilon *
NumericT<T>::pow(10, T(offsetMagnitude));
2618 return isEqual(first, second, adjustedEpsilon);
2621template <
typename T>
2624 return fabs(first - second) > eps();
2630 return first != second;
2636 return first != second;
2642 return first != second;
2648 return first != second;
2654 return first != second;
2660 return first != second;
2666 return first != second;
2672 return first != second;
2679 return first != second;
2685 return first != second;
2688template <
typename T>
2691 return isNotEqual(first.real(), second.real()) || isNotEqual(first.imag(), second.imag());
2694template <
typename T>
2697 return fabs(first - second) > weakEps();
2703 return first != second;
2709 return first != second;
2715 return first != second;
2721 return first != second;
2727 return first != second;
2733 return first != second;
2739 return first != second;
2745 return first != second;
2751 return first != second;
2757 return first != second;
2760template <
typename T>
2763 return isNotWeakEqual(first.real(), second.real()) || isNotWeakEqual(first.imag(), second.imag());
2766template <
typename T>
2769 ocean_assert(epsilon >= 0);
2770 return fabs(first - second) > epsilon;
2776 ocean_assert(epsilon >= (
signed char)(0));
2777 return std::abs(first - second) > epsilon;
2783 ocean_assert(epsilon >=
short(0));
2784 return std::abs(first - second) > epsilon;
2790 ocean_assert(epsilon >= 0);
2791 return std::abs(first - second) > epsilon;
2797 ocean_assert(epsilon >=
long(0));
2798 return std::abs(first - second) > epsilon;
2804 ocean_assert(epsilon >= 0ll);
2805 return std::abs(first - second) > epsilon;
2813 return first - second > epsilon;
2817 return second - first > epsilon;
2826 return first - second > epsilon;
2830 return second - first > epsilon;
2839 return first - second > epsilon;
2843 return second - first > epsilon;
2852 return first - second > epsilon;
2856 return second - first > epsilon;
2865 return first - second > epsilon;
2869 return second - first > epsilon;
2873template <
typename T>
2876 ocean_assert(epsilon >= 0);
2877 return isNotEqual(first.real(), second.real(), epsilon) || isNotEqual(first.imag(), second.imag(), epsilon);
2880template <
typename T>
2883 ocean_assert(lower <= upper);
2884 ocean_assert(epsilon >= T(0));
2886 return value >= lower - epsilon && value <= upper + epsilon;
2889template <
typename T>
2892 return isInsideRange(lower, value, upper, weakEps());
2895template <
typename T>
2900 return ::asin(max(T(-1), min(T(1), value)));
2912 return asinf(max(-1.0f, min(1.0f, value)));
2915template <
typename T>
2920 return ::acos(max(T(-1), min(T(1), value)));
2932 return acosf(max(-1.0f, min(1.0f, value)));
2935template <
typename T>
2938 static_assert(std::is_floating_point<T>::value,
"Invalid data type!");
2940 ocean_assert(epsilon >= T(0));
2942 return value <= upper + epsilon;
2945template <
typename T>
2948 static_assert(std::is_floating_point<T>::value,
"Invalid data type!");
2950 ocean_assert(epsilon >= T(0));
2952 return lower - epsilon <= value;
2955template <
typename T>
2958 static_assert(std::is_floating_point<T>::value,
"Data type must be a floating point data type");
2960 if constexpr (std::is_same<T, float>::value)
2962 static_assert(
sizeof(float) ==
sizeof(uint32_t),
"Invalid data type!");
2964 constexpr uint32_t integerValue = 0x7FC00000u;
2966 float floatValue = 0.0f;
2967 memcpy(&floatValue, &integerValue,
sizeof(integerValue));
2969 return T(floatValue);
2973 static_assert(std::is_same<T, double>::value,
"Invalid data type!");
2974 static_assert(
sizeof(double) ==
sizeof(uint64_t),
"Invalid data type!");
2976 constexpr uint64_t integerValue = 0x7FF8000000000000ull;
2978 double doubleValue = 0.0;
2979 memcpy(&doubleValue, &integerValue,
sizeof(integerValue));
2981 return T(doubleValue);
2991 static_assert(
sizeof(uint32_t) ==
sizeof(value),
"Invalid value!");
2996 memcpy(&tmpValue, &value,
sizeof(tmpValue));
2998 constexpr uint32_t exponentBitsAllOne = 0x7F800000u;
2999 constexpr uint32_t mantissaBitsAllOne = 0x007FFFFFu;
3001 const bool allExponentBitsAreOne = (tmpValue & exponentBitsAllOne) == exponentBitsAllOne;
3002 const bool mantissaIsNotZero = (tmpValue & mantissaBitsAllOne) != 0u;
3004 return allExponentBitsAreOne && mantissaIsNotZero;
3013 static_assert(
sizeof(uint64_t) ==
sizeof(value),
"Invalid value!");
3018 memcpy(&tmpValue, &value,
sizeof(tmpValue));
3020 constexpr uint64_t exponentBitsAllOne = 0x7FF0000000000000ull;
3021 constexpr uint64_t mantissaBitsAllOne = 0x000FFFFFFFFFFFFFull;
3023 const bool allExponentBitsAreOne = (tmpValue & exponentBitsAllOne) == exponentBitsAllOne;
3024 const bool mantissaIsNotZero = (tmpValue & mantissaBitsAllOne) != 0ull;
3026 return allExponentBitsAreOne && mantissaIsNotZero;
3029template <
typename T>
3035 ocean_assert(std::is_floating_point<T>::value ==
false);
3039template <
typename T>
3045template <
typename T>
3048 static_assert(std::is_floating_point<T>::value,
"Data type must be a floating point data type");
3050 if constexpr (std::is_same<T, float>::value)
3052 static_assert(
sizeof(float) ==
sizeof(uint32_t),
"Invalid data type!");
3054 constexpr uint32_t integerValue = 0x7F800000u;
3056 float floatValue = 0.0f;
3057 memcpy(&floatValue, &integerValue,
sizeof(integerValue));
3059 return T(floatValue);
3063 static_assert(std::is_same<T, double>::value,
"Invalid data type!");
3064 static_assert(
sizeof(double) ==
sizeof(uint64_t),
"Invalid data type!");
3066 constexpr uint64_t integerValue = 0x7FF0000000000000ull;
3068 double doubleValue = 0.0;
3069 memcpy(&doubleValue, &integerValue,
sizeof(integerValue));
3071 return T(doubleValue);
3081 static_assert(
sizeof(uint32_t) ==
sizeof(value),
"Invalid value!");
3086 memcpy(&tmpValue, &value,
sizeof(tmpValue));
3088 constexpr uint32_t exponentBitsAllOne = 0x7F800000u;
3089 constexpr uint32_t mantissaBitsAllOne = 0x007FFFFFu;
3091 const bool allExponentBitsAreOne = (tmpValue & exponentBitsAllOne) == exponentBitsAllOne;
3092 const bool allMantissaBitsAreZero = (tmpValue & mantissaBitsAllOne) == 0u;
3094 return allExponentBitsAreOne && allMantissaBitsAreZero;
3103 static_assert(
sizeof(uint64_t) ==
sizeof(value),
"Invalid value!");
3108 memcpy(&tmpValue, &value,
sizeof(tmpValue));
3110 constexpr uint64_t exponentBitsAllOne = 0x7FF0000000000000ull;
3111 constexpr uint64_t mantissaBitsAllOne = 0x000FFFFFFFFFFFFFull;
3113 const bool allExponentBitsAreOne = (tmpValue & exponentBitsAllOne) == exponentBitsAllOne;
3114 const bool allMantissaBitsAreZero = (tmpValue & mantissaBitsAllOne) == 0ull;
3116 return allExponentBitsAreOne && allMantissaBitsAreZero;
3119template <
typename T>
3125 ocean_assert(std::is_floating_point<T>::value ==
false);
3132 return std::isinf(value);
3135template <
typename T>
3141template <
typename T>
3142template <
typename TValue>
3145 if constexpr (std::is_same<T, TValue>::value)
3152 if constexpr (std::is_floating_point<T>::value && std::is_floating_point<TValue>::value)
3161 if constexpr (std::is_integral<T>::value && std::is_integral<TValue>::value)
3165 if constexpr (std::is_signed<T>::value == std::is_signed<TValue>::value)
3169 if constexpr (
sizeof(TValue) <=
sizeof(T))
3177 ocean_assert(
sizeof(T) <
sizeof(TValue));
3185 if constexpr (std::is_signed<T>::value)
3187 ocean_assert(!std::is_signed<TValue>::value);
3191 if constexpr (
sizeof(TValue) <
sizeof(T))
3203 if constexpr (std::is_signed<TValue>::value)
3205 ocean_assert(!std::is_signed<T>::value);
3209 if (value < TValue(0))
3214 if constexpr (
sizeof(TValue) <
sizeof(T))
3220 else if constexpr (
sizeof(TValue) ==
sizeof(T))
3224 ocean_assert(value >= TValue(0));
3231 ocean_assert(value >= TValue(0));
3240template <
typename T>
3243 return deg * T(0.017453292519943295769236907684886);
3246template <
typename T>
3249 return rad * T(57.295779513082320876798154814105);
3252template <
typename T>
3255 return std::numeric_limits<T>::max();
3258template <
typename T>
3261 return std::numeric_limits<T>::lowest();
3264template <
typename T>
3267 static_assert(std::numeric_limits<T>::is_signed,
"T must be a signed data type!");
3269 return T((T(0) < value) - (value < T(0)));
3272template <
typename T>
3275 if (signProvider >= 0)
3277 return abs(signReceiver);
3280 return -abs(signReceiver);
3292 const uint64_t value = ((*(uint64_t*)&first) & 0x7FFFFFFFFFFFFFFFull)
3293 | ((*(uint64_t*)&second) & 0x8000000000000000ull);
3297 ocean_assert(
sizeof(uint64_t) ==
sizeof(
double));
3299 const double result = *(
double*)(&value);
3301 double testValue = 0;
3312 ocean_assert(result == testValue || second == 0.0);
3316 return *(
double*)&value;
3326 const uint32_t value = ((*(uint32_t*)&first) & 0x7FFFFFFFu) | ((*(uint32_t*)&second) & 0x80000000u);
3330 ocean_assert(
sizeof(uint32_t) ==
sizeof(
float));
3332 const float result = *(
float*)(&value);
3334 float testValue = 0;
3345 ocean_assert(result == testValue || second == 0.0);
3349 return *(
float*)&value;
3354template <
typename T>
3357 if (signProvider < 0)
3359 return abs(signReceiver);
3362 return -abs(signReceiver);
3374 const uint64_t value = ((*(uint64_t*)&first) & 0x7FFFFFFFFFFFFFFFull)
3375 | ((~*(uint64_t*)&second) & 0x8000000000000000ull);
3379 ocean_assert(
sizeof(uint64_t) ==
sizeof(
double));
3381 const double result = *(
double*)&value;
3383 double testValue = 0;
3394 ocean_assert(result == testValue);
3399 return *(
double*)&value;
3409 const uint32_t value = ((*(uint32_t*)&first) & 0x7FFFFFFFu) | ((~*(uint32_t*)&second) & 0x80000000u);
3413 ocean_assert(
sizeof(uint32_t) ==
sizeof(
float));
3415 const float result = *(
float*)&value;
3417 double testValue = 0;
3428 ocean_assert(result == testValue);
3432 return *(
float*)&value;
3437template <
typename T>
3445 const T factor = absB / absA;
3446 return absA * sqrt(1 + factor * factor);
3450 const T factor = absA / absB;
3451 return absB * sqrt(1 + factor * factor);
3457template <
typename T>
3460 ocean_assert(sigma > eps());
3462 const T inverseSigma = T(1) / sigma;
3464 return inverseSigma * T(0.3989422804014326779) *
NumericT<T>::exp(T(-0.5) * x * x * inverseSigma * inverseSigma);
3467template <
typename T>
3470 ocean_assert(sigma > eps());
3472 const T inverseSigma = T(1) / sigma;
3473 const T x_x0 = x - x0;
3475 return inverseSigma * T(0.3989422804014326779) *
NumericT<T>::exp(T(-0.5) * x_x0 * x_x0 * inverseSigma * inverseSigma);
3478template <
typename T>
3481 ocean_assert(sigma > eps());
3483 const T inverseSigma = T(1) / sigma;
3488template <
typename T>
3491 ocean_assert(sigma > eps());
3493 const T inverseSigma = T(1) / sigma;
3494 const T x_x0 = x - x0;
3496 return NumericT<T>::exp(T(-0.5) * x_x0 * x_x0 * inverseSigma * inverseSigma);
3499template <
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 inverseSigmaX * inverseSigmaY * T(0.15915494309189533576888) *
NumericT<T>::exp(T(-0.5) * (x * x * inverseSigmaX * inverseSigmaX + y * y * inverseSigmaY * inverseSigmaY));
3510template <
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 inverseSigmaX * inverseSigmaY * T(0.15915494309189533576888) *
NumericT<T>::exp(T(-0.5) * (x_x0 * x_x0 * inverseSigmaX * inverseSigmaX + y_y0 * y_y0 * inverseSigmaY * inverseSigmaY));
3524template <
typename T>
3527 ocean_assert(sigmaX > eps() && sigmaY > eps());
3529 const T inverseSigmaX = T(1) / sigmaX;
3530 const T inverseSigmaY = T(1) / sigmaY;
3532 return NumericT<T>::exp(T(-0.5) * (x * x * inverseSigmaX * inverseSigmaX + y * y * inverseSigmaY * inverseSigmaY));
3535template <
typename T>
3538 ocean_assert(sigmaX > eps() && sigmaY > eps());
3540 const T inverseSigmaX = T(1) / sigmaX;
3541 const T inverseSigmaY = T(1) / sigmaY;
3543 const T x_x0 = x - x0;
3544 const T y_y0 = y - y0;
3546 return NumericT<T>::exp(T(-0.5) * (x_x0 * x_x0 * inverseSigmaX * inverseSigmaX + y_y0 * y_y0 * inverseSigmaY * inverseSigmaY));
3549template <
typename T>
3552 ocean_assert(sigmaX > eps() && sigmaY > eps() && sigmaZ > eps());
3554 const T inverseSigmaX = T(1) / sigmaX;
3555 const T inverseSigmaY = T(1) / sigmaY;
3556 const T inverseSigmaZ = T(1) / sigmaZ;
3558 return inverseSigmaX * inverseSigmaY * inverseSigmaZ * T(0.06349363593424096978576330493464)
3559 *
NumericT<T>::exp(T(-0.5) * (x * x * inverseSigmaX * inverseSigmaX + y * y * inverseSigmaY * inverseSigmaY + z * z * inverseSigmaZ * inverseSigmaZ));
3562template <
typename T>
3565 ocean_assert(sigmaX > eps() && sigmaY > eps() && sigmaZ > eps());
3567 const T inverseSigmaX = T(1) / sigmaX;
3568 const T inverseSigmaY = T(1) / sigmaY;
3569 const T inverseSigmaZ = T(1) / sigmaZ;
3571 const T x_x0 = x - x0;
3572 const T y_y0 = y - y0;
3573 const T z_z0 = z - z0;
3575 return inverseSigmaX * inverseSigmaY * inverseSigmaZ * T(0.06349363593424096978576330493464)
3576 *
NumericT<T>::exp(T(-0.5) * (x_x0 * x_x0 * inverseSigmaX * inverseSigmaX + y_y0 * y_y0 * inverseSigmaY * inverseSigmaY + z_z0 * z_z0 * inverseSigmaZ * inverseSigmaZ));
3579template <
typename T>
3582 ocean_assert(sigmaX > eps() && sigmaY > eps() && sigmaZ > eps());
3584 const T inverseSigmaX = T(1) / sigmaX;
3585 const T inverseSigmaY = T(1) / sigmaY;
3586 const T inverseSigmaZ = T(1) / sigmaZ;
3588 return NumericT<T>::exp(T(-0.5) * (x * x * inverseSigmaX * inverseSigmaX + y * y * inverseSigmaY * inverseSigmaY + z * z * inverseSigmaZ * inverseSigmaZ));
3591template <
typename T>
3594 ocean_assert(sigmaX > eps() && sigmaY > eps() && sigmaZ > eps());
3596 const T inverseSigmaX = T(1) / sigmaX;
3597 const T inverseSigmaY = T(1) / sigmaY;
3598 const T inverseSigmaZ = T(1) / sigmaZ;
3600 const T x_x0 = x - x0;
3601 const T y_y0 = y - y0;
3602 const T z_z0 = z - z0;
3604 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:1770
static constexpr T deg2rad(const T deg)
Converts deg to rad.
Definition Numeric.h:3241
static constexpr bool isNotWeakEqualEps(const T value)
Returns whether a value is not smaller than or equal to a weak epsilon.
Definition Numeric.h:2321
static constexpr T minValue()
Returns the min scalar value.
Definition Numeric.h:3259
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:3265
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:2881
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:1659
static T exp(const T value)
Returns the base-e exponential function of a given value.
Definition Numeric.h:1647
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:1673
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:1620
static T atan2(const T y, const T x)
Returns the arctangent of a given value in radian.
Definition Numeric.h:1636
static constexpr T sqrDistance(const T value0, const T value1)
Returns the square distance between two values.
Definition Numeric.h:1531
static T sin(const T value)
Returns the sine of a given value.
Definition Numeric.h:1572
static bool isInf(const T value)
Returns whether a given value is positive or negative infinity.
Definition Numeric.h:3120
static T pow(const T x, const T y)
Returns x raised to the power of y.
Definition Numeric.h:1866
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:3030
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:1894
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:1715
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:2946
static bool isWeakEqual(const T first, const T second)
Returns whether two values a equal up to a weak epsilon.
Definition Numeric.h:2581
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:3479
static constexpr int32_t round32(const T value)
Returns the rounded 32 bit integer value of a given value.
Definition Numeric.h:2073
static T sum(const T *values, const size_t number)
Returns the sum of given values.
Definition Numeric.h:1505
static constexpr bool isWeakEqualEps(const T value)
Returns whether a value is smaller than or equal to a weak epsilon.
Definition Numeric.h:2171
static T sqrt(const T value)
Returns the square root of a given value.
Definition Numeric.h:1537
static T pythagoras(const T a, const T b)
Returns the length of the hypotenuse of a given right-angled triangle.
Definition Numeric.h:3438
static T fmod(const T valueA, const T valueB)
Returns the floating-point remainder of a given value.
Definition Numeric.h:1741
static T angleAdjustNull(const T angle)
Adjusts an arbitrary angle into the range of (-PI, PI].
Definition Numeric.h:1800
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:1844
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:2395
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:2936
static T gaussianDistribution(const T x, const T sigma)
Returns a value of the univariate Gaussian distribution centered around the origin.
Definition Numeric.h:3458
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:3500
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:2085
static constexpr T nan()
Returns a value which is not a number (nan).
Definition Numeric.h:2956
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:2035
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:1888
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:1604
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:3580
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:1997
static constexpr int64_t round64(const T value)
Returns the rounded 64 bit integer value of a given value.
Definition Numeric.h:2079
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:1825
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:1499
static T angleAdjustPositiveHalf(const T angle)
Adjusts an arbitrary angle into the range of [0.0, PI).
Definition Numeric.h:1785
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:2890
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:3525
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition Numeric.h:2096
static constexpr T copySign(const T signReceiver, const T signProvider)
Copies the sign of a given value to another one.
Definition Numeric.h:3273
static constexpr T rad2deg(const T rad)
Converts rad to deg.
Definition Numeric.h:3247
static T cos(const T value)
Returns the cosine of a given value.
Definition Numeric.h:1588
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:3550
static T dot(const T *vectorA, const T *vectorB, const size_t size)
Returns the dot product for two vectors.
Definition Numeric.h:1757
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:3143
static T acos(const T value)
Returns the arccosine of a given value.
Definition Numeric.h:2916
static constexpr T invertSign(const T signReceiver, const T signProvider)
Copies the inverted sign of a given value to another one.
Definition Numeric.h:3355
static constexpr T inf()
Returns a value which is positive infinity.
Definition Numeric.h:3046
static constexpr bool isNotEqualEps(const T value)
Returns whether a value is not smaller than or equal to a small epsilon.
Definition Numeric.h:2246
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:1831
static T angleDistance(const T angleA, const T angleB)
Returns the angular difference (distance between two angles).
Definition Numeric.h:1852
static bool isNotEqual(const T first, const T second)
Returns whether two values are not equal up to a small epsilon.
Definition Numeric.h:2622
static T summedSqr(const T *values, const size_t number)
Returns the summed squares of a given values.
Definition Numeric.h:1518
static T log2(const T value)
Returns the logarithm to base 2 of a given value.
Definition Numeric.h:1687
static constexpr T maxValue()
Returns the max scalar value.
Definition Numeric.h:3253
static T asin(const T value)
Returns the arcsine of a given value.
Definition Numeric.h:2896
static bool isNotWeakEqual(const T first, const T second)
Returns whether two values are not equal up to a weak epsilon.
Definition Numeric.h:2695
static constexpr T binomialCoefficient(const T &n, const T &k)
Returns the binomial coefficient for two binomial parameters.
Definition Numeric.h:1966
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:1099
The namespace covering the entire Ocean framework.
Definition Accessor.h:15