[mlpack] KMeans and non-static metric

Felix Widmaier felix.widmaier at student.uni-tuebingen.de
Thu Oct 30 07:12:49 EDT 2014


Hi everybody,

First of all, in case that it is relevant: Since I am stuck with Ubuntu
12.04 which has only boost 1.48 in its repositories, I have to use
mlpack version 1.0.8 instead of the current 1.0.10.

I am currently trying to implement my own metric class and use that with
kmeans.
It worked with a simple static metric class. However the metric I want
to use is stateful so I made the Evaluate() method of the metric class
non-static. Now I get compiler errors, as KMeans::Cluster() is const and
usage of non-const, non-static Evaluate() within Cluster() discards
qualifiers.

MahalanobisDistance is also not working for the same reason (at least
the code snippet from
http://www.mlpack.org/doxygen.php?doc=kmtutorial.html#kmeans_metric_kmtut does
not work for me)

Do I miss something here or are stateful metrics for kmeans indeed not
possible due to the const?

Best regards,
Felix


PS: here is my little testing program to illustrate the problem:

====================================================================
#include <mlpack/core.hpp>
#include <mlpack/methods/kmeans/kmeans.hpp>

using namespace mlpack::kmeans;

namespace mlpack {
namespace metric {

    class MyMetric
    {
     public:
      MyMetric() { }

      // does only work if this method is static or const.
      template<typename VecType1, typename VecType2>
      double Evaluate(const VecType1& a, const VecType2& b)
      {
          return std::abs(a[0] - b[0]);
      }
    };

}
}


int main()
{
    // Some data for testing.
    arma::mat data;
    data << 0 << 1 << 2 << 3 << 4 << 5 << 10 << 11 << 13 << 13 << 100 <<
140 << arma::endr
         << 0 << 1 << 1 << 4 << 2 << 3 << 13 << 10 << 17 << 12 << 90 <<
121 << arma::endr
         << 0 << 1 << 4 << 2 << 6 << 6 << 19 << 18 << 13 << 17 << 94 <<
128 << arma::endr;

    // The number of clusters we are getting.
    size_t clusters = 3;

    // The assignments will be stored in this vector.
    arma::Col<size_t> assignments;

    mlpack::metric::MyMetric dist;
    KMeans<mlpack::metric::MyMetric> k(1000, 1.0, dist);

    k.Cluster(data, clusters, assignments);

    data.print("Data:");
    assignments.t().print("cluster:");

    return 0;
}
====================================================================

Resulting compiler error:
/usr/local/include/mlpack/methods/kmeans/kmeans_impl.hpp:587: error:
passing 'const mlpack::metric::MyMetric' as 'this' argument of 'double
mlpack::metric::MyMetric::Evaluate(const VecType1&, const VecType2&)
[with VecType1 = arma::subview_col<double>, VecType2 =
arma::subview_col<double>]' discards qualifiers [-fpermissive]


More information about the mlpack mailing list