37#include <vnl/vnl_math.h>
44#include <vxl_version.h>
55static constexpr double e = vnl_math::e;
57static constexpr double log2e = vnl_math::log2e;
59static constexpr double log10e = vnl_math::log10e;
61static constexpr double ln2 = vnl_math::ln2;
63static constexpr double ln10 = vnl_math::ln10;
65static constexpr double pi = vnl_math::pi;
67static constexpr double twopi = vnl_math::twopi;
69static constexpr double pi_over_2 = vnl_math::pi_over_2;
71static constexpr double pi_over_4 = vnl_math::pi_over_4;
81static constexpr double sqrt2pi = vnl_math::sqrt2pi;
87static constexpr double sqrt2 = vnl_math::sqrt2;
89static constexpr double sqrt1_2 = vnl_math::sqrt1_2;
91static constexpr double sqrt1_3 = vnl_math::sqrt1_3;
93static constexpr double euler = vnl_math::euler;
96static constexpr double eps = vnl_math::eps;
97static constexpr double sqrteps = vnl_math::sqrteps;
99static constexpr float float_eps = vnl_math::float_eps;
105#define itkTemplateFloatingToIntegerMacro(name) \
106 template <typename TReturn, typename TInput> \
107 inline constexpr auto name(TInput x) \
109 if constexpr (sizeof(TReturn) <= 4) \
111 return static_cast<TReturn>(Detail::name##_32(x)); \
113 else if constexpr (sizeof(TReturn) <= 8) \
115 return static_cast<TReturn>(Detail::name##_64(x)); \
119 return static_cast<TReturn>(Detail::name##_base<TReturn, TInput>(x)); \
175template <typename TReturn, typename TInput>
208#undef itkTemplateFloatingToIntegerMacro
210template <
typename TReturn,
typename TInput>
217 auto ret =
static_cast<TReturn
>(x);
218 if constexpr (
sizeof(TReturn) >
sizeof(TInput) &&
225 else if constexpr (
sizeof(TReturn) >=
sizeof(TInput))
233 else if (
static_cast<TInput
>(ret) != x ||
271 return representOutput.
asFloat;
314 const T absDifference = std::abs(x1 - x2);
315 if (absDifference <= maxAbsoluteDifference)
324 if (std::signbit(x1) != std::signbit(x2))
330 return ulps <= maxUlps;
344 template <
typename TFloatType1,
typename TFloatType2>
351 template <
typename TFloatType1,
typename TFloatType2>
358 template <
typename TFloatType1,
typename TFloatType2>
365 template <
typename TFloatType1,
typename TFloatType2>
372 template <
typename TFloatType1,
typename TFloatType2>
382 template <
typename TFloatType,
typename TIntType>
392 template <
typename TIntType,
typename TFloatType>
402 template <
typename TSignedInt,
typename TUn
signedInt>
406 if (signedVariable < 0)
414 return signedVariable ==
static_cast<TSignedInt
>(unsignedVariable);
420 template <
typename TUn
signedInt,
typename TSignedInt>
430 template <
typename TIntegerType1,
typename TIntegerType2>
441template <
bool TInput1IsIntger,
bool TInput1IsSigned,
bool TInput2IsInteger,
bool TInput2IsSigned>
456struct AlmostEqualsFunctionSelector<false, true, true, true>
463struct AlmostEqualsFunctionSelector<false, true, true, false>
470struct AlmostEqualsFunctionSelector<true, false, false, true>
513template <
typename TInputType1,
typename TInputType2>
514struct AlmostEqualsScalarImplementer
516 static constexpr bool TInputType1IsInteger = std::is_integral_v<TInputType1>;
517 static constexpr bool TInputType1IsSigned = std::is_signed_v<TInputType1>;
518 static constexpr bool TInputType2IsInteger = std::is_integral_v<TInputType2>;
519 static constexpr bool TInputType2IsSigned = std::is_signed_v<TInputType2>;
521 using SelectedVersion =
typename AlmostEqualsFunctionSelector<TInputType1IsInteger,
523 TInputType2IsInteger,
524 TInputType2IsSigned>::SelectedVersion;
530template <
typename TScalarType1,
typename TScalarType2>
532AlmostEqualsScalarComparer(TScalarType1 x1, TScalarType2 x2)
534 return AlmostEqualsScalarImplementer<TScalarType1, TScalarType2>::SelectedVersion::
535 template AlmostEqualsFunction<TScalarType1, TScalarType2>(x1, x2);
542struct AlmostEqualsScalarVsScalar
544 template <
typename TScalarType1,
typename TScalarType2>
546 AlmostEqualsFunction(TScalarType1 x1, TScalarType2 x2)
548 return AlmostEqualsScalarComparer(x1, x2);
554struct AlmostEqualsComplexVsComplex
556 template <
typename TComplexType1,
typename TComplexType2>
558 AlmostEqualsFunction(TComplexType1 x1, TComplexType2 x2)
560 return AlmostEqualsScalarComparer(x1.real(), x2.real()) && AlmostEqualsScalarComparer(x1.imag(), x2.imag());
567struct AlmostEqualsScalarVsComplex
569 template <
typename TScalarType,
typename TComplexType>
571 AlmostEqualsFunction(TScalarType scalarVariable, TComplexType complexVariable)
577 return AlmostEqualsScalarComparer(scalarVariable, complexVariable.real());
581struct AlmostEqualsComplexVsScalar
583 template <
typename TComplexType,
typename TScalarType>
585 AlmostEqualsFunction(TComplexType complexVariable, TScalarType scalarVariable)
587 return AlmostEqualsScalarVsComplex::AlmostEqualsFunction(scalarVariable, complexVariable);
594template <
bool T1IsComplex,
bool T2IsComplex>
595struct AlmostEqualsComplexChooser
597 using ChosenVersion = AlmostEqualsScalarVsScalar;
601struct AlmostEqualsComplexChooser<true, true>
603 using ChosenVersion = AlmostEqualsComplexVsComplex;
607struct AlmostEqualsComplexChooser<false, true>
609 using ChosenVersion = AlmostEqualsScalarVsComplex;
613struct AlmostEqualsComplexChooser<true, false>
615 using ChosenVersion = AlmostEqualsComplexVsScalar;
623template <
typename T1,
typename T2>
624struct AlmostEqualsComplexImplementer
626 static constexpr bool T1IsComplex = NumericTraits<T1>::IsComplex;
627 static constexpr bool T2IsComplex = NumericTraits<T2>::IsComplex;
629 using ChosenVersion =
typename AlmostEqualsComplexChooser<T1IsComplex, T2IsComplex>::ChosenVersion;
678template <
typename T1,
typename T2>
682 return Detail::AlmostEqualsComplexImplementer<T1, T2>::ChosenVersion::AlmostEqualsFunction(x1, x2);
686template <
typename T1,
typename T2>
716template <
typename TInput1,
typename TInput2>
721 ITK_GCC_SUPPRESS_Wfloat_equal
727template <
typename TInput1,
typename TInput2>
740template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
751 if (n == 2 || n == 3)
755 if (n % 2 == 0 || n % 3 == 0)
760 for (T x = 5; x <= n / x; x += 6)
762 if (n % x == 0 || n % (x + 2) == 0)
773template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
796template <
typename TReturnType = u
intmax_t>
800 static_assert(std::is_unsigned_v<TReturnType>,
"UnsignedProduct only supports unsigned return types");
804 return (a == 0) || (b == 0) ||
805 (((
static_cast<TReturnType
>(a * b) / a) == b) && ((
static_cast<TReturnType
>(a * b) / b) == a))
806 ?
static_cast<TReturnType
>(a * b)
807 : (assert(!
"UnsignedProduct overflow!"), 0);
818template <
typename TReturnType = u
intmax_t>
820UnsignedPower(
const uintmax_t base,
const uintmax_t exponent)
noexcept -> TReturnType
822 static_assert(std::is_unsigned_v<TReturnType>,
"UnsignedPower only supports unsigned return types");
826 return (exponent == 0) ? (assert(base > 0), 1)
827 : (exponent == 1) ? base
843using vnl_math::angle_0_to_2pi;
844using vnl_math::angle_minuspi_to_pi;
845using vnl_math::rnd_halfinttoeven;
846using vnl_math::rnd_halfintup;
848using vnl_math::floor;
852using vnl_math::remainder_truncated;
853using vnl_math::remainder_floored;
856using vnl_math::squared_magnitude;
882 if constexpr (std::is_same_v<T, bool>)
887 else if constexpr (std::is_integral_v<T>)
889 if constexpr (std::is_signed_v<T>)
895 if constexpr (
sizeof(T) <=
sizeof(int))
897#if __cplusplus >= 202302L
898 return static_cast<std::make_unsigned_t<T>
>(std::abs(
static_cast<int>(x)));
900 return static_cast<std::make_unsigned_t<T>
>((x < T(0)) ? -x : x);
903 else if constexpr (
sizeof(T) <=
sizeof(
long int))
905#if __cplusplus >= 202302L
906 return static_cast<std::make_unsigned_t<T>
>(std::abs(
static_cast<long int>(x)));
908 return static_cast<std::make_unsigned_t<T>
>((x < T(0)) ? -x : x);
911 else if constexpr (
sizeof(T) ==
sizeof(
long long int))
914#if __cplusplus >= 202302L
915 return static_cast<std::make_unsigned_t<T>
>(std::abs(
static_cast<long long int>(x)));
917 return static_cast<std::make_unsigned_t<T>
>((x < T(0)) ? -x : x);
935 else if constexpr (std::is_floating_point_v<T>)
937#if __cplusplus >= 202302L
951 return std::abs<T>(x);
954#if !defined(ITK_FUTURE_LEGACY_REMOVE)
Define additional traits for native types such as int or float.
static constexpr T max(const T &)
static bool IsPositive(T val)
#define itkConceptMacro(name, concept)
#define itkTemplateFloatingToIntegerMacro(name)
RoundHalfIntegerToEven(TInput x) template< TReturn
Round towards nearest integer.
constexpr T GreatestPrimeFactor(T n)
bool AlmostEquals(T1 x1, T2 x2)
Provide consistent equality checks between values of potentially different scalar or complex types.
static constexpr double sqrt2pi
constexpr auto UnsignedPower(const uintmax_t base, const uintmax_t exponent) noexcept -> TReturnType
static constexpr double sqrt1_2
static constexpr double eps
constexpr auto Absolute(T x) noexcept
Returns the absolute value of a number.
TInput TInput auto CastWithRangeCheck(TInput x)
bool NotAlmostEquals(T1 x1, T2 x2)
TInput Ceil(TInput x) template< typename TReturn
static constexpr double pi_over_2
constexpr bool IsPrime(T n)
static constexpr double one_over_sqrt2pi
static constexpr double pi_over_4
TInput RoundHalfIntegerUp(TInput x) template< typename TReturn
Round towards nearest integer (This is a synonym for RoundHalfIntegerUp)
constexpr bool ExactlyEquals(const TInput1 &x1, const TInput2 &x2)
Return the result of an exact comparison between two scalar values of potentially different types.
static constexpr double sqrteps
static constexpr double two_over_sqrtpi
static constexpr double one_over_pi
constexpr auto UnsignedProduct(const uintmax_t a, const uintmax_t b) noexcept
static constexpr double ln2
Floor(TInput x) template< TReturn
Round towards minus infinity.
static constexpr double euler
euler constant
TInput TInput constexpr auto Round(TInput x)
static constexpr float float_sqrteps
static constexpr float float_eps
static constexpr double ln10
static constexpr double twopi
static constexpr double sqrt2
constexpr bool NotExactlyEquals(const TInput1 &x1, const TInput2 &x2)
bool FloatAlmostEqual(T x1, T x2, typename Detail::FloatIEEE< T >::IntType maxUlps=4, typename Detail::FloatIEEE< T >::FloatType maxAbsoluteDifference=0.1 *itk::NumericTraits< T >::epsilon())
Compare two floats and return if they are effectively equal.
static constexpr double pi
static constexpr double deg_per_rad
static constexpr double two_over_pi
static constexpr double e
static constexpr double sqrt1_3
static constexpr double pi_over_180
constexpr Detail::FloatIEEE< T >::IntType FloatDifferenceULP(T x1, T x2)
Return the signed distance in ULPs (units in the last place) between two floats.
constexpr T FloatAddULP(T x, typename Detail::FloatIEEE< T >::IntType ulps)
Add the given ULPs (units in the last place) to a float.
static constexpr double log10e
static constexpr double log2e
static bool AlmostEqualsFunction(double x1, double x2)
static bool AlmostEqualsFunction(float x1, double x2)
static bool AlmostEqualsFunction(TFloatType1 x1, TFloatType2 x2)
static bool AlmostEqualsFunction(double x1, float x2)
static bool AlmostEqualsFunction(float x1, float x2)
static bool AlmostEqualsFunction(TFloatType floatingVariable, TIntType integerVariable)
AlmostEqualsPlainOldEquals SelectedVersion
static bool AlmostEqualsFunction(TIntType integerVariable, TFloatType floatingVariable)
static bool AlmostEqualsFunction(TIntegerType1 x1, TIntegerType2 x2)
static bool AlmostEqualsFunction(TSignedInt signedVariable, TUnsignedInt unsignedVariable)
static bool AlmostEqualsFunction(TUnsignedInt unsignedVariable, TSignedInt signedVariable)
constexpr IntType AsULP() const
typename FloatIEEETraits< T >::IntType IntType