ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkMath.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 /*=========================================================================
00019  *
00020  *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
00021  *
00022  *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00023  *
00024  *  For complete copyright, license and disclaimer of warranty information
00025  *  please refer to the NOTICE file at the top of the ITK source tree.
00026  *
00027  *=========================================================================*/
00028 #ifndef __itkMath_h
00029 #define __itkMath_h
00030 
00031 #include "itkIntTypes.h"
00032 #include "itkMathDetail.h"
00033 #include "itkConceptChecking.h"
00034 
00035 namespace itk
00036 {
00037 namespace Math
00038 {
00039 // These constants originate from VXL's vnl_math.h. They have been
00040 // moved here to improve visibility, and to ensure that the constants
00041 // are available during compile time ( as opposed to static const
00042 // member vaiables ).
00043 
00045 static const double e                = 2.7182818284590452354;
00047 static const double log2e            = 1.4426950408889634074;
00049 static const double log10e           = 0.43429448190325182765;
00051 static const double ln2              = 0.69314718055994530942;
00053 static const double ln10             = 2.30258509299404568402;
00055 static const double pi               = 3.14159265358979323846;
00057 static const double pi_over_2        = 1.57079632679489661923;
00059 static const double pi_over_4        = 0.78539816339744830962;
00061 static const double one_over_pi      = 0.31830988618379067154;
00063 static const double two_over_pi      = 0.63661977236758134308;
00065 static const double two_over_sqrtpi  = 1.12837916709551257390;
00067 static const double one_over_sqrt2pi = 0.39894228040143267794;
00069 static const double sqrt2            = 1.41421356237309504880;
00071 static const double sqrt1_2          = 0.70710678118654752440;
00072 
00076 #define itkTemplateFloatingToIntegerMacro(name)                                     \
00077   template< typename TReturn, typename TInput >                                     \
00078   inline TReturn name(TInput x)                                                     \
00079     {                                                                               \
00080                                                                                     \
00081     if ( sizeof( TReturn ) <= 4 )                                                   \
00082       {                                                                             \
00083       return static_cast< TReturn >( Detail::name##_32(x) );                      \
00084       }                                                                             \
00085     else if ( sizeof( TReturn ) <= 8 )                                              \
00086       {                                                                             \
00087       return static_cast< TReturn >( Detail::name##_64(x) );                      \
00088       }                                                                             \
00089     else                                                                            \
00090       {                                                                             \
00091       return static_cast< TReturn >( Detail::name##_base< TReturn, TInput >(x) ); \
00092       }                                                                             \
00093     }
00094 
00095 
00115 itkTemplateFloatingToIntegerMacro(RoundHalfIntegerToEven);
00116 
00139 itkTemplateFloatingToIntegerMacro(RoundHalfIntegerUp);
00140 
00148 template< typename TReturn, typename TInput >
00149 inline TReturn Round(TInput x) { return RoundHalfIntegerUp< TReturn, TInput >(x); }
00150 
00163 itkTemplateFloatingToIntegerMacro(Floor);
00164 
00175 itkTemplateFloatingToIntegerMacro(Ceil);
00176 
00177 #undef  itkTemplateFloatingToIntegerMacro
00178 
00179 template< typename TReturn, typename TInput >
00180 inline TReturn CastWithRangeCheck(TInput x)
00181 {
00182 #ifdef ITK_USE_CONCEPT_CHECKING
00183   itkConceptMacro( OnlyDefinedForIntegerTypes1, ( itk::Concept::IsInteger< TReturn > ) );
00184   itkConceptMacro( OnlyDefinedForIntegerTypes2, ( itk::Concept::IsInteger< TInput > ) );
00185 #endif // ITK_USE_CONCEPT_CHECKING
00186 
00187   TReturn ret = static_cast< TReturn >( x );
00188   if ( sizeof( TReturn ) > sizeof( TInput )
00189        && !( !itk::NumericTraits< TReturn >::is_signed &&  itk::NumericTraits< TInput >::is_signed ) )
00190     {
00191     // if the output type is bigger and we are not converting a signed
00192     // interger to an unsigned interger then we have no problems
00193     return ret;
00194     }
00195   else if ( sizeof( TReturn ) >= sizeof( TInput ) )
00196     {
00197     if ( itk::NumericTraits< TInput >::IsPositive(x) != itk::NumericTraits< TReturn >::IsPositive(ret) )
00198       {
00199       itk::RangeError _e(__FILE__, __LINE__);
00200       throw _e;
00201       }
00202     }
00203   else if ( static_cast< TInput >( ret ) != x
00204             || ( itk::NumericTraits< TInput >::IsPositive(x) != itk::NumericTraits< TReturn >::IsPositive(ret) ) )
00205     {
00206     itk::RangeError _e(__FILE__, __LINE__);
00207     throw _e;
00208     }
00209   return ret;
00210 }
00211 } // end namespace Math
00212 } // end namespace itk
00213 #endif // end of itkMath.h
00214