ITK  4.4.0
Insight Segmentation and Registration Toolkit
itkMath.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
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  * http://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 "itkIntTypes.h"
32 #include "itkMathDetail.h"
33 #include "itkConceptChecking.h"
34 
35 namespace itk
36 {
37 namespace Math
38 {
39 // These constants originate from VXL's vnl_math.h. They have been
40 // moved here to improve visibility, and to ensure that the constants
41 // are available during compile time ( as opposed to static const
42 // member vaiables ).
43 
45 static const double e = 2.7182818284590452354;
47 static const double log2e = 1.4426950408889634074;
49 static const double log10e = 0.43429448190325182765;
51 static const double ln2 = 0.69314718055994530942;
53 static const double ln10 = 2.30258509299404568402;
55 static const double pi = 3.14159265358979323846;
57 static const double pi_over_2 = 1.57079632679489661923;
59 static const double pi_over_4 = 0.78539816339744830962;
61 static const double one_over_pi = 0.31830988618379067154;
63 static const double two_over_pi = 0.63661977236758134308;
65 static const double two_over_sqrtpi = 1.12837916709551257390;
67 static const double one_over_sqrt2pi = 0.39894228040143267794;
69 static const double sqrt2 = 1.41421356237309504880;
71 static const double sqrt1_2 = 0.70710678118654752440;
72 
76 #define itkTemplateFloatingToIntegerMacro(name) \
77  template< typename TReturn, typename TInput > \
78  inline TReturn name(TInput x) \
79  { \
80  \
81  if ( sizeof( TReturn ) <= 4 ) \
82  { \
83  return static_cast< TReturn >( Detail::name##_32(x) ); \
84  } \
85  else if ( sizeof( TReturn ) <= 8 ) \
86  { \
87  return static_cast< TReturn >( Detail::name##_64(x) ); \
88  } \
89  else \
90  { \
91  return static_cast< TReturn >( Detail::name##_base< TReturn, TInput >(x) ); \
92  } \
93  }
94 
95 
116 
140 
148 template< typename TReturn, typename TInput >
149 inline TReturn Round(TInput x) { return RoundHalfIntegerUp< TReturn, TInput >(x); }
150 
164 
176 
177 #undef itkTemplateFloatingToIntegerMacro
178 
179 template< typename TReturn, typename TInput >
180 inline TReturn CastWithRangeCheck(TInput x)
181 {
182 #ifdef ITK_USE_CONCEPT_CHECKING
183  itkConceptMacro( OnlyDefinedForIntegerTypes1, ( itk::Concept::IsInteger< TReturn > ) );
184  itkConceptMacro( OnlyDefinedForIntegerTypes2, ( itk::Concept::IsInteger< TInput > ) );
185 #endif // ITK_USE_CONCEPT_CHECKING
186 
187  TReturn ret = static_cast< TReturn >( x );
188  if ( sizeof( TReturn ) > sizeof( TInput )
190  {
191  // if the output type is bigger and we are not converting a signed
192  // integer to an unsigned integer then we have no problems
193  return ret;
194  }
195  else if ( sizeof( TReturn ) >= sizeof( TInput ) )
196  {
198  {
199  itk::RangeError _e(__FILE__, __LINE__);
200  throw _e;
201  }
202  }
203  else if ( static_cast< TInput >( ret ) != x
205  {
206  itk::RangeError _e(__FILE__, __LINE__);
207  throw _e;
208  }
209  return ret;
210 }
211 
218 template <typename T>
219 inline typename Detail::FloatIEEE<T>::IntType
220 FloatDifferenceULP( T x1, T x2 )
221 {
222  Detail::FloatIEEE<T> x1f(x1);
223  Detail::FloatIEEE<T> x2f(x2);
224  return x1f.AsULP() - x2f.AsULP();
225 }
226 
257 template <typename T>
258 inline bool
259 FloatAlmostEqual( T x1, T x2,
260  typename Detail::FloatIEEE<T>::IntType maxUlps = 4,
261  typename Detail::FloatIEEE<T>::FloatType maxAbsoluteDifference = 0.1*NumericTraits<T>::epsilon() )
262 {
263  // Check if the numbers are really close -- needed
264  // when comparing numbers near zero.
265  const T absDifference = vcl_abs(x1 - x2);
266  if ( absDifference <= maxAbsoluteDifference )
267  {
268  return true;
269  }
270 
272  ulps = FloatDifferenceULP(x1, x2);
273  if(ulps < 0)
274  {
275  ulps = -ulps;
276  }
277  return ulps <= maxUlps;
278 }
279 
280 } // end namespace Math
281 } // end namespace itk
282 #endif // end of itkMath.h
283