/** * @file EMDDistance.cpp * @brief Earth Movers Distance * @author Erik Rodner * @date 10/24/2007 */ #include #include "vislearning/math/distances/emd.h" #include "vislearning/math/distances/EMDDistance.h" using namespace OBJREC; using namespace std; // refactor-nice.pl: check this substitution // old: using namespace ice; using namespace NICE; // global variable work around :( int global_dimension; float euclidian_distance (double **x, double **y) { double *xx = *x; double *yy = *y; float sum = 0.0; for ( int i = 1 ; i < global_dimension ; i++ ) { double diff = xx[i] - yy[i]; sum += diff*diff; } return sqrt(sum); } EMDDistance::EMDDistance ( int _descriptor_size ) { // add dimension for weights descriptor_size = _descriptor_size + 1; } EMDDistance::~EMDDistance() { } // refactor-nice.pl: check this substitution // old: double EMDDistance::calculate (const Vector & x, const Vector & y) const double EMDDistance::doCalculate (const NICE::Vector & x, const NICE::Vector & y) const { signature_t x_signature; signature_t y_signature; if ( x.size() % descriptor_size != 0 ) { fprintf (stderr, "EMDDistance::distance: wrong dimensions: x.size()=%d, descriptor_size=%d\n", x.size(), descriptor_size ); exit(-1); } x_signature.n = x.size() / descriptor_size; y_signature.n = y.size() / descriptor_size; x_signature.Features = new double * [ x_signature.n ]; x_signature.Weights = new float [ x_signature.n ]; y_signature.Features = new double * [ y_signature.n ]; y_signature.Weights = new float [ y_signature.n ]; double *dataX = const_cast( x.getDataPointer() ); double *dataY = const_cast( y.getDataPointer() ); for ( int i = 0; i < x_signature.n ; i++ ) { x_signature.Features[i] = dataX + i*descriptor_size; x_signature.Weights[i] = (x_signature.Features[i])[0]; } for ( int i = 0; i < y_signature.n ; i++ ) { y_signature.Features[i] = dataY + i*descriptor_size; y_signature.Weights[i] = (y_signature.Features[i])[0]; } global_dimension = descriptor_size; double result = emd ( &x_signature, &y_signature, euclidian_distance, 0, 0 ); delete [] x_signature.Features; delete [] y_signature.Features; delete [] x_signature.Weights; delete [] y_signature.Weights; return result; }