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

radialfunction.h

Go to the documentation of this file.
00001 
00007 #ifndef __RADIAL_FUNCTION_H__
00008 #define __RADIAL_FUNCTION_H__
00009 
00010 #include <cmath>
00011 #include <string>
00012 using std::string;
00013 
00014 #include "shuffledrand.h"
00015 #include "mathconstants.h"
00016 
00017 
00032 namespace RadialFunction {
00033 
00035   template<class T>
00036   inline T Constant( T, T )
00037     {  return 1.0;  }
00038 
00040   template<class T>
00041   inline T Random( T, T )
00042   {  return shuffled_rand();  }
00043 
00045   template<class T>
00046   inline T Gaussian( T x_sq, T sig_sq)
00047     {  return exp( -x_sq/(2*(Math::pi)*sig_sq) );  }
00048 
00054   template<class T>
00055   inline T LoG( T x_sq, T sig_sq) { 
00056     const T exponent = -x_sq/(2*sig_sq);
00057     return 1/((Math::pi)*sig_sq*sig_sq)*(1.0+exponent) * exp(exponent);
00058   }
00059 
00060   
00065   template<class matrix_type, class radial_function, class radius_type>
00066     matrix_type matrix
00067     (/* Function pointer or function object of the form T fn(T,T) */
00068      radial_function radial_fn,
00069      radius_type radius,
00070      radius_type max_radius_,
00071      string& errors,
00072      bool circular=true,
00073      bool normalize=true
00074      )
00075   {
00076     typedef typename matrix_type::value_type value_type;
00077     typedef typename matrix_type::size_type  size_type;
00078     
00079     const radius_type radius_sq      = radius*radius;
00080     /* Uses floating-point max_radius for circular radius, integer for other tasks */
00081     const radius_type max_radius_sq  = max_radius_*max_radius_;
00082     const size_type   max_radius     = size_type(floor((0.5+(max_radius_))));
00083     const size_type   kernelwidth    = std::max(size_type(1),size_type(max_radius*2+1));
00084     matrix_type kernel(kernelwidth,kernelwidth);
00085     
00086     /* Cropping is counterproductive for very small radii */
00087     if (max_radius<=1) circular=false;
00088     
00089     /* Create kernel matrix */
00090     value_type kernelsum=0;
00091     /*   ki and kj cannot be size_type since that might be unsigned */
00092     int ki = -max_radius;
00093     for (size_type i=0; i < kernelwidth; ki++,i++) {
00094       int kj = -max_radius;
00095       for (size_type j=0; j < kernelwidth; kj++,j++) {
00096         const size_type ki_sq = ki*ki;
00097         const size_type kj_sq = kj*kj;
00098         const size_type r_sq  = ki_sq + kj_sq;
00099         
00100         if (circular && (r_sq > max_radius_sq))
00101           kernel[i][j] = 0;
00102         else {
00103           const value_type val = (radial_fn)(r_sq,radius_sq);
00104           kernelsum += val;
00105           kernel[i][j] = val;
00106         }
00107       }
00108     }
00109     //cout << "Unnormalized sum of blurring kernel values is " <<kernelsum;
00110     
00111     /* Normalize kernel matrix */
00112     if (normalize) {
00113       if (kernelsum==0)
00114         errors += "Can't normalize a kernel that sums to zero";
00115       else
00116         kernel *= 1/kernelsum;
00117     }
00118     
00119     return kernel;
00120   }
00121 
00122 } /* namespace */
00123 
00124 
00125 #endif /* __RADIAL_FUNCTION_H__ */

Generated on Mon Jan 20 02:35:45 2003 for RF-LISSOM by doxygen1.3-rc2