EMDDistance.cpp 2.4 KB

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