double ConvolutionIntegral(const VecTypeA& a, const VecTypeB& b) const { double distance = sqrt(metric::SquaredEuclideanDistance::Evaluate(a, b)); if (distance >= 2.0 * bandwidth) { return 0.0; } double volumeSquared = pow(Normalizer(a.n_rows), 2.0); switch(a.n_rows) { case 1: return 1.0 / volumeSquared * (2.0 * bandwidth - distance); break; case 2: return 1.0 / volumeSquared * (2.0 * bandwidth * bandwidth * acos(distance/(2.0 * bandwidth)) - distance / 4.0 * sqrt(4.0*bandwidth*bandwidth-distance*distance)); break; default: Log::Fatal << "The spherical kernel does not support convolution\ integrals above dimension two, yet..." << std::endl; return -1.0; break; } }
double EpanechnikovKernel::ConvolutionIntegral(const VecType& a, const VecType& b) { double distance = sqrt(metric::SquaredEuclideanDistance::Evaluate(a, b)); if (distance >= 2.0 * bandwidth) return 0.0; double volumeSquared = std::pow(Normalizer(a.n_rows), 2.0); switch (a.n_rows) { case 1: return 1.0 / volumeSquared * (16.0 / 15.0 * bandwidth - 4.0 * distance * distance / (3.0 * bandwidth) + 2.0 * distance * distance * distance / (3.0 * bandwidth * bandwidth) - std::pow(distance, 5.0) / (30.0 * std::pow(bandwidth, 4.0))); break; case 2: return 1.0 / volumeSquared * ((2.0 / 3.0 * bandwidth * bandwidth - distance * distance) * asin(sqrt(1.0 - std::pow(distance / (2.0 * bandwidth), 2.0))) + sqrt(4.0 * bandwidth * bandwidth - distance * distance) * (distance / 6.0 + 2.0 / 9.0 * distance * std::pow(distance / bandwidth, 2.0) - distance / 72.0 * std::pow(distance / bandwidth, 4.0))); break; default: Log::Fatal << "EpanechnikovKernel::ConvolutionIntegral(): dimension " << a.n_rows << " not supported."; return -1.0; // This line will not execute. break; } }
double ConvolutionIntegral(const VecType& a, const VecType& b) { return Evaluate(sqrt(metric::SquaredEuclideanDistance::Evaluate(a, b) / 2.0)) / (Normalizer(a.n_rows) * pow(2.0, (double) a.n_rows / 2.0)); }