38#include <vnl/vnl_math.h>
45#include <vxl_version.h>
56static constexpr double e = vnl_math::e;
58static constexpr double log2e = vnl_math::log2e;
60static constexpr double log10e = vnl_math::log10e;
62static constexpr double ln2 = vnl_math::ln2;
64static constexpr double ln10 = vnl_math::ln10;
66static constexpr double pi = vnl_math::pi;
68static constexpr double twopi = vnl_math::twopi;
70static constexpr double pi_over_2 = vnl_math::pi_over_2;
72static constexpr double pi_over_4 = vnl_math::pi_over_4;
82static constexpr double sqrt2pi = vnl_math::sqrt2pi;
88static constexpr double sqrt2 = vnl_math::sqrt2;
90static constexpr double sqrt1_2 = vnl_math::sqrt1_2;
92static constexpr double sqrt1_3 = vnl_math::sqrt1_3;
94static constexpr double euler = vnl_math::euler;
97static constexpr double eps = vnl_math::eps;
98static constexpr double sqrteps = vnl_math::sqrteps;
106#define itkTemplateFloatingToIntegerMacro(name) \
107 template <typename TReturn, typename TInput> \
108 inline constexpr auto name(TInput x) \
110 if constexpr (sizeof(TReturn) <= 4) \
112 return static_cast<TReturn>(Detail::name##_32(x)); \
114 else if constexpr (sizeof(TReturn) <= 8) \
116 return static_cast<TReturn>(Detail::name##_64(x)); \
120 return static_cast<TReturn>(Detail::name##_base<TReturn, TInput>(x)); \
176template <typename TReturn, typename TInput>
209#undef itkTemplateFloatingToIntegerMacro
211template <
typename TReturn,
typename TInput>
218 auto ret =
static_cast<TReturn
>(x);
219 if constexpr (
sizeof(TReturn) >
sizeof(TInput) &&
226 else if constexpr (
sizeof(TReturn) >=
sizeof(TInput))
234 else if (
static_cast<TInput
>(ret) != x ||
272 return representOutput.
asFloat;
315 const T absDifference = std::abs(x1 - x2);
316 if (absDifference <= maxAbsoluteDifference)
325 if (std::signbit(x1) != std::signbit(x2))
331 return ulps <= maxUlps;
345 template <
typename TFloatType1,
typename TFloatType2>
352 template <
typename TFloatType1,
typename TFloatType2>
359 template <
typename TFloatType1,
typename TFloatType2>
366 template <
typename TFloatType1,
typename TFloatType2>
373 template <
typename TFloatType1,
typename TFloatType2>
383 template <
typename TFloatType,
typename TIntType>
393 template <
typename TIntType,
typename TFloatType>
403 template <
typename TSignedInt,
typename TUn
signedInt>
407 if (signedVariable < 0)
415 return signedVariable ==
static_cast<TSignedInt
>(unsignedVariable);
421 template <
typename TUn
signedInt,
typename TSignedInt>
431 template <
typename TIntegerType1,
typename TIntegerType2>
442template <
bool TInput1IsIntger,
bool TInput1IsSigned,
bool TInput2IsInteger,
bool TInput2IsSigned>
457struct AlmostEqualsFunctionSelector<false, true, true, true>
464struct AlmostEqualsFunctionSelector<false, true, true, false>
471struct AlmostEqualsFunctionSelector<true, false, false, true>
514template <
typename TInputType1,
typename TInputType2>
515struct AlmostEqualsScalarImplementer
517 static constexpr bool TInputType1IsInteger = std::is_integral_v<TInputType1>;
518 static constexpr bool TInputType1IsSigned = std::is_signed_v<TInputType1>;
519 static constexpr bool TInputType2IsInteger = std::is_integral_v<TInputType2>;
520 static constexpr bool TInputType2IsSigned = std::is_signed_v<TInputType2>;
522 using SelectedVersion =
typename AlmostEqualsFunctionSelector<TInputType1IsInteger,
524 TInputType2IsInteger,
525 TInputType2IsSigned>::SelectedVersion;
531template <
typename TScalarType1,
typename TScalarType2>
533AlmostEqualsScalarComparer(TScalarType1 x1, TScalarType2 x2)
535 return AlmostEqualsScalarImplementer<TScalarType1, TScalarType2>::SelectedVersion::
536 template AlmostEqualsFunction<TScalarType1, TScalarType2>(x1, x2);
543struct AlmostEqualsScalarVsScalar
545 template <
typename TScalarType1,
typename TScalarType2>
547 AlmostEqualsFunction(TScalarType1 x1, TScalarType2 x2)
549 return AlmostEqualsScalarComparer(x1, x2);
555struct AlmostEqualsComplexVsComplex
557 template <
typename TComplexType1,
typename TComplexType2>
559 AlmostEqualsFunction(TComplexType1 x1, TComplexType2 x2)
561 return AlmostEqualsScalarComparer(x1.real(), x2.real()) && AlmostEqualsScalarComparer(x1.imag(), x2.imag());
568struct AlmostEqualsScalarVsComplex
570 template <
typename TScalarType,
typename TComplexType>
572 AlmostEqualsFunction(TScalarType scalarVariable, TComplexType complexVariable)
578 return AlmostEqualsScalarComparer(scalarVariable, complexVariable.real());
582struct AlmostEqualsComplexVsScalar
584 template <
typename TComplexType,
typename TScalarType>
586 AlmostEqualsFunction(TComplexType complexVariable, TScalarType scalarVariable)
588 return AlmostEqualsScalarVsComplex::AlmostEqualsFunction(scalarVariable, complexVariable);
595template <
bool T1IsComplex,
bool T2IsComplex>
596struct AlmostEqualsComplexChooser
598 using ChosenVersion = AlmostEqualsScalarVsScalar;
602struct AlmostEqualsComplexChooser<true, true>
604 using ChosenVersion = AlmostEqualsComplexVsComplex;
608struct AlmostEqualsComplexChooser<false, true>
610 using ChosenVersion = AlmostEqualsScalarVsComplex;
614struct AlmostEqualsComplexChooser<true, false>
616 using ChosenVersion = AlmostEqualsComplexVsScalar;
624template <
typename T1,
typename T2>
625struct AlmostEqualsComplexImplementer
627 static constexpr bool T1IsComplex = NumericTraits<T1>::IsComplex;
628 static constexpr bool T2IsComplex = NumericTraits<T2>::IsComplex;
630 using ChosenVersion =
typename AlmostEqualsComplexChooser<T1IsComplex, T2IsComplex>::ChosenVersion;
679template <
typename T1,
typename T2>
683 return Detail::AlmostEqualsComplexImplementer<T1, T2>::ChosenVersion::AlmostEqualsFunction(x1, x2);
687template <
typename T1,
typename T2>
717template <
typename TInput1,
typename TInput2>
722 ITK_GCC_SUPPRESS_Wfloat_equal
728template <
typename TInput1,
typename TInput2>
741template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
752 if (n == 2 || n == 3)
756 if (n % 2 == 0 || n % 3 == 0)
761 for (T x = 5; x <= n / x; x += 6)
763 if (n % x == 0 || n % (x + 2) == 0)
774template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
797template <
typename TReturnType = u
intmax_t>
801 static_assert(std::is_unsigned_v<TReturnType>,
"UnsignedProduct only supports unsigned return types");
805 return (a == 0) || (b == 0) ||
806 (((
static_cast<TReturnType
>(a * b) / a) == b) && ((
static_cast<TReturnType
>(a * b) / b) == a))
807 ?
static_cast<TReturnType
>(a * b)
808 : (assert(!
"UnsignedProduct overflow!"), 0);
819template <
typename TReturnType = u
intmax_t>
821UnsignedPower(
const uintmax_t base,
const uintmax_t exponent)
noexcept -> TReturnType
823 static_assert(std::is_unsigned_v<TReturnType>,
"UnsignedPower only supports unsigned return types");
827 return (exponent == 0) ? (assert(base > 0), 1)
828 : (exponent == 1) ? base
844using vnl_math::angle_0_to_2pi;
845using vnl_math::angle_minuspi_to_pi;
846using vnl_math::rnd_halfinttoeven;
847using vnl_math::rnd_halfintup;
849using vnl_math::floor;
853using vnl_math::remainder_truncated;
854using vnl_math::remainder_floored;
857using vnl_math::squared_magnitude;
884 if constexpr (std::is_same_v<T, bool>)
889 else if constexpr (std::is_integral_v<T>)
891 if constexpr (std::is_signed_v<T>)
893 using UnsignedType = std::make_unsigned_t<T>;
894 using Limits = std::numeric_limits<T>;
897 constexpr UnsignedType absoluteValueOfMin{ UnsignedType{ Limits::max() } + UnsignedType{ 1 } };
899 return static_cast<UnsignedType
>((x < 0) ? (x == Limits::min()) ? absoluteValueOfMin : -x : x);
915 else if constexpr (std::is_floating_point_v<T>)
927 return std::abs<T>(x);
930#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