EMDDistance.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /**
  2. * @file EMDDistance.cpp
  3. * @brief Earth Movers Distance
  4. * @author Erik Rodner
  5. * @date 10/24/2007
  6. */
  7. #include <iostream>
  8. #include "vislearning/math/distances/emd.h"
  9. #include "vislearning/math/distances/EMDDistance.h"
  10. using namespace OBJREC;
  11. using namespace std;
  12. // refactor-nice.pl: check this substitution
  13. // old: using namespace ice;
  14. using namespace NICE;
  15. // global variable work around :(
  16. int global_dimension;
  17. float euclidian_distance (double **x, double **y)
  18. {
  19. double *xx = *x;
  20. double *yy = *y;
  21. float sum = 0.0;
  22. for ( int i = 1 ; i < global_dimension ; i++ )
  23. {
  24. double diff = xx[i] - yy[i];
  25. sum += diff*diff;
  26. }
  27. return sqrt(sum);
  28. }
  29. EMDDistance::EMDDistance ( int _descriptor_size )
  30. {
  31. // add dimension for weights
  32. descriptor_size = _descriptor_size + 1;
  33. }
  34. EMDDistance::~EMDDistance()
  35. {
  36. }
  37. // refactor-nice.pl: check this substitution
  38. // old: double EMDDistance::calculate (const Vector & x, const Vector & y) const
  39. double EMDDistance::doCalculate (const NICE::Vector & x, const NICE::Vector & y) const
  40. {
  41. signature_t x_signature;
  42. signature_t y_signature;
  43. if ( x.size() % descriptor_size != 0 )
  44. {
  45. fprintf (stderr, "EMDDistance::distance: wrong dimensions: x.size()=%d, descriptor_size=%d\n",
  46. x.size(), descriptor_size );
  47. exit(-1);
  48. }
  49. x_signature.n = x.size() / descriptor_size;
  50. y_signature.n = y.size() / descriptor_size;
  51. x_signature.Features = new double * [ x_signature.n ];
  52. x_signature.Weights = new float [ x_signature.n ];
  53. y_signature.Features = new double * [ y_signature.n ];
  54. y_signature.Weights = new float [ y_signature.n ];
  55. double *dataX = const_cast<double *>( x.getDataPointer() );
  56. double *dataY = const_cast<double *>( y.getDataPointer() );
  57. for ( int i = 0; i < x_signature.n ; i++ )
  58. {
  59. x_signature.Features[i] = dataX + i*descriptor_size;
  60. x_signature.Weights[i] = (x_signature.Features[i])[0];
  61. }
  62. for ( int i = 0; i < y_signature.n ; i++ )
  63. {
  64. y_signature.Features[i] = dataY + i*descriptor_size;
  65. y_signature.Weights[i] = (y_signature.Features[i])[0];
  66. }
  67. global_dimension = descriptor_size;
  68. double result = emd ( &x_signature, &y_signature,
  69. euclidian_distance, 0, 0 );
  70. delete [] x_signature.Features;
  71. delete [] y_signature.Features;
  72. delete [] x_signature.Weights;
  73. delete [] y_signature.Weights;
  74. return result;
  75. }