Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

math_tools.h

Go to the documentation of this file.
00001 
00052 #ifndef __MATH_TOOLS__
00053 #define __MATH_TOOLS__
00054 
00055 
00056 
00057 
00058 #include <algorithm>
00059 #include <cmath>
00060 #include <cstdlib>
00061 #include <ctime>
00062 
00063 #ifndef WITHOUT_LIMITS
00064 #include <limits>
00065 #endif
00066 
00067 #include "msg_stream.h"
00068 
00069 
00070 
00071 
00072 namespace Math_tools{
00073   
00074   template<typename Vec2,typename Real>
00075   inline void barycentric_coordinates(const Vec2& A,
00076                                       const Vec2& B,
00077                                       const Vec2& C,
00078                                       const Vec2& M,
00079                                       Real* const a,
00080                                       Real* const b,
00081                                       Real* const c);
00082   
00083   inline void init_random() {std::srand(std::time(NULL));}
00084 
00085   template<typename Real>
00086   inline Real random(const Real min_value_included,
00087                      const Real max_value_included);
00088 
00089   
00090   template<typename ValueIterator>
00091   inline double entropy(ValueIterator begin,
00092                         ValueIterator end);
00093 
00094 
00095   
00096   template<typename Real>
00097   inline Real clamp(const Real min_value,
00098                     const Real max_value,
00099                     const Real x);
00100 
00101   
00102   template<typename Array,typename Real>
00103   inline
00104   typename Array::value_type
00105   bilinear_interpolation(const Array& array,
00106                          const Real x,
00107                          const Real y);
00108 
00109 
00110   inline double degree_to_radian(const double d);
00111   
00112   inline double radian_to_degree(const double r);
00113 
00114   template<typename Real>
00115   inline Real sign(const Real r);
00116 
00117 
00118 #ifndef WITHOUT_LIMITS    
00119 
00120   template<typename T> inline bool is_quiet_NaN(T x);
00121 
00122   template<typename T> inline bool is_signaling_NaN(T x);
00123 
00124   template<typename T> inline bool is_NaN(T x);
00125   
00126 #endif
00127 
00128 /*
00129   
00130   #############################################
00131   #############################################
00132   #############################################
00133   ######                                 ######
00134   ######   I M P L E M E N T A T I O N   ######
00135   ######                                 ######
00136   #############################################
00137   #############################################
00138   #############################################
00139   
00140 */
00141 
00142 
00143   
00144   
00145   template<typename Vec2,typename Real>
00146   void barycentric_coordinates(const Vec2& A,
00147                                const Vec2& B,
00148                                const Vec2& C,
00149                                const Vec2& M,
00150                                Real* const a,
00151                                Real* const b,
00152                                Real* const c){
00153 
00154     const Real Xa = A[0] - C[0];
00155     const Real Ya = A[1] - C[1];
00156 
00157     const Real Xb = B[0] - C[0];
00158     const Real Yb = B[1] - C[1];
00159 
00160     const Real Xm = M[0] - C[0];
00161     const Real Ym = M[1] - C[1];
00162 
00163     const Real det = Xa*Yb - Ya*Xb;
00164 
00165     if (det != 0){
00166       
00167       const Real inv_det = 1.0/det;
00168 
00169       *a = inv_det * (Yb*Xm  - Xb*Ym);
00170       *b = inv_det * (-Ya*Xm + Ym*Xa);
00171       *c = 1.0 - (*a) - (*b);
00172     }
00173     else{
00174 
00175       Message::error
00176         <<"barycentric_coordinates: colinear points not yet implemented"
00177         <<Message::done;
00178       
00179     }
00180   }
00181 
00182 
00183   
00184 
00185   template<typename Real>
00186   Real random(const Real min_value_included,
00187               const Real max_value_included){
00188     
00189     const double delta = static_cast<double>(max_value_included - min_value_included);
00190     
00191     return min_value_included + static_cast<Real>(delta*rand()/(RAND_MAX));
00192   }
00193 
00194 
00195 
00196   
00197   template<typename ValueIterator>
00198   double entropy(ValueIterator begin,
00199                  ValueIterator end){
00200     
00201     double sum = 0;
00202     for(ValueIterator i=begin;i!=end;i++){
00203       if (*i>=0){
00204         sum+=*i;
00205       }
00206       else{
00207         Message::error<<"entropy: non-positive value"<<Message::done;
00208       }
00209     }
00210 
00211     if (sum==0){
00212       Message::error<<"entropy: sum==0"<<Message::done;
00213     }
00214 
00215     double result = 0;
00216     for(ValueIterator i=begin;i!=end;i++){
00217       const double p = (*i)/sum;
00218       result -= (p==0) ? 0 : p*log(p);
00219     }
00220 
00221     return result;
00222   }
00223 
00224   
00225 
00226   template<typename Real>
00227   inline Real clamp(const Real min_value,
00228                     const Real max_value,
00229                     const Real x){
00230 
00231     return std::max(std::min(x,max_value),min_value);
00232   }
00233 
00234 
00235   template<typename Array,typename Real>
00236   inline
00237   typename Array::value_type
00238   bilinear_interpolation(const Array& array,
00239                          const Real x,
00240                          const Real y){
00241 
00242     typedef unsigned int size_type;
00243     typedef float        real_type;
00244 
00245     const size_type x_size = array.x_size();
00246     const size_type y_size = array.y_size();
00247     
00248     const size_type x_index  =
00249       clamp<size_type>(0,x_size-1,static_cast<size_type>(x));
00250     const size_type xx_index =
00251       clamp<size_type>(0,x_size-1,x_index+1);
00252     
00253     const size_type y_index  =
00254       clamp<size_type>(0,y_size-1,static_cast<size_type>(y));
00255     const size_type yy_index =
00256       clamp<size_type>(0,y_size-1,y_index+1);
00257 
00258     const real_type x_alpha = x - x_index;
00259     const real_type y_alpha = y - y_index;
00260 
00261     return
00262       (1.0f-x_alpha) * (1.0f-y_alpha) * array(x_index, y_index) +
00263       x_alpha        * (1.0f-y_alpha) * array(xx_index,y_index) +
00264       (1.0f-x_alpha) * y_alpha        * array(x_index, yy_index) +
00265       x_alpha        * y_alpha        * array(xx_index,yy_index);
00266       
00267   }
00268 
00269 
00270   inline double degree_to_radian(const double d){
00271     return d*M_PI/180;
00272   }
00273   
00274 
00275   inline double radian_to_degree(const double r){
00276     return r*180/M_PI;
00277   }
00278 
00279 
00280   template<typename Real>
00281   inline Real sign(const Real r){
00282     return (r==0) ? 0 : ((r>0) ? 1 : -1);
00283   }
00284 
00285 
00286   
00287 #ifndef WITHOUT_LIMITS    
00288 
00289   template<typename T> bool is_quiet_NaN(T x){
00290 
00291     const unsigned int size = sizeof(T)/sizeof(int);
00292     
00293     T ref = std::numeric_limits<T>::quiet_NaN();
00294     
00295     int* index_ref = reinterpret_cast<int*>(&ref);
00296     int* index_cmp = reinterpret_cast<int*>(&x);
00297 
00298     for(unsigned int i=0;i<size;i++){
00299       if (index_ref[i]!=index_cmp[i]){
00300         return false;
00301       }
00302     }
00303 
00304     return true;
00305   }
00306 
00307   
00308   template<typename T> bool is_signaling_NaN(T x){
00309     
00310     const unsigned int size = sizeof(T)/sizeof(int);
00311     
00312     T ref = std::numeric_limits<T>::signaling_NaN();
00313     
00314     int* index_ref = reinterpret_cast<int*>(&ref);
00315     int* index_cmp = reinterpret_cast<int*>(&x);
00316 
00317     for(unsigned int i=0;i<size;i++){
00318       if (index_ref[i]!=index_cmp[i]){
00319         return false;
00320       }
00321     }
00322 
00323     return true;
00324   }
00325 
00326 
00327   template<typename T> bool is_NaN(T x){
00328     return (is_quiet_NaN(x)||is_signaling_NaN(x));
00329   }
00330   
00331 #endif
00332 
00333   
00334 } // end of namespace
00335 
00336 
00337 #endif

Generated on Fri Aug 20 15:03:52 2004 by doxygen1.2.18