LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiMath.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiMath.h
00027  * authors ....: Thomas Rusert
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 28.04.99
00030  * revisions ..: $Id: ltiMath.h,v 1.28 2006/02/08 12:33:43 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_MATH_H_
00034 #define _LTI_MATH_H_
00035 
00036 #include "ltiObject.h"
00037 #include "ltiTypes.h"
00038 #include "ltiSinCos.h"
00039 #include <cmath>
00040 #include <limits>
00041 
00042 /**
00043  * \file ltiMath.h
00044  * Definition of some usually used global functions like min, max, round, etc.
00045  */
00046 
00047 /*
00048  * MS Visual C++ 6.0 and old GCC versions do not provide the standard
00049  * cmath interface of functions for several types in the namespace std.
00050  * For this compilers a cumbersome implementation must be provided.
00051  */
00052 #undef _LTI_MATH_H_STYLE
00053 #if (defined _LTI_MSC_6) || (defined _LTI_GNUC_2 )
00054 #define _LTI_MATH_H_STYLE 1
00055 #endif
00056 
00057 // on newer gcc's isnan and others are sometimes only available in the
00058 // namespace std. Examples are mingw and possibly gcc on Mac. 
00059 // Pull them in here
00060 #if defined(_LTI_GNUC_3) && !defined(_LTI_ICC) 
00061   using std::isnan;
00062   using std::isinf;
00063   using std::isfinite;
00064 #endif
00065 
00066 #ifndef _LTI_MATH_H_STYLE
00067 #include <algorithm>
00068 #endif
00069 
00070 # ifdef min
00071 #   undef min
00072 # endif
00073 
00074 # ifdef max
00075 #   undef max
00076 # endif
00077 
00078 namespace lti {
00079 
00080   /**
00081    * Returns true if \a a is close to \a b, i.e. if \a abs(a-b) <= \a epsilon.
00082    *
00083    * This is always better than testing equality with a==b for
00084    * floating point types. For default \a epsilon integers are tested
00085    * for equality.
00086    *
00087    * \b Note: Do not used for unsigned types T.
00088    * 
00089    * @param a first value
00090    * @param b second value
00091    * @param epsilon max difference between \a a and \a b
00092    *                         , default std::numeric_limits<T>::epsilon()
00093    * @returns true if distance between \a a and \a b is <= \a epsilon 
00094    *
00095    * @ingroup gBasicMathFunc
00096    */
00097   template <class T>
00098   inline bool closeTo(const T& a, const T& b, 
00099                       const T epsilon=std::numeric_limits<T>::epsilon()) {
00100     const T diff=a-b;
00101     return ((diff<=epsilon) && (diff>=-epsilon));
00102   }
00103 
00104   
00105   /**
00106    * Returns true if \a a is close to T(0), i.e. if abs(a) <= \a epsilon.
00107    *
00108    * This is always better than testing equality with a==0. for
00109    * floating point types. For default \a epsilon integers are tested
00110    * for ==0 automagically.
00111    *
00112    * \b Note: Do not used for unsigned types T.
00113    *
00114    * @param a value
00115    * @param epsilon maximum absolute value of \a a 
00116    *                         , default std::numeric_limits<T>::epsilon()
00117    * @returns true if absolute value of \a a is <= \a epsilon 
00118    *
00119    * @ingroup gBasicMathFunc
00120    */
00121   template <class T>
00122   inline bool closeToZero(const T& a,
00123                           const T epsilon=std::numeric_limits<T>::epsilon()) {
00124     return ((a<=epsilon) && (a>=-epsilon));
00125   }
00126 
00127 
00128   /**
00129    * round any float type mathematicly
00130    *
00131    * @ingroup gBasicMathFunc
00132    */
00133   template<class T>
00134   inline T round(T x) {
00135     if( x >= static_cast<T>(0) ) {
00136       return static_cast<T>(static_cast<long>(x + 0.5));
00137     }
00138 
00139     return static_cast<T>(static_cast<long>(x - 0.5));
00140   }
00141 
00142   /**
00143    * round any float type mathematicly and return an integer
00144    *
00145    * @ingroup gBasicMathFunc
00146    */
00147   template<class T>
00148   inline int iround(T x) {
00149     if( x >= 0 ) {
00150       return static_cast<int>(x + 0.5);
00151     }
00152 
00153     return static_cast<int>(x - 0.5);
00154   }
00155 
00156   /**
00157    * round any float type mathematicly and return an long integer
00158    *
00159    * @ingroup gBasicMathFunc
00160    */
00161   template<class T>
00162   inline long lround(T x) {
00163     if( x >= 0 ) {
00164       return static_cast<long>(x + 0.5);
00165     }
00166 
00167     return static_cast<long>(x - 0.5);
00168   }
00169 
00170   /**
00171    * Conditional rounding with cast.
00172    *
00173    * Template function that rounds only if the desired output type is
00174    * an integer type.  Otherwise, just a static cast will be done.
00175    *
00176    * It would be nice to have this in a static_cast or dynamic_cast
00177    * similar syntax, but, as usuall, Visual C++ do not support ANSI
00178    * C++ template as it should (the bug that make this imposible is
00179    * documented as Q240871)
00180    *
00181    * Usage: 
00182    * T a;
00183    * condRoundCastTo(from,to)
00184    *
00185    * @param from original data with type F
00186    * @param to destination data, will contain \a from rounded if it is
00187    *           of a floating point type and \a T is an integer type. 
00188    *           Otherwise the types will just be casted.
00189    */
00190   template<class T,class F>
00191   inline void condRoundCastTo(const F from,T& to) {
00192     to=static_cast<T>(from);
00193   }
00194 
00195   // specializations
00196   template<>
00197   inline void condRoundCastTo<int,float>(const float x,int& dest) {
00198     dest=iround(x);
00199   }
00200 
00201   template<>
00202   inline void condRoundCastTo<int,double>(const double x,int& dest) {
00203     dest=iround(x);
00204   }
00205 
00206   template<>
00207   inline void condRoundCastTo<ubyte,float>(const float x,ubyte& dest) {
00208     dest=static_cast<ubyte>(iround(x));
00209   }
00210 
00211   template<>
00212   inline void condRoundCastTo<ubyte,double>(const double x,ubyte& dest) {
00213     dest=static_cast<ubyte>(iround(x));
00214   }
00215 
00216   template<>
00217   inline void condRoundCastTo<short,float>(const float x,short& dest) {
00218     dest=static_cast<short>(iround(x));
00219   }
00220 
00221   template<>
00222   inline void condRoundCastTo<short,double>(const double x,short& dest) {
00223     dest=static_cast<short>(iround(x));
00224   }
00225 
00226   template<>
00227   inline void condRoundCastTo<unsigned int,float>(const float x,
00228                                                   unsigned int& dest) {
00229     dest=static_cast<unsigned int>(iround(x));
00230   }
00231 
00232   template<>
00233   inline void condRoundCastTo<unsigned int,double>(const double x,
00234                                                    unsigned int& dest) {
00235     dest=static_cast<unsigned int>(iround(x));
00236   }
00237 
00238   template<>
00239   inline void condRoundCastTo<byte,float>(const float x,byte& dest) {
00240     dest=static_cast<byte>(iround(x));
00241   }
00242 
00243   template<>
00244   inline void condRoundCastTo<byte,double>(const double x,byte& dest) {
00245     dest=static_cast<byte>(iround(x));
00246   }
00247 
00248   template<>
00249   inline void condRoundCastTo<unsigned short,float>(const float x,
00250                                                     unsigned short& dest) {
00251     dest=static_cast<unsigned short>(iround(x));
00252   }
00253 
00254   template<>
00255   inline void condRoundCastTo<unsigned short,double>(const double x,
00256                                                      unsigned short& dest) {
00257     dest=static_cast<unsigned short>(iround(x));
00258   }
00259 
00260   // end of condRoundCastTo specializations
00261 
00262   /**
00263    * Exchange the content of the two given variables.  It works for all
00264    * types T that properly define the copy constructor and operator=().
00265    *
00266    * \deprecated Please use swap instead
00267    *
00268    * @param a first variable
00269    * @param b second variable
00270    *
00271    * @ingroup gBasicMathFunc
00272    */
00273   template<class T>
00274   inline void exchange(T& a,T& b) {
00275     T tmp(a);
00276     a=b;
00277     b=tmp;
00278   }
00279 
00280   /**
00281    * Get the minimum of x and y
00282    *
00283    * @ingroup gBasicMathFunc
00284    */
00285   template<class T>
00286   inline T min(const T x, const T y) {
00287     return ((x<y) ? x : y);
00288   };
00289 
00290   /**
00291    * Get the maximum of x and y
00292    *
00293    * @ingroup gBasicMathFunc
00294    */
00295   template<class T>
00296   inline T max(const T x, const T y) {
00297     return ((x<y) ? y : x);
00298   };
00299 
00300   /**
00301    * Get the minimum of x, y and z
00302    *
00303    * @ingroup gBasicMathFunc
00304    */
00305   template<class T>
00306   inline T min(const T x, const T y, const T z) {
00307     return (min(x,min(y,z)));
00308   };
00309 
00310   /**
00311    * Get the maximum of x, y and z
00312    *
00313    * @ingroup gBasicMathFunc
00314    */
00315   template<class T>
00316   inline T max(const T x, const T y, const T z) {
00317     return (max(x,max(y,z)));
00318   };
00319 
00320   /**
00321    * Store the minimum of x and y in theMin and the maximum in theMax
00322    */
00323   template<class T>
00324   inline void minmax(const T x, const T y, T& theMin, T& theMax) {
00325     if (x<y) {
00326       theMin=x;
00327       theMax=y;
00328     } else {
00329       theMin=y;
00330       theMax=x;
00331     }
00332   }
00333 
00334   /**
00335    * Ensure that the minimum of the two given values is stored in theMin and
00336    * the maximum in theMax.
00337    */
00338   template<class T>
00339   inline void minmax(T& theMin, T& theMax) {
00340     if (theMax < theMin) {
00341       exchange(theMin,theMax);
00342     }
00343   }
00344 
00345   /**
00346    * Constant Pi (double precision)
00347    *
00348    * @ingroup gBasicMathFunc
00349    */
00350   const double Pi = 3.1415926535897932; //3.1415926535897932384626433832795;
00351 
00352   /**
00353    * Constant Not a Number (NaN) (doble precision)
00354    *
00355    * @ingroup gBasicMathFunc
00356    */
00357   const double NaN = log(-1.0);
00358 
00359   /**
00360    * Constant Infinity (Inf) (double precision)
00361    *
00362    * @ingroup gBasicMathFunc
00363    */
00364   const double Inf = tan(Pi/2.0);
00365 
00366   /**
00367    * Returns the value ln( gamma(x) ) for xx>0
00368    *
00369    * @ingroup gBasicMathFunc
00370    */
00371   template<class T> T lnGamma(const T& x);
00372 
00373   /**
00374    * Returns the factorial of x 
00375    *
00376    * Note that the returned type is always the same as the input type.  So,
00377    * if you require very large faculty values, just cast the input to double.
00378    *
00379    * @ingroup gBasicMathFunc
00380    */
00381   double factorial(const int x);
00382 
00383   /**
00384    * Returns the natural logarithm of the factorial of x 
00385    *
00386    * @ingroup gBasicMathFunc
00387    */
00388   double lnFactorial(const int x);
00389 
00390   /**
00391    * Returns the binomial coefficient defined by
00392    * \f[ \begin{pmatrix} n \\ k \end{pmatrix} \frac{n!}{k!(n-k)!} 
00393    * \quad 0 \leq k \leq n \f]
00394    *
00395    * @ingroup gBasicMathFunc
00396    */
00397   double binomial(const int n,const int k);
00398 
00399   /**
00400    * Convert the given angle in degrees to an angle in radians
00401    */
00402   inline double degToRad(const double& deg) {
00403     static const double factor = Pi/180.0;
00404     return deg*factor;
00405   }
00406 
00407   /**
00408    * Convert the given angle in degrees to an angle in radians
00409    */
00410   inline float degToRad(const float& deg) {
00411     static const float factor = static_cast<float>(Pi/180.0);
00412     return deg*factor;
00413   }
00414 
00415   /**
00416    * Convert the given angle in degrees to an angle in radians
00417    */
00418   inline double degToRad(const int& deg) {
00419     static const double factor = Pi/180.0;
00420     return deg*factor;
00421   }
00422 
00423 
00424   /**
00425    * Convert the given angle in radians to an angle in degrees
00426    */
00427   inline double radToDeg(const double& rad) {
00428     static const double factor = 180.0/Pi;
00429     return rad*factor;
00430   }
00431 
00432   /**
00433    * Convert the given angle in radians to an angle in degrees
00434    */
00435   inline float radToDeg(const float& rad) {
00436     static const float factor = static_cast<float>(180.0/Pi);
00437     return rad*factor;
00438   }
00439 
00440   /**
00441    * absolute value for signed bytes
00442    *
00443    * @ingroup gBasicMathFunc
00444    */
00445   inline byte abs(byte x) {
00446     return ((x>=0) ? x : -x);
00447   }
00448 
00449   /**
00450    * absolute value for integers
00451    *
00452    * @ingroup gBasicMathFunc
00453    */
00454   inline int abs(int x) {
00455     return ((x>=0) ? x : -x);
00456   }
00457 
00458   /**
00459    * absolute value for any type
00460    *
00461    * @ingroup gBasicMathFunc
00462    */
00463   inline float abs(float x) {
00464 #ifdef _LTI_MATH_H_STYLE
00465     return ((x>=0) ? x : -x);
00466 #else
00467     return std::abs(x);
00468 #endif
00469   }
00470 
00471   /**
00472    * absolute value for any type
00473    *
00474    * @ingroup gBasicMathFunc
00475    */
00476   inline double abs(const double& x) {
00477 #ifdef _LTI_MATH_H_STYLE
00478     return ((x>=0) ? x : -x);
00479 #else
00480     return std::abs(x);
00481 #endif
00482   }
00483 
00484   /**
00485    * absolute difference for the given values
00486    * equals if (x>y) then (x-y) else (y-x).
00487    * 
00488    * Note that with complex numbers it does not return the real abs value.
00489    *
00490    * @ingroup gBasicMathFunc
00491    */
00492   template<class T>
00493   inline T absdiff(const T& x,const T& y) {
00494     return ((x>y) ? (x-y) : (y-x));
00495   }
00496 
00497   /**
00498    * Compute the reciprocal of the given value \e x, defined as 1/x.
00499    */
00500   inline double reciprocal(const double& x) {
00501     return 1.0/x;
00502   }
00503 
00504   /**
00505    * Compute the reciprocal of the given value \e x, defined as 1/x.
00506    */
00507   inline float reciprocal(const float& x) {
00508     return 1.0f/x;
00509   }
00510 
00511   /**
00512    * Compute 1 minus the given value.
00513    *
00514    * This function is usually employed to revert a probability value
00515    */
00516   inline double oneMinus(const double& x) {
00517     return 1.0-x;
00518   }
00519 
00520   /**
00521    * Compute 1 minus the given value
00522    *
00523    * This function is usually employed to revert a probability value
00524    */
00525   inline float oneMinus(const float& x) {
00526     return 1.0f-x;
00527   }
00528 
00529   /**
00530    * Compute 1 minus the given value
00531    */
00532   inline int oneMinus(const int& x) {
00533     return 1-x;
00534   }
00535 
00536   /**
00537    * rectify is 0 if x<0 or x otherwise
00538    *
00539    * @ingroup gBasicMathFunc
00540    */
00541   template<class T>
00542   inline T rectify(const T& x) {
00543     return ((x>=0) ? x : 0);
00544   }
00545 
00546   /**
00547    * square (x*x)
00548    *
00549    * @ingroup gBasicMathFunc
00550    */
00551   template<class T>
00552   inline T sqr(const T& x) {
00553     return (x*x);
00554   }
00555 
00556   /**
00557    * square root of integer type.  Equals floor(sqrt(x))
00558    *
00559    * @ingroup gBasicMathFunc
00560    */
00561   inline int sqrt(int x) {
00562     return static_cast<int>(::sqrt(static_cast<double>(x)));
00563   }
00564 
00565   /**
00566    * square root
00567    *
00568    * @ingroup gBasicMathFunc
00569    */
00570   inline unsigned int sqrt(unsigned int x) {
00571     return static_cast<unsigned int>(::sqrt(static_cast<double>(x)));
00572   }
00573 
00574   /**
00575    * square root
00576    *
00577    * @ingroup gBasicMathFunc
00578    */
00579   inline float sqrt(float x) {
00580 #ifdef _LTI_MATH_H_STYLE
00581     // MS Visual does not support std namespace functions, which
00582     // can be optimized for the different types
00583     return static_cast<float>(::sqrt(x));
00584 #else
00585     // use std method optimized for float
00586     return static_cast<float>(std::sqrt(x));
00587 #endif
00588   }
00589 
00590   /**
00591    * square root
00592    *
00593    * @ingroup gBasicMathFunc
00594    */
00595   inline double sqrt(const double& x) {
00596 #ifdef _LTI_MATH_H_STYLE
00597     // MS Visual does not support std namespace functions, which
00598     // can be optimized for the different types
00599     return static_cast<double>(::sqrt(x));
00600 #else
00601     // use std method optimized for double
00602     return static_cast<double>(std::sqrt(x));
00603 #endif
00604   }
00605 
00606   /**
00607    * square root of rectified value, i.e. returns 0 if x<=0 or sqrt(x)
00608    * otherwise.
00609    */
00610   template<class T>
00611   inline T sqrtrect(const T x) {
00612     if (x<=static_cast<T>(0)) {
00613       return static_cast<T>(0);
00614     }
00615     return sqrt(x);
00616   }
00617 
00618   // other standard functions used
00619 
00620   /**
00621    * Calculate the sine and cosine values of \p angle in one step if
00622    * the setup allows it.
00623    *
00624    * @param angle the angle
00625    * @param sval sine of the \p angle
00626    * @param cval cosine of the \p angle
00627    */
00628   template <class T>
00629   inline void sincos(T angle, T& sval, T& cval) {
00630     sincos_impl(static_cast<double>(angle),
00631                 static_cast<double&>(sval),
00632                 static_cast<double&>(cval));
00633   }
00634 
00635   // overload for float
00636   inline void sincos(float angle, float& sval, float& cval) {
00637     sincosf_impl(angle,sval,cval);
00638   }
00639 
00640     
00641 
00642 #ifdef _LTI_MATH_H_STYLE
00643   /**
00644    * Exchange the content of the two given variables.  It works for all
00645    * types T that properly define the copy constructor and operator=().
00646    *
00647    * @param a first variable
00648    * @param b second variable
00649    *
00650    * At the end \a b contains the previous contents of \a a, which at the
00651    * same time contains the previous contents of \a b.
00652    * 
00653    * @ingroup gBasicMathFunc
00654    */
00655   template<class T>
00656   inline void swap(T& a,T& b) {
00657     T tmp(a);
00658     a=b;
00659     b=tmp;
00660   }
00661 
00662   /**
00663    * sinus
00664    *
00665    * @ingroup gBasicMathFunc
00666    */
00667   inline float sin(float x) {
00668     return static_cast<float>(::sin(x));
00669   }
00670 
00671   /**
00672    * sinus
00673    *
00674    * @ingroup gBasicMathFunc
00675    */
00676   inline double sin(const double& x) {
00677     return ::sin(x);
00678   }
00679 
00680   /**
00681    * cosinus
00682    *
00683    * @ingroup gBasicMathFunc
00684    */
00685   inline float cos(float x) {
00686     return static_cast<float>(::cos(x));
00687   }
00688 
00689   /**
00690    * cosinus
00691    *
00692    * @ingroup gBasicMathFunc
00693    */
00694   inline double cos(const double& x) {
00695     return ::cos(x);
00696   }
00697 
00698   /**
00699    * tangent
00700    *
00701    * @ingroup gBasicMathFunc
00702    */
00703   inline float tan(float x) {
00704     return static_cast<float>(::tan(x));
00705   }
00706 
00707   /**
00708    * tangent
00709    *
00710    * @ingroup gBasicMathFunc
00711    */
00712   inline double tan(const double& x) {
00713     return ::tan(x);
00714   }
00715 
00716   /**
00717    * arc sine
00718    *
00719    * @ingroup gBasicMathFunc
00720    */
00721   inline float asin(float x) {
00722     return static_cast<float>(::asin(x));
00723   }
00724 
00725   /**
00726    * arc sine
00727    *
00728    * @ingroup gBasicMathFunc
00729    */
00730   inline double asin(const double& x) {
00731     return ::asin(x);
00732   }
00733 
00734   /**
00735    * arc cosine
00736    *
00737    * @ingroup gBasicMathFunc
00738    */
00739   inline float acos(float x) {
00740     return static_cast<float>(::acos(x));
00741   }
00742 
00743   /**
00744    * arc cosine
00745    *
00746    * @ingroup gBasicMathFunc
00747    */
00748   inline double acos(const double& x) {
00749     return ::acos(x);
00750   }
00751 
00752 
00753   /**
00754    * arc tangent
00755    *
00756    * @ingroup gBasicMathFunc
00757    */
00758   inline float atan(float x) {
00759     return static_cast<float>(::atan(x));
00760   }
00761 
00762   /**
00763    * arc tangent
00764    *
00765    * @ingroup gBasicMathFunc
00766    */
00767   inline double atan(const double& x) {
00768     return ::atan(x);
00769   }
00770 
00771   /**
00772    * arc tangent of y/x
00773    *
00774    * @ingroup gBasicMathFunc
00775    */
00776   inline float atan2(float y,float x) {
00777     return static_cast<float>(::atan2(y,x));
00778   }
00779 
00780   /**
00781    * arc tangent of y/x
00782    *
00783    * @ingroup gBasicMathFunc
00784    */
00785   inline double atan2(const double& y,const double& x) {
00786     return ::atan2(y,x);
00787   }
00788 
00789   /**
00790    * hyperbolic sine
00791    *
00792    * @ingroup gBasicMathFunc
00793    */
00794   inline double sinh(const double& x) {
00795     return ::sinh(x);
00796   }
00797 
00798   /**
00799    * hyperbolic sinus
00800    *
00801    * @ingroup gBasicMathFunc
00802    */
00803   inline double sinh(float x) {
00804     return static_cast<float>(::sinh(x));
00805   }
00806 
00807   /**
00808    * hyperbolic cosine
00809    *
00810    * @ingroup gBasicMathFunc
00811    */
00812   inline float cosh(float x) {
00813     return static_cast<float>(::cosh(x));
00814   }
00815 
00816   /**
00817    * hyperbolic cosine
00818    *
00819    * @ingroup gBasicMathFunc
00820    */
00821   inline double cosh(const double& x) {
00822     return ::cosh(x);
00823   }
00824 
00825   /**
00826    * hyperbolic tangent
00827    *
00828    * @ingroup gBasicMathFunc
00829    */
00830   inline float tanh(float x) {
00831     return static_cast<float>(::tanh(x));
00832   }
00833 
00834   /**
00835    * hyperbolic tangent
00836    *
00837    * @ingroup gBasicMathFunc
00838    */
00839   inline double tanh(const double& x) {
00840     return ::tanh(x);
00841   }
00842 
00843   /**
00844    * natural logarithm
00845    *
00846    * @ingroup gBasicMathFunc
00847    */
00848   inline float log(float x) {
00849     return static_cast<float>(::log(x));
00850   }
00851 
00852   /**
00853    * natural logarithm
00854    *
00855    * @ingroup gBasicMathFunc
00856    */
00857   inline double log(const double& x) {
00858     return ::log(x);
00859   }
00860 
00861   /**
00862    * natural logarithm
00863    *
00864    * @ingroup gBasicMathFunc
00865    */
00866   inline double log(int x) {
00867     return ::log(static_cast<double>(x));
00868   }
00869 
00870   /**
00871    * logarithm base 10
00872    *
00873    * @ingroup gBasicMathFunc
00874    */
00875   inline float log10(float x) {
00876     return static_cast<float>(::log10(x));
00877   }
00878 
00879   /**
00880    * logarithm base 10
00881    *
00882    * @ingroup gBasicMathFunc
00883    */
00884   inline double log10(const double& x) {
00885     return ::log10(x);
00886   }
00887 
00888   /**
00889    * logarithm base 10
00890    *
00891    * @ingroup gBasicMathFunc
00892    */
00893   inline double log10(int x) {
00894     return ::log10(static_cast<double>(x));
00895   }
00896 
00897   /**
00898    * natural exponential
00899    *
00900    * @ingroup gBasicMathFunc
00901    */
00902   inline float exp(float x) {
00903     return static_cast<float>(::exp(x));
00904   }
00905 
00906   /**
00907    * natural exponential
00908    *
00909    * @ingroup gBasicMathFunc
00910    */
00911   inline double exp(const double& x) {
00912     return ::exp(x);
00913   }
00914 
00915   /**
00916    * natural exponential
00917    *
00918    * @ingroup gBasicMathFunc
00919    */
00920   inline double exp(int x) {
00921     return ::exp(static_cast<double>(x));
00922   }
00923 
00924   /**
00925    * power function, computes \f$x^y\f$
00926    *
00927    * @ingroup gBasicMathFunc
00928    */
00929   inline double pow(const double& x, const double& y) {
00930     return ::pow(x,y);
00931   }
00932 
00933   /**
00934    * power function, computes \f$x^y\f$
00935    *
00936    * @ingroup gBasicMathFunc
00937    */
00938   inline float pow(float x,float y) {
00939     return static_cast<float>(::pow(x,y));
00940   }
00941 
00942   /**
00943    * power function, computes \f$x^y\f$
00944    *
00945    * @ingroup gBasicMathFunc
00946    */
00947   inline double pow(const double& x, int y) {
00948     return ::pow(x,y);
00949   }
00950 
00951   /**
00952    * power function, computes \f$x^y\f$
00953    *
00954    * @ingroup gBasicMathFunc
00955    */
00956   inline float pow(float x,int y) {
00957     return static_cast<float>(::pow(x,y));
00958   }
00959 
00960 #else
00961   // methods optimized for different types
00962   using std::swap;
00963   using std::sin;
00964   using std::cos;
00965   using std::tan;
00966   using std::asin;
00967   using std::acos;
00968   using std::atan;
00969   using std::atan2;
00970   using std::sinh;
00971   using std::cosh;
00972   using std::tanh;
00973   using std::log;
00974   using std::log10;
00975   using std::exp;
00976   using std::pow;
00977 #endif
00978 
00979   /**
00980    * sigmoid for floats
00981    *
00982    * @ingroup gBasicMathFunc
00983    */
00984   inline float sigmoid(const float x) {
00985     return static_cast<float>(1.0/(1.0+exp(-x)));
00986   }
00987 
00988   /**
00989    * sigmoid for doubles
00990    *
00991    * @ingroup gBasicMathFunc
00992    */
00993   inline double sigmoid(const double& x){
00994     return 1.0/(1.0+exp(-x));
00995   }
00996 
00997   /**
00998    * sigmoid for ints
00999    *
01000    * @ingroup gBasicMathFunc
01001    */
01002   inline double sigmoid(const int x){
01003     return 1.0/(1.0+exp(-static_cast<double>(x)));
01004   }
01005 
01006   /**
01007    * signum of x (for x==0 -> signum = 1) (@see signum0)
01008    *
01009    * @ingroup gBasicMathFunc
01010    */
01011   template<class T>
01012   inline T signum(T x) {
01013     return ((x>=T()) ? T(1) : T(-1));
01014   }
01015 
01016   /**
01017    * signum of x (for x==0 -> signum = 0) (@see signum)
01018    *
01019    * @ingroup gBasicMathFunc
01020    */
01021   template<class T>
01022   inline T signum0(T x) {
01023     return ((x>0) ? T(1) : ((x<0) ? T(-1) : T(0)));
01024   }
01025 
01026   /**
01027    * Return true if the given number is an even number. 
01028    *
01029    * For floating point types, this function will return true only if the
01030    * number is \e exacltly an integer and it is even.
01031    *
01032    * @ingroup gBasicMathFunc
01033    */
01034   template<class T>
01035   inline bool even(const T x) {
01036     return ((x & static_cast<T>(1)) == 0); 
01037   }
01038 
01039   template<>
01040   inline bool even(const double x) {
01041     const int64 i = static_cast<int64>(x);
01042     return ((static_cast<double>(i) == x) && even(i));
01043   }
01044 
01045   template<>
01046   inline bool even(const float x) {
01047     const int i = static_cast<int>(x);
01048     return ((static_cast<float>(i) == x) && even(i));
01049   }
01050 
01051 
01052   /**
01053    * Return true if the given number is an odd number.
01054    *
01055    * For floating point types, this function will return true only if the
01056    * number is \e exacltly an integer and it is odd.
01057    *
01058    * @ingroup gBasicMathFunc
01059    */
01060   template<class T>
01061   inline bool odd(const T x) {
01062     return ((x & static_cast<T>(1)) != 0); 
01063   }
01064 
01065   template<>
01066   inline bool odd(const double x) {
01067     const int64 i = static_cast<int64>(x);
01068     return ((static_cast<double>(i) == x) && odd(i));
01069   }
01070 
01071   template<>
01072   inline bool odd(const float x) {
01073     const int i = static_cast<int>(x);
01074     return ((static_cast<float>(i) == x) && odd(i));
01075   }
01076 
01077   /**
01078    * Compute the incomplete beta function.
01079    *
01080    * @ingroup gBasicMathFunc
01081    */
01082   template<class T>
01083   T betai(const T& a, const T& b, const T& x);
01084   
01085   /**
01086    * Compute the coefficients required for the incomplete beta function.
01087    * Internally we compute with double precision.
01088    */
01089   double betacf(const double& a, const double& b, const double& x);
01090   
01091 }
01092 
01093 
01094 #include "ltiMath_template.h"
01095 
01096 #endif

Generated on Sat Apr 10 15:25:49 2010 for LTI-Lib by Doxygen 1.6.1