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
00098 private:
00099 double bandwidth;
00100 double bandwidthSquared;
00101 };
00102
00104 template<>
00105 class KernelTraits<SphericalKernel>
00106 {
00107 public:
00109 static const bool IsNormalized = true;
00110 };
00111
00112 };
00113 };
00114
00115 #endif