ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkMath.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18/*=========================================================================
19 *
20 * Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21 *
22 * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23 *
24 * For complete copyright, license and disclaimer of warranty information
25 * please refer to the NOTICE file at the top of the ITK source tree.
26 *
27 *=========================================================================*/
28#ifndef itkMath_h
29#define itkMath_h
30
31#include <cassert>
32#include <complex>
33#include <cmath>
34#include <limits>
35#include <type_traits>
36// _MSVC_LANG tracks /std: even when __cplusplus stays 199711L (no /Zc:__cplusplus),
37// matching the STL condition under which <limits> defines __cpp_lib_math_constants.
38#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
39# include <numbers>
40#endif
41#include "itkMathDetail.h"
42#include "itkConceptChecking.h"
43#if !defined(ITK_FUTURE_LEGACY_REMOVE)
44// itk::Math no longer uses vnl_math; kept transitionally for downstream vnl_math:: users.
45# include <vnl/vnl_math.h>
46#endif
47
48namespace itk::Math
49{
50// These mathematical constants originate from VXL's vnl_math.h: correctly-rounded
51// double-precision literals (OEIS references in vnl_math.h), defined identically under
52// every C++ standard level and verified against C++20 <numbers> below.
53
55inline constexpr double e = 2.71828182845904523536;
57inline constexpr double log2e = 1.44269504088896340736;
59inline constexpr double log10e = 0.43429448190325182765;
61inline constexpr double ln2 = 0.69314718055994530942;
63inline constexpr double ln10 = 2.30258509299404568402;
65inline constexpr double pi = 3.14159265358979323846;
67inline constexpr double twopi = 6.28318530717958647693;
69inline constexpr double pi_over_2 = 1.57079632679489661923;
71inline constexpr double pi_over_4 = 0.78539816339744830962;
73inline constexpr double pi_over_180 = 0.01745329251994329577;
75inline constexpr double one_over_pi = 0.31830988618379067154;
77inline constexpr double two_over_pi = 0.63661977236758134308;
79inline constexpr double deg_per_rad = 57.2957795130823208768;
81inline constexpr double sqrt2pi = 2.50662827463100050242;
83inline constexpr double two_over_sqrtpi = 1.12837916709551257390;
85inline constexpr double one_over_sqrt2pi = 0.39894228040143267794;
87inline constexpr double sqrt2 = 1.41421356237309504880;
89inline constexpr double sqrt1_2 = 0.70710678118654752440;
91inline constexpr double sqrt1_3 = 0.57735026918962576451;
93inline constexpr double euler = 0.57721566490153286061;
94
95#if defined(__cpp_lib_math_constants)
96// Bit-exactness proof against C++20 <numbers>. sqrt2pi and one_over_sqrt2pi have no
97// exact std::numbers identity (inv_sqrtpi / sqrt2 double-rounds 1 ULP off).
98static_assert(e == std::numbers::e);
99static_assert(log2e == std::numbers::log2e);
100static_assert(log10e == std::numbers::log10e);
101static_assert(ln2 == std::numbers::ln2);
102static_assert(ln10 == std::numbers::ln10);
103static_assert(pi == std::numbers::pi);
104static_assert(twopi == 2 * std::numbers::pi);
105static_assert(pi_over_2 == std::numbers::pi / 2);
106static_assert(pi_over_4 == std::numbers::pi / 4);
107static_assert(pi_over_180 == std::numbers::pi / 180);
108static_assert(one_over_pi == std::numbers::inv_pi);
109static_assert(two_over_pi == 2 * std::numbers::inv_pi);
110static_assert(deg_per_rad == 180 * std::numbers::inv_pi);
111static_assert(two_over_sqrtpi == 2 * std::numbers::inv_sqrtpi);
112static_assert(sqrt2 == std::numbers::sqrt2);
113static_assert(sqrt1_2 == std::numbers::sqrt2 / 2);
114static_assert(sqrt1_3 == std::numbers::inv_sqrt3);
115static_assert(euler == std::numbers::egamma);
116#endif
117
118//: IEEE double machine precision
119inline constexpr double eps = std::numeric_limits<double>::epsilon();
120// sqrt(2^-52) = 2^-26 = 1.490116119384765625e-8 exactly, matching C++26 constexpr std::sqrt(eps);
121// vnl_math::sqrteps used 1.490116119384766e-08, which rounds 1 ULP above (2^-26 + 2^-78).
122inline constexpr double sqrteps = 0x1p-26;
123//: IEEE single machine precision
124inline constexpr float float_eps = std::numeric_limits<float>::epsilon();
125inline constexpr float float_sqrteps = 3.4526698300e-4F;
126
130#define itkTemplateFloatingToIntegerMacro(name) \
131 template <typename TReturn, typename TInput> \
132 inline constexpr auto name(TInput x) \
133 { \
134 if constexpr (sizeof(TReturn) <= 4) \
135 { \
136 return static_cast<TReturn>(Detail::name##_32(x)); \
137 } \
138 else if constexpr (sizeof(TReturn) <= 8) \
139 { \
140 return static_cast<TReturn>(Detail::name##_64(x)); \
141 } \
142 else \
143 { \
144 return static_cast<TReturn>(Detail::name##_base<TReturn, TInput>(x)); \
145 } \
146 }
147
168
169
192
200template <typename TReturn, typename TInput>
201inline constexpr auto
202Round(TInput x)
203{
205}
206
220
221
232
233#undef itkTemplateFloatingToIntegerMacro
234
235template <typename TReturn, typename TInput>
236inline auto
238{
239 itkConceptMacro(OnlyDefinedForIntegerTypes1, (itk::Concept::IsInteger<TReturn>));
240 itkConceptMacro(OnlyDefinedForIntegerTypes2, (itk::Concept::IsInteger<TInput>));
241
242 auto ret = static_cast<TReturn>(x);
243 if constexpr (sizeof(TReturn) > sizeof(TInput) &&
245 {
246 // if the output type is bigger and we are not converting a signed
247 // integer to an unsigned integer then we have no problems
248 return ret;
249 }
250 else if constexpr (sizeof(TReturn) >= sizeof(TInput))
251 {
253 {
254 itk::RangeError _e(__FILE__, __LINE__);
255 throw _e;
256 }
257 }
258 else if (static_cast<TInput>(ret) != x ||
260 {
261 itk::RangeError _e(__FILE__, __LINE__);
262 throw _e;
263 }
264 return ret;
265}
266
274template <typename T>
275inline constexpr typename Detail::FloatIEEE<T>::IntType
277{
278 const Detail::FloatIEEE<T> x1f(x1);
279 const Detail::FloatIEEE<T> x2f(x2);
280 return x1f.AsULP() - x2f.AsULP();
281}
282
290template <typename T>
291inline constexpr T
293{
294 const Detail::FloatIEEE<T> representInput(x);
295 const Detail::FloatIEEE<T> representOutput(representInput.asInt + ulps);
296 return representOutput.asFloat;
297}
298
329template <typename T>
330inline bool
332 T x2,
333 typename Detail::FloatIEEE<T>::IntType maxUlps = 4,
334 typename Detail::FloatIEEE<T>::FloatType maxAbsoluteDifference = 0.1 *
336{
337 // Check if the numbers are really close -- needed
338 // when comparing numbers near zero.
339 const T absDifference = std::abs(x1 - x2);
340 if (absDifference <= maxAbsoluteDifference)
341 {
342 return true;
343 }
344
345 // This check for different signs is necessary for several reasons, see the blog link above.
346 // Subtracting the signed-magnitude representation of floats using twos-complement
347 // math isn't particularly meaningful, and the subtraction would produce a 33-bit
348 // result and overflow an int.
349 if (std::signbit(x1) != std::signbit(x2))
350 {
351 return false;
352 }
353
354 const typename Detail::FloatIEEE<T>::IntType ulps = std::abs(FloatDifferenceULP(x1, x2));
355 return ulps <= maxUlps;
356}
357
358// The following code cannot be moved to the itkMathDetail.h file without introducing circular dependencies
359namespace Detail // The Detail namespace holds the templates used by AlmostEquals
360{
361// The following structs and templates are used to choose
362// which version of the AlmostEquals function
363// should be implemented base on input parameter types
364
365// Structs for choosing AlmostEquals function
366
368{
369 template <typename TFloatType1, typename TFloatType2>
370 static bool
371 AlmostEqualsFunction(TFloatType1 x1, TFloatType2 x2)
372 {
373 return FloatAlmostEqual<double>(x1, x2);
374 }
375
376 template <typename TFloatType1, typename TFloatType2>
377 static bool
378 AlmostEqualsFunction(double x1, double x2)
379 {
380 return FloatAlmostEqual<double>(x1, x2);
381 }
382
383 template <typename TFloatType1, typename TFloatType2>
384 static bool
385 AlmostEqualsFunction(double x1, float x2)
386 {
387 return FloatAlmostEqual<float>(x1, x2);
388 }
389
390 template <typename TFloatType1, typename TFloatType2>
391 static bool
392 AlmostEqualsFunction(float x1, double x2)
393 {
394 return FloatAlmostEqual<float>(x1, x2);
395 }
396
397 template <typename TFloatType1, typename TFloatType2>
398 static bool
399 AlmostEqualsFunction(float x1, float x2)
400 {
401 return FloatAlmostEqual<float>(x1, x2);
402 }
403};
404
406{
407 template <typename TFloatType, typename TIntType>
408 static bool
409 AlmostEqualsFunction(TFloatType floatingVariable, TIntType integerVariable)
410 {
411 return FloatAlmostEqual<TFloatType>(floatingVariable, integerVariable);
412 }
413};
414
416{
417 template <typename TIntType, typename TFloatType>
418 static bool
419 AlmostEqualsFunction(TIntType integerVariable, TFloatType floatingVariable)
420 {
421 return AlmostEqualsFloatVsInteger::AlmostEqualsFunction(floatingVariable, integerVariable);
422 }
423};
424
426{
427 template <typename TSignedInt, typename TUnsignedInt>
428 static bool
429 AlmostEqualsFunction(TSignedInt signedVariable, TUnsignedInt unsignedVariable)
430 {
431 if (signedVariable < 0)
432 {
433 return false;
434 }
435 if (unsignedVariable > static_cast<size_t>(itk::NumericTraits<TSignedInt>::max()))
436 {
437 return false;
438 }
439 return signedVariable == static_cast<TSignedInt>(unsignedVariable);
440 }
441};
442
444{
445 template <typename TUnsignedInt, typename TSignedInt>
446 static bool
447 AlmostEqualsFunction(TUnsignedInt unsignedVariable, TSignedInt signedVariable)
448 {
449 return AlmostEqualsSignedVsUnsigned::AlmostEqualsFunction(signedVariable, unsignedVariable);
450 }
451};
452
454{
455 template <typename TIntegerType1, typename TIntegerType2>
456 static bool
457 AlmostEqualsFunction(TIntegerType1 x1, TIntegerType2 x2)
458 {
459 return x1 == x2;
460 }
461};
462// end of structs that choose the specific AlmostEquals function
463
464// Selector structs, these select the correct case based on its types
465// input1 is int? input 1 is signed? input2 is int? input 2 is signed?
466template <bool TInput1IsIntger, bool TInput1IsSigned, bool TInput2IsInteger, bool TInput2IsSigned>
471
473template <>
474struct AlmostEqualsFunctionSelector<false, true, false, true>
475// floating type v floating type
476{
478};
479
480template <>
481struct AlmostEqualsFunctionSelector<false, true, true, true>
482// float vs int
483{
484 using SelectedVersion = AlmostEqualsFloatVsInteger;
485};
486
487template <>
488struct AlmostEqualsFunctionSelector<false, true, true, false>
489// float vs unsigned int
490{
491 using SelectedVersion = AlmostEqualsFloatVsInteger;
492};
493
494template <>
495struct AlmostEqualsFunctionSelector<true, false, false, true>
496// unsigned int vs float
497{
498 using SelectedVersion = AlmostEqualsIntegerVsFloat;
499};
500
501template <>
502struct AlmostEqualsFunctionSelector<true, true, false, true>
503// int vs float
504{
505 using SelectedVersion = AlmostEqualsIntegerVsFloat;
506};
507
508template <>
509struct AlmostEqualsFunctionSelector<true, true, true, false>
510// signed vs unsigned
511{
512 using SelectedVersion = AlmostEqualsSignedVsUnsigned;
513};
514
515template <>
516struct AlmostEqualsFunctionSelector<true, false, true, true>
517// unsigned vs signed
518{
519 using SelectedVersion = AlmostEqualsUnsignedVsSigned;
520};
521
522template <>
523struct AlmostEqualsFunctionSelector<true, true, true, true>
524// signed vs signed
525{
526 using SelectedVersion = AlmostEqualsPlainOldEquals;
527};
528
529template <>
530struct AlmostEqualsFunctionSelector<true, false, true, false>
531// unsigned vs unsigned
532{
533 using SelectedVersion = AlmostEqualsPlainOldEquals;
534};
535// end of AlmostEqualsFunctionSelector structs
536
537// The implementor tells the selector what to do
538template <typename TInputType1, typename TInputType2>
539struct AlmostEqualsScalarImplementer
540{
541 static constexpr bool TInputType1IsInteger = std::is_integral_v<TInputType1>;
542 static constexpr bool TInputType1IsSigned = std::is_signed_v<TInputType1>;
543 static constexpr bool TInputType2IsInteger = std::is_integral_v<TInputType2>;
544 static constexpr bool TInputType2IsSigned = std::is_signed_v<TInputType2>;
545
546 using SelectedVersion = typename AlmostEqualsFunctionSelector<TInputType1IsInteger,
547 TInputType1IsSigned,
548 TInputType2IsInteger,
549 TInputType2IsSigned>::SelectedVersion;
550};
551
552// The AlmostEqualsScalarComparer returns the result of an
553// approximate comparison between two scalar values of
554// potentially different data types.
555template <typename TScalarType1, typename TScalarType2>
556inline bool
557AlmostEqualsScalarComparer(TScalarType1 x1, TScalarType2 x2)
558{
559 return AlmostEqualsScalarImplementer<TScalarType1, TScalarType2>::SelectedVersion::
560 template AlmostEqualsFunction<TScalarType1, TScalarType2>(x1, x2);
561}
562
563// The following structs are used to evaluate approximate comparisons between
564// complex and scalar values of potentially different types.
565
566// Comparisons between scalar types use the AlmostEqualsScalarComparer function.
567struct AlmostEqualsScalarVsScalar
568{
569 template <typename TScalarType1, typename TScalarType2>
570 static bool
571 AlmostEqualsFunction(TScalarType1 x1, TScalarType2 x2)
572 {
573 return AlmostEqualsScalarComparer(x1, x2);
574 }
575};
576
577// Comparisons between two complex values compare the real and imaginary components
578// separately with the AlmostEqualsScalarComparer function.
579struct AlmostEqualsComplexVsComplex
580{
581 template <typename TComplexType1, typename TComplexType2>
582 static bool
583 AlmostEqualsFunction(TComplexType1 x1, TComplexType2 x2)
584 {
585 return AlmostEqualsScalarComparer(x1.real(), x2.real()) && AlmostEqualsScalarComparer(x1.imag(), x2.imag());
586 }
587};
588
589// Comparisons between complex and scalar values first check to see if the imaginary component
590// of the complex value is approximately 0. Then a ScalarComparison is done between the real
591// part of the complex number and the scalar value.
592struct AlmostEqualsScalarVsComplex
593{
594 template <typename TScalarType, typename TComplexType>
595 static bool
596 AlmostEqualsFunction(TScalarType scalarVariable, TComplexType complexVariable)
597 {
598 if (!AlmostEqualsScalarComparer(complexVariable.imag(), typename itk::NumericTraits<TComplexType>::ValueType{}))
599 {
600 return false;
601 }
602 return AlmostEqualsScalarComparer(scalarVariable, complexVariable.real());
603 }
604};
605
606struct AlmostEqualsComplexVsScalar
607{
608 template <typename TComplexType, typename TScalarType>
609 static bool
610 AlmostEqualsFunction(TComplexType complexVariable, TScalarType scalarVariable)
611 {
612 return AlmostEqualsScalarVsComplex::AlmostEqualsFunction(scalarVariable, complexVariable);
613 }
614};
615
616// The AlmostEqualsComplexChooser structs choose the correct case
617// from the input parameter types' IsComplex property
618// The default case is scalar vs scalar
619template <bool T1IsComplex, bool T2IsComplex> // Default is false, false
620struct AlmostEqualsComplexChooser
621{
622 using ChosenVersion = AlmostEqualsScalarVsScalar;
623};
624
625template <>
626struct AlmostEqualsComplexChooser<true, true>
627{
628 using ChosenVersion = AlmostEqualsComplexVsComplex;
629};
630
631template <>
632struct AlmostEqualsComplexChooser<false, true>
633{
634 using ChosenVersion = AlmostEqualsScalarVsComplex;
635};
636
637template <>
638struct AlmostEqualsComplexChooser<true, false>
639{
640 using ChosenVersion = AlmostEqualsComplexVsScalar;
641};
642// End of AlmostEqualsComplexChooser structs.
643
644// The AlmostEqualsComplexImplementer determines which of the input
645// parameters are complex and which are real, and sends that information
646// to the AlmostEqualsComplexChooser structs to determine the proper
647// type of evaluation.
648template <typename T1, typename T2>
649struct AlmostEqualsComplexImplementer
650{
651 static constexpr bool T1IsComplex = NumericTraits<T1>::IsComplex;
652 static constexpr bool T2IsComplex = NumericTraits<T2>::IsComplex;
653
654 using ChosenVersion = typename AlmostEqualsComplexChooser<T1IsComplex, T2IsComplex>::ChosenVersion;
655};
657
658} // end namespace Detail
659
701
702// The AlmostEquals function
703template <typename T1, typename T2>
704inline bool
705AlmostEquals(T1 x1, T2 x2)
706{
707 return Detail::AlmostEqualsComplexImplementer<T1, T2>::ChosenVersion::AlmostEqualsFunction(x1, x2);
708}
709
710// The NotAlmostEquals function
711template <typename T1, typename T2>
712inline bool
713NotAlmostEquals(T1 x1, T2 x2)
714{
715 return !AlmostEquals(x1, x2);
716}
717
718
739
740// The ExactlyEquals function
741template <typename TInput1, typename TInput2>
742inline constexpr bool
743ExactlyEquals(const TInput1 & x1, const TInput2 & x2)
744{
745 ITK_GCC_PRAGMA_PUSH
746 ITK_GCC_SUPPRESS_Wfloat_equal
747 return x1 == x2;
748 ITK_GCC_PRAGMA_POP
749}
750
751// The NotExactlyEquals function
752template <typename TInput1, typename TInput2>
753inline constexpr bool
754NotExactlyEquals(const TInput1 & x1, const TInput2 & x2)
755{
756 return !ExactlyEquals(x1, x2);
757}
758
759
765template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
766constexpr bool
768{
769 // An Introduction to the Theory of Numbers — G.H. Hardy & E.M. Wright, 6th ed., Oxford University Press.
770 // See Chapter 1 (Elementary Results on Primes). The observation that primes > 3 lie in residue classes
771 // +/1 mod 6 follows directly from eliminating multiples of 2 and 3.
772 if (n <= 1)
773 {
774 return false;
775 }
776 if (n == 2 || n == 3)
777 {
778 return true;
779 }
780 if (n % 2 == 0 || n % 3 == 0)
781 {
782 return false;
783 }
784 // 6k +/- 1, and avoid overflow via i <= n / i
785 for (T x = 5; x <= n / x; x += 6)
786 {
787 if (n % x == 0 || n % (x + 2) == 0)
788 {
789 return false;
790 }
791 }
792 return true;
793}
794
795
798template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
799constexpr T
801{
802 T v = 2;
803 while (v <= n)
804 {
805 if (n % v == 0 && IsPrime(v))
806 {
807 n /= v;
808 }
809 else
810 {
811 v += 1;
812 }
813 }
814 return v;
815}
816
817
821template <typename TReturnType = uintmax_t>
822constexpr auto
823UnsignedProduct(const uintmax_t a, const uintmax_t b) noexcept
824{
825 static_assert(std::is_unsigned_v<TReturnType>, "UnsignedProduct only supports unsigned return types");
826
827 // Note that numeric overflow is not "undefined behavior", for unsigned numbers.
828 // This function checks if the result of a*b is mathematically correct.
829 return (a == 0) || (b == 0) ||
830 (((static_cast<TReturnType>(a * b) / a) == b) && ((static_cast<TReturnType>(a * b) / b) == a))
831 ? static_cast<TReturnType>(a * b)
832 : (assert(!"UnsignedProduct overflow!"), 0);
833}
834
835
843template <typename TReturnType = uintmax_t>
844constexpr auto
845UnsignedPower(const uintmax_t base, const uintmax_t exponent) noexcept -> TReturnType
846{
847 static_assert(std::is_unsigned_v<TReturnType>, "UnsignedPower only supports unsigned return types");
848
849 // Uses recursive function calls because C++11 does not support other ways of
850 // iterations for a constexpr function.
851 return (exponent == 0) ? (assert(base > 0), 1)
852 : (exponent == 1) ? base
854 UnsignedPower<TReturnType>(base, (exponent + 1) / 2));
855}
856
857
858/*==========================================
859 * itk::Math utility functions. std:: equivalents are used where they exist;
860 * the remainder are native definitions providing the historical interface.
861 */
862using std::isnan;
863using std::isinf;
864using std::isfinite;
865using std::isnormal;
866using std::cbrt;
867using std::hypot;
868
870template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
871constexpr int
872sgn(T x)
873{
874 return (x != T{}) ? ((x > T{}) ? 1 : -1) : 0;
875}
876
878template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
879constexpr int
881{
882 return (x >= T{}) ? 1 : -1;
883}
884
886constexpr bool
887sqr(bool x)
888{
889 return x;
890}
891template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
892constexpr T
893sqr(T x)
894{
895 return x * x;
896}
897
899constexpr bool
900cube(bool x)
901{
902 return x;
903}
904template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
905constexpr T
907{
908 return x * x * x;
909}
910
912constexpr unsigned int
914{
915 return static_cast<unsigned int>(static_cast<int>(x) * static_cast<int>(x));
916}
917constexpr unsigned int
918squared_magnitude(unsigned char x)
919{
920 return static_cast<unsigned int>(static_cast<int>(x) * static_cast<int>(x));
921}
922constexpr unsigned int
924{
925 // Multiply in unsigned: avoids the signed-overflow UB of vnl_math's x * x.
926 const auto ux = static_cast<unsigned int>(x);
927 return ux * ux;
928}
929constexpr unsigned int
930squared_magnitude(unsigned int x)
931{
932 return x * x;
933}
934constexpr unsigned long
936{
937 const auto ux = static_cast<unsigned long>(x);
938 return ux * ux;
939}
940constexpr unsigned long
941squared_magnitude(unsigned long x)
942{
943 return x * x;
944}
945constexpr unsigned long long
947{
948 const auto ux = static_cast<unsigned long long>(x);
949 return ux * ux;
950}
951constexpr unsigned long long
952squared_magnitude(unsigned long long x)
953{
954 return x * x;
955}
956constexpr float
958{
959 return x * x;
960}
961constexpr double
963{
964 return x * x;
965}
966constexpr long double
967squared_magnitude(long double x)
968{
969 return x * x;
970}
971
973template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
974constexpr T
976{
977 return x % y;
978}
979inline float
980remainder_truncated(float x, float y)
981{
982 return std::fmod(x, y);
983}
984inline double
985remainder_truncated(double x, double y)
986{
987 return std::fmod(x, y);
988}
989inline long double
990remainder_truncated(long double x, long double y)
991{
992 return std::fmod(x, y);
993}
994
996template <typename T, std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>, int> = 0>
997constexpr T
999{
1000 // Conditional add: vnl_math's ((x % y) + y) % y overflows for |y| > max/2.
1001 const T r = x % y;
1002 return (r != 0 && ((r < 0) != (y < 0))) ? r + y : r;
1003}
1004template <typename T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>, int> = 0>
1005constexpr T
1006remainder_floored(T x, T y)
1007{
1008 return x % y;
1009}
1010inline float
1011remainder_floored(float x, float y)
1012{
1013 return std::fmod(std::fmod(x, y) + y, y);
1014}
1015inline double
1016remainder_floored(double x, double y)
1017{
1018 return std::fmod(std::fmod(x, y) + y, y);
1019}
1020inline long double
1021remainder_floored(long double x, long double y)
1022{
1023 return std::fmod(std::fmod(x, y) + y, y);
1024}
1025
1027inline int
1029{
1030 return static_cast<int>(std::lrint(x));
1031}
1032inline int
1034{
1035 return static_cast<int>(std::lrint(x));
1036}
1037
1040inline int
1042{
1043 return rnd_halfinttoeven(2 * x + 0.5f) >> 1;
1044}
1045inline int
1047{
1048 return rnd_halfinttoeven(2 * x + 0.5) >> 1;
1049}
1050
1052inline int
1053rnd(float x)
1054{
1055 return static_cast<int>(std::lrint(x));
1056}
1057inline int
1058rnd(double x)
1059{
1060 return static_cast<int>(std::lrint(x));
1061}
1062
1064inline int
1065floor(float x)
1066{
1067 return static_cast<int>(std::floor(x));
1068}
1069inline int
1070floor(double x)
1071{
1072 return static_cast<int>(std::floor(x));
1073}
1074
1076inline int
1077ceil(float x)
1078{
1079 return static_cast<int>(std::ceil(x));
1080}
1081inline int
1082ceil(double x)
1083{
1084 return static_cast<int>(std::ceil(x));
1085}
1086
1088inline double
1089angle_0_to_2pi(double angle)
1090{
1091 angle = std::fmod(angle, twopi);
1092 if (angle >= 0)
1093 return angle;
1094 const double a = angle + twopi;
1095 // Guard the boundary: tiny negative inputs round a up to exactly twopi; clamp 1 ULP below.
1096 return (a < twopi) ? a : 6.28318530717958575;
1097}
1098
1100inline double
1102{
1103 angle = std::fmod(angle, twopi);
1104 if (angle > pi)
1105 angle -= twopi;
1106 if (angle < -pi)
1107 angle += twopi;
1108 return angle;
1109}
1110
1111
1132template <typename T>
1133constexpr auto
1134Absolute(T x) noexcept
1135{
1136 if constexpr (std::is_same_v<T, bool>)
1137 {
1138 // std::abs does not provide abs for bool, but ITK depends on bool support for abs.
1139 return x;
1140 }
1141 else if constexpr (std::is_integral_v<T>)
1142 {
1143 if constexpr (std::is_signed_v<T>)
1144 {
1145 using UnsignedType = std::make_unsigned_t<T>;
1146 using Limits = std::numeric_limits<T>;
1147
1148 // The absolute value of the minimum integer value, having a two's complement signed integer representation.
1149 constexpr UnsignedType absoluteValueOfMin{ UnsignedType{ Limits::max() } + UnsignedType{ 1 } };
1150
1151 return static_cast<UnsignedType>((x < 0) ? (x == Limits::min()) ? absoluteValueOfMin : -x : x);
1152 }
1153 else
1154 { // In C++17, the std::abs() integer overloads are only for : int, long, and long long.
1155 // unsigned type values std::abs() are supported through implicit type conversions to
1156 // the next larger sized integer type. The 'unsigned long long' failed due to an
1157 // lack of larger sized signed integer type to be promoted to.
1158 // type of x | default std::abs() called
1159 // uint8_t | std::abs( (int32_t) x)
1160 // uint16_t | std::abs( (int32_t) x)
1161 // uint32_t | std::abs( (int64_t) x)
1162 // uint64_t | // compiler error
1163 // This explicit override provides direct support for all unsigned integer types with type promotion.
1164 return x;
1165 }
1166 }
1167 else if constexpr (std::is_floating_point_v<T>) // floating point or complex<> types
1168 { // floating point std::abs is constexpr in c++23 and later
1169 // Note: +0.0 and -0.0 are considered equal, according to ExactlyEquals. They are both considered equal to T{}.
1170 // And they both have the same absolute value: +0.0.
1171 return ExactlyEquals(x, T{}) ? T{} : (x < 0) ? -x : x;
1172 }
1173}
1174template <typename T>
1175auto
1176Absolute(const std::complex<T> & x) noexcept
1177{
1178 // std::abs<T>(std::complex<T>) is not constexpr in in any proposed c++ standard
1179 return std::abs<T>(x);
1180}
1181
1182#if !defined(ITK_FUTURE_LEGACY_REMOVE)
1183// itk::Math::Absolute has different behavior than std::abs. The use of
1184// abs() in the ITK context without namespace resolution can be confusing
1185// The abs() version is provided for backwards compatibility.
1186template <typename T>
1187auto
1188abs(T x) noexcept
1189{
1190 return Absolute(x);
1191}
1192#endif
1193
1194} // namespace itk::Math
1195
1196#endif // end of itkMath.h
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)
Definition itkMath.h:130
RoundHalfIntegerToEven(TInput x) template< TReturn
Round towards nearest integer.
constexpr int sgn0(T x)
Sign of a value in {-1, +1}; zero maps to +1.
Definition itkMath.h:880
int ceil(float x)
Round toward plus infinity.
Definition itkMath.h:1077
constexpr bool cube(bool x)
Cube of a value.
Definition itkMath.h:900
constexpr T GreatestPrimeFactor(T n)
Definition itkMath.h:800
bool AlmostEquals(T1 x1, T2 x2)
Provide consistent equality checks between values of potentially different scalar or complex types.
Definition itkMath.h:705
constexpr T remainder_floored(T x, T y)
Floored remainder: quotient rounded toward minus infinity, result has the sign of y.
Definition itkMath.h:998
constexpr double sqrt2pi
Definition itkMath.h:81
constexpr auto UnsignedPower(const uintmax_t base, const uintmax_t exponent) noexcept -> TReturnType
Definition itkMath.h:845
constexpr double sqrt1_2
Definition itkMath.h:89
constexpr double eps
Definition itkMath.h:119
constexpr auto Absolute(T x) noexcept
Returns the absolute value of a number.
Definition itkMath.h:1134
double angle_0_to_2pi(double angle)
Normalize an angle (radians) into [0, 2*pi).
Definition itkMath.h:1089
TInput TInput auto CastWithRangeCheck(TInput x)
Definition itkMath.h:237
int floor(float x)
Round toward minus infinity.
Definition itkMath.h:1065
bool NotAlmostEquals(T1 x1, T2 x2)
Definition itkMath.h:713
TInput Ceil(TInput x) template< typename TReturn
constexpr double pi_over_2
Definition itkMath.h:69
constexpr bool IsPrime(T n)
Definition itkMath.h:767
constexpr bool sqr(bool x)
Square of a value.
Definition itkMath.h:887
int rnd_halfintup(float x)
Round to nearest integer, halfway cases upward (toward plus infinity). Valid only for |x| < INT_MAX /...
Definition itkMath.h:1041
constexpr double one_over_sqrt2pi
Definition itkMath.h:85
double angle_minuspi_to_pi(double angle)
Normalize an angle (radians) into (-pi, pi].
Definition itkMath.h:1101
constexpr double pi_over_4
Definition itkMath.h:71
TInput RoundHalfIntegerUp(TInput x) template< typename TReturn
Round towards nearest integer (This is a synonym for RoundHalfIntegerUp)
int rnd(float x)
Round to nearest integer; halfway cases follow round-half-to-even.
Definition itkMath.h:1053
constexpr bool ExactlyEquals(const TInput1 &x1, const TInput2 &x2)
Return the result of an exact comparison between two scalar values of potentially different types.
Definition itkMath.h:743
constexpr unsigned int squared_magnitude(char x)
Squared magnitude; integer results are unsigned.
Definition itkMath.h:913
constexpr double sqrteps
Definition itkMath.h:122
constexpr double two_over_sqrtpi
Definition itkMath.h:83
constexpr double one_over_pi
Definition itkMath.h:75
constexpr int sgn(T x)
Sign of a value: -1, 0, or +1.
Definition itkMath.h:872
constexpr auto UnsignedProduct(const uintmax_t a, const uintmax_t b) noexcept
Definition itkMath.h:823
int rnd_halfinttoeven(float x)
Round to nearest integer, halfway cases to the nearest even integer.
Definition itkMath.h:1028
constexpr double ln2
Definition itkMath.h:61
Floor(TInput x) template< TReturn
Round towards minus infinity.
constexpr double euler
euler constant
Definition itkMath.h:93
TInput TInput constexpr auto Round(TInput x)
Definition itkMath.h:202
constexpr float float_sqrteps
Definition itkMath.h:125
constexpr float float_eps
Definition itkMath.h:124
constexpr double ln10
Definition itkMath.h:63
constexpr double twopi
Definition itkMath.h:67
constexpr double sqrt2
Definition itkMath.h:87
constexpr bool NotExactlyEquals(const TInput1 &x1, const TInput2 &x2)
Definition itkMath.h:754
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.
Definition itkMath.h:331
constexpr double pi
Definition itkMath.h:65
constexpr double deg_per_rad
Definition itkMath.h:79
constexpr double two_over_pi
Definition itkMath.h:77
constexpr double e
Definition itkMath.h:55
constexpr double sqrt1_3
Definition itkMath.h:91
constexpr double pi_over_180
Definition itkMath.h:73
constexpr Detail::FloatIEEE< T >::IntType FloatDifferenceULP(T x1, T x2)
Return the signed distance in ULPs (units in the last place) between two floats.
Definition itkMath.h:276
constexpr T remainder_truncated(T x, T y)
Truncated remainder: quotient truncated toward zero, result has the sign of x.
Definition itkMath.h:975
constexpr T FloatAddULP(T x, typename Detail::FloatIEEE< T >::IntType ulps)
Add the given ULPs (units in the last place) to a float.
Definition itkMath.h:292
constexpr double log10e
Definition itkMath.h:59
constexpr double log2e
Definition itkMath.h:57
static bool AlmostEqualsFunction(double x1, double x2)
Definition itkMath.h:378
static bool AlmostEqualsFunction(float x1, double x2)
Definition itkMath.h:392
static bool AlmostEqualsFunction(TFloatType1 x1, TFloatType2 x2)
Definition itkMath.h:371
static bool AlmostEqualsFunction(double x1, float x2)
Definition itkMath.h:385
static bool AlmostEqualsFunction(float x1, float x2)
Definition itkMath.h:399
static bool AlmostEqualsFunction(TFloatType floatingVariable, TIntType integerVariable)
Definition itkMath.h:409
AlmostEqualsPlainOldEquals SelectedVersion
Definition itkMath.h:469
static bool AlmostEqualsFunction(TIntType integerVariable, TFloatType floatingVariable)
Definition itkMath.h:419
static bool AlmostEqualsFunction(TIntegerType1 x1, TIntegerType2 x2)
Definition itkMath.h:457
static bool AlmostEqualsFunction(TSignedInt signedVariable, TUnsignedInt unsignedVariable)
Definition itkMath.h:429
static bool AlmostEqualsFunction(TUnsignedInt unsignedVariable, TSignedInt signedVariable)
Definition itkMath.h:447
constexpr IntType AsULP() const
typename FloatIEEETraits< T >::IntType IntType