[mlpack-git] master: Generalize metrics to arbitrary types. (c566aaf)
gitdub at mlpack.org
gitdub at mlpack.org
Wed Jun 8 10:05:13 EDT 2016
Repository : https://github.com/mlpack/mlpack
On branch : master
Link : https://github.com/mlpack/mlpack/compare/8551a21f9821399ded164d8dbb11e453bcb33c45...e8e2ff17da5978cacf3c9a45d4aa572a4bf008e5
>---------------------------------------------------------------
commit c566aaf3549a3863acab39f874d9cbd492ea07b0
Author: Ryan Curtin <ryan at ratml.org>
Date: Wed Jun 8 14:04:53 2016 +0000
Generalize metrics to arbitrary types.
>---------------------------------------------------------------
c566aaf3549a3863acab39f874d9cbd492ea07b0
src/mlpack/core/metrics/ip_metric.hpp | 2 +-
src/mlpack/core/metrics/ip_metric_impl.hpp | 10 +++---
src/mlpack/core/metrics/lmetric.hpp | 3 +-
src/mlpack/core/metrics/lmetric_impl.hpp | 57 +++++++++++++++++++-----------
4 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/src/mlpack/core/metrics/ip_metric.hpp b/src/mlpack/core/metrics/ip_metric.hpp
index d8caf2f..b55ace8 100644
--- a/src/mlpack/core/metrics/ip_metric.hpp
+++ b/src/mlpack/core/metrics/ip_metric.hpp
@@ -46,7 +46,7 @@ class IPMetric
* @return Distance between the two points in kernel space.
*/
template<typename VecTypeA, typename VecTypeB>
- double Evaluate(const VecTypeA& a, const VecTypeB& b);
+ typename VecTypeA::elem_type Evaluate(const VecTypeA& a, const VecTypeB& b);
//! Get the kernel.
const KernelType& Kernel() const { return *kernel; }
diff --git a/src/mlpack/core/metrics/ip_metric_impl.hpp b/src/mlpack/core/metrics/ip_metric_impl.hpp
index 4297c94..0d9cc1c 100644
--- a/src/mlpack/core/metrics/ip_metric_impl.hpp
+++ b/src/mlpack/core/metrics/ip_metric_impl.hpp
@@ -44,8 +44,9 @@ IPMetric<KernelType>::~IPMetric()
template<typename KernelType>
template<typename Vec1Type, typename Vec2Type>
-inline double IPMetric<KernelType>::Evaluate(const Vec1Type& a,
- const Vec2Type& b)
+inline typename Vec1Type::elem_type IPMetric<KernelType>::Evaluate(
+ const Vec1Type& a,
+ const Vec2Type& b)
{
// This is the metric induced by the kernel function.
// Maybe we can do better by caching some of this?
@@ -71,8 +72,9 @@ void IPMetric<KernelType>::Serialize(Archive& ar,
// the Euclidean distance.
template<>
template<typename Vec1Type, typename Vec2Type>
-inline double IPMetric<kernel::LinearKernel>::Evaluate(const Vec1Type& a,
- const Vec2Type& b)
+inline typename Vec1Type::elem_type IPMetric<kernel::LinearKernel>::Evaluate(
+ const Vec1Type& a,
+ const Vec2Type& b)
{
return metric::LMetric<2, true>::Evaluate(a, b);
}
diff --git a/src/mlpack/core/metrics/lmetric.hpp b/src/mlpack/core/metrics/lmetric.hpp
index 5d599ab..240ae2a 100644
--- a/src/mlpack/core/metrics/lmetric.hpp
+++ b/src/mlpack/core/metrics/lmetric.hpp
@@ -75,7 +75,8 @@ class LMetric
* @return Distance between vectors a and b.
*/
template<typename VecTypeA, typename VecTypeB>
- static double Evaluate(const VecTypeA& a, const VecTypeB& b);
+ static typename VecTypeA::elem_type Evaluate(const VecTypeA& a,
+ const VecTypeB& b);
//! Serialize the metric (nothing to do).
template<typename Archive>
diff --git a/src/mlpack/core/metrics/lmetric_impl.hpp b/src/mlpack/core/metrics/lmetric_impl.hpp
index c87b7e7..5e1c886 100644
--- a/src/mlpack/core/metrics/lmetric_impl.hpp
+++ b/src/mlpack/core/metrics/lmetric_impl.hpp
@@ -16,74 +16,89 @@ namespace metric {
// Unspecialized implementation. This should almost never be used...
template<int Power, bool TakeRoot>
template<typename VecTypeA, typename VecTypeB>
-double LMetric<Power, TakeRoot>::Evaluate(const VecTypeA& a,
- const VecTypeB& b)
+typename VecTypeA::elem_type LMetric<Power, TakeRoot>::Evaluate(
+ const VecTypeA& a,
+ const VecTypeB& b)
{
- double sum = 0;
+ typename VecTypeA::elem_type sum = 0;
for (size_t i = 0; i < a.n_elem; i++)
- sum += pow(fabs(a[i] - b[i]), Power);
+ sum += std::pow(fabs(a[i] - b[i]), Power);
if (!TakeRoot) // The compiler should optimize this correctly at compile-time.
return sum;
- return pow(sum, (1.0 / Power));
+ return std::pow(sum, (1.0 / Power));
}
// L1-metric specializations; the root doesn't matter.
template<>
template<typename VecTypeA, typename VecTypeB>
-double LMetric<1, true>::Evaluate(const VecTypeA& a, const VecTypeB& b)
+typename VecTypeA::elem_type LMetric<1, true>::Evaluate(
+ const VecTypeA& a,
+ const VecTypeB& b)
{
- return accu(abs(a - b));
+ return arma::accu(abs(a - b));
}
template<>
template<typename VecTypeA, typename VecTypeB>
-double LMetric<1, false>::Evaluate(const VecTypeA& a, const VecTypeB& b)
+typename VecTypeA::elem_type LMetric<1, false>::Evaluate(
+ const VecTypeA& a,
+ const VecTypeB& b)
{
- return accu(abs(a - b));
+ return arma::accu(abs(a - b));
}
// L2-metric specializations.
template<>
template<typename VecTypeA, typename VecTypeB>
-double LMetric<2, true>::Evaluate(const VecTypeA& a, const VecTypeB& b)
+typename VecTypeA::elem_type LMetric<2, true>::Evaluate(
+ const VecTypeA& a,
+ const VecTypeB& b)
{
- return sqrt(accu(square(a - b)));
+ return sqrt(arma::accu(square(a - b)));
}
template<>
template<typename VecTypeA, typename VecTypeB>
-double LMetric<2, false>::Evaluate(const VecTypeA& a, const VecTypeB& b)
+typename VecTypeA::elem_type LMetric<2, false>::Evaluate(
+ const VecTypeA& a,
+ const VecTypeB& b)
{
- return accu(square(a - b));
+ return accu(arma::square(a - b));
}
// L3-metric specialization (not very likely to be used, but just in case).
template<>
template<typename VecTypeA, typename VecTypeB>
-double LMetric<3, true>::Evaluate(const VecTypeA& a, const VecTypeB& b)
+typename VecTypeA::elem_type LMetric<3, true>::Evaluate(
+ const VecTypeA& a,
+ const VecTypeB& b)
{
- double sum = 0;
+ typename VecTypeA::elem_type sum = 0;
for (size_t i = 0; i < a.n_elem; i++)
- sum += pow(fabs(a[i] - b[i]), 3.0);
+ sum += std::pow(fabs(a[i] - b[i]), 3.0);
- return pow(accu(pow(abs(a - b), 3.0)), 1.0 / 3.0);
+ return std::pow(arma::accu(arma::pow(arma::abs(a - b), 3.0)), 1.0 / 3.0);
}
template<>
template<typename VecTypeA, typename VecTypeB>
-double LMetric<3, false>::Evaluate(const VecTypeA& a, const VecTypeB& b)
+typename VecTypeA::elem_type LMetric<3, false>::Evaluate(
+ const VecTypeA& a,
+ const VecTypeB& b)
{
- return accu(pow(abs(a - b), 3.0));
+ return arma::accu(arma::pow(arma::abs(a - b), 3.0));
}
// L-infinity (Chebyshev distance) specialization
template<>
template<typename VecTypeA, typename VecTypeB>
-double LMetric<INT_MAX, false>::Evaluate(const VecTypeA& a, const VecTypeB& b)
+typename VecTypeA::elem_type LMetric<INT_MAX, false>::Evaluate(
+ const VecTypeA& a,
+ const VecTypeB& b)
{
- return arma::as_scalar(max(abs(a - b)));
+ return arma::as_scalar(arma::max(arma::abs(a - b)));
}
} // namespace metric
More information about the mlpack-git
mailing list