MLPACK  1.0.4
spherical_kernel.hpp
Go to the documentation of this file.
00001 
00023 #ifndef __MLPACK_CORE_KERNELS_SPHERICAL_KERNEL_H
00024 #define __MLPACK_CORE_KERNELS_SPHERICAL_KERNEL_H
00025 
00026 #include <boost/math/special_functions/gamma.hpp>
00027 #include <mlpack/core.hpp>
00028 
00029 namespace mlpack {
00030 namespace kernel {
00031 
00032 class SphericalKernel
00033 {
00034  public:
00035   SphericalKernel() :
00036     bandwidth(1.0),
00037     bandwidthSquared(1.0) {}
00038   SphericalKernel(double b) :
00039     bandwidth(b),
00040     bandwidthSquared(b*b) {}
00041 
00042   template<typename VecType>
00043   double Evaluate(const VecType& a, const VecType& b)
00044   {
00045     return
00046       (metric::SquaredEuclideanDistance::Evaluate(a, b) <= bandwidthSquared) ?
00047         1.0 : 0.0;
00048   }
00061   template<typename VecType>
00062   double ConvolutionIntegral(const VecType& a, const VecType& b)
00063   {
00064     double distance = sqrt(metric::SquaredEuclideanDistance::Evaluate(a, b));
00065     if (distance >= 2.0 * bandwidth)
00066     {
00067       return 0.0;
00068     }
00069     double volumeSquared = pow(Normalizer(a.n_rows), 2.0);
00070 
00071     switch(a.n_rows)
00072     {
00073       case 1:
00074         return 1.0 / volumeSquared * (2.0 * bandwidth - distance);
00075         break;
00076       case 2:
00077         return 1.0 / volumeSquared *
00078           (2.0 * bandwidth * bandwidth * acos(distance/(2.0 * bandwidth)) -
00079           distance / 4.0 * sqrt(4.0*bandwidth*bandwidth-distance*distance));
00080         break;
00081       default:
00082         Log::Fatal << "The spherical kernel does not support convolution\
00083           integrals above dimension two, yet..." << std::endl;
00084         return -1.0;
00085         break;
00086     }
00087   }
00088   double Normalizer(size_t dimension)
00089   {
00090     return pow(bandwidth, (double) dimension) * pow(M_PI, dimension / 2.0) /
00091         boost::math::tgamma(dimension / 2.0 + 1.0);
00092   }
00093   double Evaluate(double t)
00094   {
00095     return (t <= bandwidth) ? 1.0 : 0.0;
00096   }
00097  private:
00098   double bandwidth;
00099   double bandwidthSquared;
00100 };
00101 
00102 }; // namespace kernel
00103 }; // namespace mlpack
00104 
00105 #endif