[mlpack-git] master: Take different types for each kernel and metric argument. (3e7d8bc)
gitdub at big.cc.gt.atl.ga.us
gitdub at big.cc.gt.atl.ga.us
Sun Apr 5 18:48:23 EDT 2015
Repository : https://github.com/mlpack/mlpack
On branch : master
Link : https://github.com/mlpack/mlpack/compare/c41bc8d54695f1a20b3de551bc80fe7221dd3cd1...81fe638aa0c8d9592bbf7b434110140eb9bb86e7
>---------------------------------------------------------------
commit 3e7d8bc2bb681686ca5b731ebeb0500e0327335d
Author: ryan <ryan at ratml.org>
Date: Fri Apr 3 17:18:50 2015 -0400
Take different types for each kernel and metric argument.
>---------------------------------------------------------------
3e7d8bc2bb681686ca5b731ebeb0500e0327335d
src/mlpack/core/kernels/cosine_distance.hpp | 4 +-
src/mlpack/core/kernels/cosine_distance_impl.hpp | 4 +-
src/mlpack/core/kernels/epanechnikov_kernel.hpp | 13 ++---
.../core/kernels/epanechnikov_kernel_impl.hpp | 16 +++---
src/mlpack/core/kernels/example_kernel.hpp | 18 ++++---
src/mlpack/core/kernels/gaussian_kernel.hpp | 16 +++---
.../core/kernels/hyperbolic_tangent_kernel.hpp | 8 +--
src/mlpack/core/kernels/laplacian_kernel.hpp | 9 ++--
src/mlpack/core/kernels/linear_kernel.hpp | 8 +--
src/mlpack/core/kernels/polynomial_kernel.hpp | 8 +--
src/mlpack/core/kernels/spherical_kernel.hpp | 62 ++++++++++++++--------
src/mlpack/core/kernels/triangular_kernel.hpp | 6 ++-
src/mlpack/core/metrics/ip_metric.hpp | 28 ++++++++--
src/mlpack/core/metrics/lmetric.hpp | 15 ++++--
src/mlpack/core/metrics/lmetric_impl.hpp | 34 ++++++------
src/mlpack/core/metrics/mahalanobis_distance.hpp | 10 ++--
.../core/metrics/mahalanobis_distance_impl.hpp | 12 ++---
17 files changed, 164 insertions(+), 107 deletions(-)
diff --git a/src/mlpack/core/kernels/cosine_distance.hpp b/src/mlpack/core/kernels/cosine_distance.hpp
index d2a6fea..77c8142 100644
--- a/src/mlpack/core/kernels/cosine_distance.hpp
+++ b/src/mlpack/core/kernels/cosine_distance.hpp
@@ -32,8 +32,8 @@ class CosineDistance
* @param b Second vector.
* @return d(a, b).
*/
- template<typename VecType>
- static double Evaluate(const VecType& a, const VecType& b);
+ template<typename VecTypeA, typename VecTypeB>
+ static double Evaluate(const VecTypeA& a, const VecTypeB& b);
/**
* Returns a string representation of this object.
diff --git a/src/mlpack/core/kernels/cosine_distance_impl.hpp b/src/mlpack/core/kernels/cosine_distance_impl.hpp
index 69a1a3e..870691a 100644
--- a/src/mlpack/core/kernels/cosine_distance_impl.hpp
+++ b/src/mlpack/core/kernels/cosine_distance_impl.hpp
@@ -12,8 +12,8 @@
namespace mlpack {
namespace kernel {
-template<typename VecType>
-double CosineDistance::Evaluate(const VecType& a, const VecType& b)
+template<typename VecTypeA, typename VecTypeB>
+double CosineDistance::Evaluate(const VecTypeA& a, const VecTypeB& b)
{
// Since we are using the L2 inner product, this is easy. But we have to make
// sure we aren't dividing by zero (if we are, then the cosine similarity is
diff --git a/src/mlpack/core/kernels/epanechnikov_kernel.hpp b/src/mlpack/core/kernels/epanechnikov_kernel.hpp
index c47bd43..4db40c6 100644
--- a/src/mlpack/core/kernels/epanechnikov_kernel.hpp
+++ b/src/mlpack/core/kernels/epanechnikov_kernel.hpp
@@ -37,11 +37,13 @@ class EpanechnikovKernel
/**
* Evaluate the Epanechnikov kernel on the given two inputs.
*
+ * @tparam VecTypeA Type of first vector.
+ * @tparam VecTypeB Type of second vector.
* @param a One input vector.
* @param b The other input vector.
*/
- template<typename Vec1Type, typename Vec2Type>
- double Evaluate(const Vec1Type& a, const Vec2Type& b) const;
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b) const;
/**
* Evaluate the Epanechnikov kernel given that the distance between the two
@@ -58,9 +60,8 @@ class EpanechnikovKernel
* @param b Second vector.
* @return the convolution integral value.
*/
-
- template<typename VecType>
- double ConvolutionIntegral(const VecType& a, const VecType& b);
+ template<typename VecTypeA, typename VecTypeB>
+ double ConvolutionIntegral(const VecTypeA& a, const VecTypeB& b);
/**
* Compute the normalizer of this Epanechnikov kernel for the given dimension.
@@ -69,7 +70,7 @@ class EpanechnikovKernel
*/
double Normalizer(const size_t dimension);
- // Returns String of O bject
+ //! Returns string representation of object.
std::string ToString() const;
private:
diff --git a/src/mlpack/core/kernels/epanechnikov_kernel_impl.hpp b/src/mlpack/core/kernels/epanechnikov_kernel_impl.hpp
index d1e5eb6..bd40bb2 100644
--- a/src/mlpack/core/kernels/epanechnikov_kernel_impl.hpp
+++ b/src/mlpack/core/kernels/epanechnikov_kernel_impl.hpp
@@ -15,28 +15,28 @@
namespace mlpack {
namespace kernel {
-template<typename Vec1Type, typename Vec2Type>
-inline double EpanechnikovKernel::Evaluate(const Vec1Type& a, const Vec2Type& b)
+template<typename VecTypeA, typename VecTypeB>
+inline double EpanechnikovKernel::Evaluate(const VecTypeA& a, const VecTypeB& b)
const
{
return std::max(0.0, 1.0 - metric::SquaredEuclideanDistance::Evaluate(a, b)
* inverseBandwidthSquared);
}
-
-
/**
* Obtains the convolution integral [integral of K(||x-a||) K(||b-x||) dx]
* for the two vectors.
*
- * @tparam VecType Type of vector (arma::vec, arma::spvec should be expected).
+ * @tparam VecTypeA Type of first vector (arma::vec, arma::sp_vec should be
+ * expected).
+ * @tparam VecTypeB Type of second vector (arma::vec, arma::sp_vec).
* @param a First vector.
* @param b Second vector.
* @return the convolution integral value.
*/
-template<typename VecType>
-double EpanechnikovKernel::ConvolutionIntegral(const VecType& a,
- const VecType& b)
+template<typename VecTypeA, typename VecTypeB>
+double EpanechnikovKernel::ConvolutionIntegral(const VecTypeA& a,
+ const VecTypeB& b)
{
double distance = sqrt(metric::SquaredEuclideanDistance::Evaluate(a, b));
if (distance >= 2.0 * bandwidth)
diff --git a/src/mlpack/core/kernels/example_kernel.hpp b/src/mlpack/core/kernels/example_kernel.hpp
index d957e7c..46380ea 100644
--- a/src/mlpack/core/kernels/example_kernel.hpp
+++ b/src/mlpack/core/kernels/example_kernel.hpp
@@ -93,13 +93,15 @@ class ExampleKernel
* function static. For a more complex example which cannot be declared
* static, see the GaussianKernel, which stores an internal parameter.
*
- * @tparam VecType Type of vector (arma::vec, arma::spvec should be expected).
+ * @tparam VecTypeA Type of first vector (arma::vec, arma::sp_vec should be
+ * expected).
+ * @tparam VecTypeB Type of second vector (arma::vec, arma::sp_vec).
* @param a First vector.
* @param b Second vector.
* @return K(a, b).
*/
- template<typename VecType>
- static double Evaluate(const VecType& /* a */, const VecType& /* b */)
+ template<typename VecTypeA, typename VecTypeB>
+ static double Evaluate(const VecTypeA& /* a */, const VecTypeB& /* b */)
{ return 0; }
/**
@@ -121,14 +123,16 @@ class ExampleKernel
* function static. For a more complex example which cannot be declared
* static, see the GaussianKernel, which stores an internal parameter.
*
- * @tparam VecType Type of vector (arma::vec, arma::spvec should be expected).
+ * @tparam VecTypeA Type of first vector (arma::vec, arma::sp_vec should be
+ * expected).
+ * @tparam VecTypeB Type of second vector (arma::vec, arma::sp_vec).
* @param a First vector.
* @param b Second vector.
* @return the convolution integral value.
*/
- template<typename VecType>
- static double ConvolutionIntegral(const VecType& /* a */,
- const VecType& /* b */) { return 0; }
+ template<typename VecTypeA, typename VecTypeB>
+ static double ConvolutionIntegral(const VecTypeA& /* a */,
+ const VecTypeB& /* b */) { return 0; }
/**
* Obtains the normalizing volume for the kernel with dimension $dimension$.
diff --git a/src/mlpack/core/kernels/gaussian_kernel.hpp b/src/mlpack/core/kernels/gaussian_kernel.hpp
index 859a91d..9e52638 100644
--- a/src/mlpack/core/kernels/gaussian_kernel.hpp
+++ b/src/mlpack/core/kernels/gaussian_kernel.hpp
@@ -55,8 +55,8 @@ class GaussianKernel
* @return K(a, b) using the bandwidth (@f$\mu at f$) specified in the
* constructor.
*/
- template<typename VecType>
- double Evaluate(const VecType& a, const VecType& b) const
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b) const
{
// The precalculation of gamma saves us a little computation time.
return exp(gamma * metric::SquaredEuclideanDistance::Evaluate(a, b));
@@ -89,15 +89,15 @@ class GaussianKernel
/**
* Obtain a convolution integral of the Gaussian kernel.
*
- * @param a, first vector
- * @param b, second vector
- * @return the convolution integral
+ * @param a First vector.
+ * @param b Second vector.
+ * @return The convolution integral.
*/
- template<typename VecType>
- double ConvolutionIntegral(const VecType& a, const VecType& b)
+ template<typename VecTypeA, typename VecTypeB>
+ double ConvolutionIntegral(const VecTypeA& a, const VecTypeB& b)
{
return Evaluate(sqrt(metric::SquaredEuclideanDistance::Evaluate(a, b) / 2.0)) /
- (Normalizer(a.n_rows) * pow(2.0, (double) a.n_rows / 2.0));
+ (Normalizer(a.n_rows) * pow(2.0, (double) a.n_rows / 2.0));
}
diff --git a/src/mlpack/core/kernels/hyperbolic_tangent_kernel.hpp b/src/mlpack/core/kernels/hyperbolic_tangent_kernel.hpp
index 77fb4e7..7ebd41c 100644
--- a/src/mlpack/core/kernels/hyperbolic_tangent_kernel.hpp
+++ b/src/mlpack/core/kernels/hyperbolic_tangent_kernel.hpp
@@ -44,13 +44,15 @@ class HyperbolicTangentKernel
* Evaluate the hyperbolic tangent kernel. This evaluation uses Armadillo's
* dot() function.
*
- * @tparam VecType Type of vector (should be arma::vec or arma::spvec).
+ * @tparam VecTypeA Type of first vector (should be arma::vec or
+ * arma::sp_vec).
+ * @tparam VecTypeB Type of second vector (arma::vec / arma::sp_vec).
* @param a First vector.
* @param b Second vector.
* @return K(a, b).
*/
- template<typename VecType>
- double Evaluate(const VecType& a, const VecType& b)
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b)
{
return tanh(scale * arma::dot(a, b) + offset);
}
diff --git a/src/mlpack/core/kernels/laplacian_kernel.hpp b/src/mlpack/core/kernels/laplacian_kernel.hpp
index 65f99a3..bb865ef 100644
--- a/src/mlpack/core/kernels/laplacian_kernel.hpp
+++ b/src/mlpack/core/kernels/laplacian_kernel.hpp
@@ -45,14 +45,15 @@ class LaplacianKernel
* distance metric, not the Euclidean distance, but for now, the Euclidean
* distance is used.
*
- * @tparam VecType Type of vector (likely arma::vec or arma::spvec).
+ * @tparam VecTypeA Type of first vector (likely arma::vec or arma::sp_vec).
+ * @tparam VecTypeB Type of second vector (arma::vec / arma::sp_vec).
* @param a First vector.
* @param b Second vector.
* @return K(a, b) using the bandwidth (@f$\mu at f$) specified in the
- * constructor.
+ * constructor.
*/
- template<typename VecType>
- double Evaluate(const VecType& a, const VecType& b) const
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b) const
{
// The precalculation of gamma saves us a little computation time.
return exp(-metric::EuclideanDistance::Evaluate(a, b) / bandwidth);
diff --git a/src/mlpack/core/kernels/linear_kernel.hpp b/src/mlpack/core/kernels/linear_kernel.hpp
index 6dfbfba..26c098e 100644
--- a/src/mlpack/core/kernels/linear_kernel.hpp
+++ b/src/mlpack/core/kernels/linear_kernel.hpp
@@ -37,13 +37,15 @@ class LinearKernel
* Simple evaluation of the dot product. This evaluation uses Armadillo's
* dot() function.
*
- * @tparam VecType Type of vector (should be arma::vec or arma::spvec).
+ * @tparam VecTypeA Type of first vector (should be arma::vec or
+ * arma::sp_vec).
+ * @tparam VecTypeB Type of second vector (arma::vec / arma::sp_vec).
* @param a First vector.
* @param b Second vector.
* @return K(a, b).
*/
- template<typename VecType>
- static double Evaluate(const VecType& a, const VecType& b)
+ template<typename VecTypeA, typename VecTypeB>
+ static double Evaluate(const VecTypeA& a, const VecTypeB& b)
{
return arma::dot(a, b);
}
diff --git a/src/mlpack/core/kernels/polynomial_kernel.hpp b/src/mlpack/core/kernels/polynomial_kernel.hpp
index ca0eff6..b64f133 100644
--- a/src/mlpack/core/kernels/polynomial_kernel.hpp
+++ b/src/mlpack/core/kernels/polynomial_kernel.hpp
@@ -39,13 +39,15 @@ class PolynomialKernel
* Simple evaluation of the dot product. This evaluation uses Armadillo's
* dot() function.
*
- * @tparam VecType Type of vector (should be arma::vec or arma::spvec).
+ * @tparam VecTypeA Type of first vector (should be arma::vec or
+ * arma::sp_vec).
+ * @tparam VecTypeB Type of second vector (arma::vec / arma::sp_vec).
* @param a First vector.
* @param b Second vector.
* @return K(a, b).
*/
- template<typename VecType>
- double Evaluate(const VecType& a, const VecType& b) const
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b) const
{
return pow((arma::dot(a, b) + offset), degree);
}
diff --git a/src/mlpack/core/kernels/spherical_kernel.hpp b/src/mlpack/core/kernels/spherical_kernel.hpp
index faf355c..d8e04f8 100644
--- a/src/mlpack/core/kernels/spherical_kernel.hpp
+++ b/src/mlpack/core/kernels/spherical_kernel.hpp
@@ -1,12 +1,9 @@
/**
* @file spherical_kernel.hpp
* @author Neil Slagle
- *
- * This is an example kernel. If you are making your own kernel, follow the
- * outline specified in this file.
*/
-#ifndef __MLPACK_CORE_KERNELS_SPHERICAL_KERNEL_H
-#define __MLPACK_CORE_KERNELS_SPHERICAL_KERNEL_H
+#ifndef __MLPACK_CORE_KERNELS_SPHERICAL_KERNEL_HPP
+#define __MLPACK_CORE_KERNELS_SPHERICAL_KERNEL_HPP
#include <boost/math/special_functions/gamma.hpp>
#include <mlpack/core.hpp>
@@ -14,37 +11,50 @@
namespace mlpack {
namespace kernel {
+/**
+ * The spherical kernel, which is 1 when the distance between the two argument
+ * points is less than or equal to the bandwidth, or 0 otherwise.
+ */
class SphericalKernel
{
public:
- SphericalKernel() :
- bandwidth(1.0),
- bandwidthSquared(1.0) {}
- SphericalKernel(double b) :
- bandwidth(b),
- bandwidthSquared(b*b) {}
+ /**
+ * Construct the SphericalKernel with the given bandwidth.
+ */
+ SphericalKernel(const double bandwidth = 1.0) :
+ bandwidth(bandwidth),
+ bandwidthSquared(std::pow(bandwidth, 2.0))
+ { /* Nothing to do. */ }
- template<typename VecType>
- double Evaluate(const VecType& a, const VecType& b)
+ /**
+ * Evaluate the spherical kernel with the given two vectors.
+ *
+ * @tparam VecTypeA Type of first vector.
+ * @tparam VecTypeB Type of second vector.
+ * @param a First vector.
+ * @param b Second vector.
+ * @return The kernel evaluation between the two vectors.
+ */
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b) const
{
return
- (metric::SquaredEuclideanDistance::Evaluate(a, b) <= bandwidthSquared) ?
+ (metric::SquaredEuclideanDistance::Evaluate(a, b) <= bandwidthSquared) ?
1.0 : 0.0;
}
/**
* Obtains the convolution integral [integral K(||x-a||)K(||b-x||)dx]
- * for the two vectors. In this case, because
- * our simple example kernel has no internal parameters, we can declare the
- * function static. For a more complex example which cannot be declared
- * static, see the GaussianKernel, which stores an internal parameter.
+ * for the two vectors.
*
- * @tparam VecType Type of vector (arma::vec, arma::spvec should be expected).
+ * @tparam VecTypeA Type of first vector (arma::vec, arma::sp_vec should be
+ * expected).
+ * @tparam VecTypeB Type of second vector.
* @param a First vector.
* @param b Second vector.
* @return the convolution integral value.
*/
- template<typename VecType>
- double ConvolutionIntegral(const VecType& a, const VecType& b)
+ template<typename VecTypeA, typename VecTypeB>
+ double ConvolutionIntegral(const VecTypeA& a, const VecTypeB& b) const
{
double distance = sqrt(metric::SquaredEuclideanDistance::Evaluate(a, b));
if (distance >= 2.0 * bandwidth)
@@ -70,12 +80,18 @@ class SphericalKernel
break;
}
}
- double Normalizer(size_t dimension)
+ double Normalizer(size_t dimension) const
{
return pow(bandwidth, (double) dimension) * pow(M_PI, dimension / 2.0) /
boost::math::tgamma(dimension / 2.0 + 1.0);
}
- double Evaluate(double t)
+
+ /**
+ * Evaluate the kernel when only a distance is given, not two points.
+ *
+ * @param t Argument to kernel.
+ */
+ double Evaluate(const double t) const
{
return (t <= bandwidth) ? 1.0 : 0.0;
}
diff --git a/src/mlpack/core/kernels/triangular_kernel.hpp b/src/mlpack/core/kernels/triangular_kernel.hpp
index e724c76..7b8020a 100644
--- a/src/mlpack/core/kernels/triangular_kernel.hpp
+++ b/src/mlpack/core/kernels/triangular_kernel.hpp
@@ -35,11 +35,13 @@ class TriangularKernel
/**
* Evaluate the triangular kernel for the two given vectors.
*
+ * @tparam VecTypeA Type of first vector.
+ * @tparam VecTypeB Type of second vector.
* @param a First vector.
* @param b Second vector.
*/
- template<typename Vec1Type, typename Vec2Type>
- double Evaluate(const Vec1Type& a, const Vec2Type& b) const
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b) const
{
return std::max(0.0, (1 - metric::EuclideanDistance::Evaluate(a, b) /
bandwidth));
diff --git a/src/mlpack/core/metrics/ip_metric.hpp b/src/mlpack/core/metrics/ip_metric.hpp
index af87177..c8d97df 100644
--- a/src/mlpack/core/metrics/ip_metric.hpp
+++ b/src/mlpack/core/metrics/ip_metric.hpp
@@ -11,6 +11,18 @@
namespace mlpack {
namespace metric {
+/**
+ * The inner product metric, IPMetric, takes a given Mercer kernel (KernelType),
+ * and when Evaluate() is called, returns the distance between the two points in
+ * kernel space:
+ *
+ * @f[
+ * d(x, y) = \sqrt{ K(x, x) + K(y, y) - 2K(x, y) }.
+ * @f]
+ *
+ * @tparam KernelType Type of Kernel to use. This must be a Mercer kernel
+ * (positive definite), otherwise the metric may not be valid.
+ */
template<typename KernelType>
class IPMetric
{
@@ -26,18 +38,24 @@ class IPMetric
/**
* Evaluate the metric.
+ *
+ * @tparam VecTypeA Type of first vector.
+ * @tparam VecTypeB Type of second vector.
+ * @param a First vector.
+ * @param b Second vector.
+ * @return Distance between the two points in kernel space.
*/
- template<typename Vec1Type, typename Vec2Type>
- double Evaluate(const Vec1Type& a, const Vec2Type& b);
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b);
//! Get the kernel.
const KernelType& Kernel() const { return kernel; }
//! Modify the kernel.
KernelType& Kernel() { return kernel; }
- /**
- * Returns a string representation of this object.
- */
+
+ //! Returns a string representation of this object.
std::string ToString() const;
+
private:
//! The locally stored kernel, if it is necessary.
KernelType* localKernel;
diff --git a/src/mlpack/core/metrics/lmetric.hpp b/src/mlpack/core/metrics/lmetric.hpp
index 8ac655d..25f19fa 100644
--- a/src/mlpack/core/metrics/lmetric.hpp
+++ b/src/mlpack/core/metrics/lmetric.hpp
@@ -59,16 +59,25 @@ class LMetric
{
public:
/***
- * Default constructor does nothing, but is required to satisfy the Kernel
+ * Default constructor does nothing, but is required to satisfy the Metric
* policy.
*/
LMetric() { }
/**
* Computes the distance between two points.
+ *
+ * @tparam VecTypeA Type of first vector (generally arma::vec or
+ * arma::sp_vec).
+ * @tparam VecTypeB Type of second vector.
+ * @param a First vector.
+ * @param b Second vector.
+ * @return Distance between vectors a and b.
*/
- template<typename VecType1, typename VecType2>
- static double Evaluate(const VecType1& a, const VecType2& b);
+ template<typename VecTypeA, typename VecTypeB>
+ static double Evaluate(const VecTypeA& a, const VecTypeB& b);
+
+ //! Return a string representation of the object.
std::string ToString() const;
};
diff --git a/src/mlpack/core/metrics/lmetric_impl.hpp b/src/mlpack/core/metrics/lmetric_impl.hpp
index 8cc81c5..7558a06 100644
--- a/src/mlpack/core/metrics/lmetric_impl.hpp
+++ b/src/mlpack/core/metrics/lmetric_impl.hpp
@@ -15,9 +15,9 @@ namespace metric {
// Unspecialized implementation. This should almost never be used...
template<int Power, bool TakeRoot>
-template<typename VecType1, typename VecType2>
-double LMetric<Power, TakeRoot>::Evaluate(const VecType1& a,
- const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double LMetric<Power, TakeRoot>::Evaluate(const VecTypeA& a,
+ const VecTypeB& b)
{
double sum = 0;
for (size_t i = 0; i < a.n_elem; i++)
@@ -42,38 +42,38 @@ std::string LMetric<Power, TakeRoot>::ToString() const
// L1-metric specializations; the root doesn't matter.
template<>
-template<typename VecType1, typename VecType2>
-double LMetric<1, true>::Evaluate(const VecType1& a, const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double LMetric<1, true>::Evaluate(const VecTypeA& a, const VecTypeB& b)
{
return accu(abs(a - b));
}
template<>
-template<typename VecType1, typename VecType2>
-double LMetric<1, false>::Evaluate(const VecType1& a, const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double LMetric<1, false>::Evaluate(const VecTypeA& a, const VecTypeB& b)
{
return accu(abs(a - b));
}
// L2-metric specializations.
template<>
-template<typename VecType1, typename VecType2>
-double LMetric<2, true>::Evaluate(const VecType1& a, const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double LMetric<2, true>::Evaluate(const VecTypeA& a, const VecTypeB& b)
{
return sqrt(accu(square(a - b)));
}
template<>
-template<typename VecType1, typename VecType2>
-double LMetric<2, false>::Evaluate(const VecType1& a, const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double LMetric<2, false>::Evaluate(const VecTypeA& a, const VecTypeB& b)
{
return accu(square(a - b));
}
// L3-metric specialization (not very likely to be used, but just in case).
template<>
-template<typename VecType1, typename VecType2>
-double LMetric<3, true>::Evaluate(const VecType1& a, const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double LMetric<3, true>::Evaluate(const VecTypeA& a, const VecTypeB& b)
{
double sum = 0;
for (size_t i = 0; i < a.n_elem; i++)
@@ -83,16 +83,16 @@ double LMetric<3, true>::Evaluate(const VecType1& a, const VecType2& b)
}
template<>
-template<typename VecType1, typename VecType2>
-double LMetric<3, false>::Evaluate(const VecType1& a, const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double LMetric<3, false>::Evaluate(const VecTypeA& a, const VecTypeB& b)
{
return accu(pow(abs(a - b), 3.0));
}
// L-infinity (Chebyshev distance) specialization
template<>
-template<typename VecType1, typename VecType2>
-double LMetric<INT_MAX, false>::Evaluate(const VecType1& a, const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double LMetric<INT_MAX, false>::Evaluate(const VecTypeA& a, const VecTypeB& b)
{
return arma::as_scalar(max(abs(a - b)));
}
diff --git a/src/mlpack/core/metrics/mahalanobis_distance.hpp b/src/mlpack/core/metrics/mahalanobis_distance.hpp
index 23518dd..88bcca3 100644
--- a/src/mlpack/core/metrics/mahalanobis_distance.hpp
+++ b/src/mlpack/core/metrics/mahalanobis_distance.hpp
@@ -80,11 +80,8 @@ class MahalanobisDistance
* @param a First vector.
* @param b Second vector.
*/
-
- // Return String of Object
- std::string ToString() const;
- template<typename VecType1, typename VecType2>
- double Evaluate(const VecType1& a, const VecType2& b);
+ template<typename VecTypeA, typename VecTypeB>
+ double Evaluate(const VecTypeA& a, const VecTypeB& b);
/**
* Access the covariance matrix.
@@ -99,6 +96,9 @@ class MahalanobisDistance
* @return Reference to the covariance matrix.
*/
arma::mat& Covariance() { return covariance; }
+
+ //! Return string representation of object.
+ std::string ToString() const;
private:
//! The covariance matrix associated with this distance.
arma::mat covariance;
diff --git a/src/mlpack/core/metrics/mahalanobis_distance_impl.hpp b/src/mlpack/core/metrics/mahalanobis_distance_impl.hpp
index 0175b7f..b9f9199 100644
--- a/src/mlpack/core/metrics/mahalanobis_distance_impl.hpp
+++ b/src/mlpack/core/metrics/mahalanobis_distance_impl.hpp
@@ -16,9 +16,9 @@ namespace metric {
* Specialization for non-rooted case.
*/
template<>
-template<typename VecType1, typename VecType2>
-double MahalanobisDistance<false>::Evaluate(const VecType1& a,
- const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double MahalanobisDistance<false>::Evaluate(const VecTypeA& a,
+ const VecTypeB& b)
{
arma::vec m = (a - b);
arma::mat out = trans(m) * covariance * m; // 1x1
@@ -29,9 +29,9 @@ double MahalanobisDistance<false>::Evaluate(const VecType1& a,
* sqrt().
*/
template<>
-template<typename VecType1, typename VecType2>
-double MahalanobisDistance<true>::Evaluate(const VecType1& a,
- const VecType2& b)
+template<typename VecTypeA, typename VecTypeB>
+double MahalanobisDistance<true>::Evaluate(const VecTypeA& a,
+ const VecTypeB& b)
{
// Check if covariance matrix has been initialized.
if (covariance.n_rows == 0)
More information about the mlpack-git
mailing list