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 (
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
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
00087 if (max_radius<=1) circular=false;
00088
00089
00090 value_type kernelsum=0;
00091
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
00110
00111
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 }
00123
00124
00125 #endif