KMeansMatlab.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /**
  2. * @file KMeansMatlab.cpp
  3. * @brief K-Means
  4. * @author Erik Rodner
  5. * @date 02/04/2008
  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/cluster/KMeansMatlab.h"
  14. #include <set>
  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. #undef DEBUG_KMeansMatlab
  21. KMeansMatlab::KMeansMatlab( const Config *conf,
  22. int _noClasses ) : noClasses(_noClasses)
  23. {
  24. kmeansDir = conf->gS("matlab", "source_root", "/home/rodner/osl/labor/cvs/osl/") + "/kernel/";
  25. inputFN = conf->gS("KMeansMatlab", "tmpInput", "/tmp/KMeansMatlab.input" );
  26. outputFN = conf->gS("KMeansMatlab", "tmpoutput", "/tmp/KMeansMatlab.output" );
  27. matlabExec = conf->gS("matlab", "matlab_exec", "matlab");
  28. matlabArgs = conf->gS("matlab", "matlab_args", "-nosplash -nojvm -nodesktop");
  29. }
  30. KMeansMatlab::~KMeansMatlab()
  31. {
  32. if ( matlabPipe != NULL )
  33. pclose (matlabPipe);
  34. }
  35. int KMeansMatlab::compute_prototypes ( const VVector & features,
  36. VVector & prototypes,
  37. std::vector<double> & weights,
  38. const std::vector<int> & assignment )
  39. {
  40. int j = 0;
  41. // fprintf (stderr, "KMeansMatlab::compute_prototypes: init noClasses=%d\n", noClasses);
  42. for ( int k = 0 ; k < noClasses ; k++ )
  43. {
  44. prototypes[k].set(0);
  45. weights[k] = 0;
  46. }
  47. // fprintf (stderr, "KMeansMatlab::compute_prototypes: compute means\n");
  48. for ( VVector::const_iterator i = features.begin();
  49. i != features.end();
  50. i++, j++ )
  51. {
  52. int k = assignment[j];
  53. // refactor-nice.pl: check this substitution
  54. // old: Vector & p = prototypes[k];
  55. NICE::Vector & p = prototypes[k];
  56. // refactor-nice.pl: check this substitution
  57. // old: const Vector & x = *i;
  58. const NICE::Vector & x = *i;
  59. #ifdef DEBUG_KMeansMatlab
  60. // refactor-nice.pl: check this substitution
  61. // old: fprintf (stderr, "KMeansMatlab::compute_prototypes: vector %d has assignment %d\n", j, k );
  62. fprintf (stderr, "KMeansMatlab::compute_prototypes: std::vector %d has assignment %d\n", j, k );
  63. #endif
  64. p += x;
  65. #ifdef DEBUG_KMeansMatlab
  66. cerr << "vector was : " << x << endl;
  67. cerr << "prototype for this class is now : " << p << endl;
  68. #endif
  69. weights[k]++;
  70. }
  71. // fprintf (stderr, "KMeansMatlab::compute_prototypes: scaling\n");
  72. for ( int k = 0 ; k < noClasses ; k++ )
  73. {
  74. // refactor-nice.pl: check this substitution
  75. // old: Vector & p = prototypes[k];
  76. NICE::Vector & p = prototypes[k];
  77. #ifdef DEBUG_KMeansMatlab
  78. cerr << "prototype for this class before scaling : " << p << endl;
  79. #endif
  80. if ( weights[k] <= 0 ) {
  81. return -1;
  82. }
  83. p *= ( 1.0 / weights[k] );
  84. weights[k] = weights[k] / features.size();
  85. #ifdef DEBUG_KMeansMatlab
  86. cerr << "prototype for this class after scaling with " << weights[k] << " : " << p << endl;
  87. #endif
  88. }
  89. return 0;
  90. }
  91. void KMeansMatlab::cluster ( const VVector & features,
  92. VVector & prototypes,
  93. std::vector<double> & weights,
  94. std::vector<int> & assignment )
  95. {
  96. prototypes.clear();
  97. weights.clear();
  98. assignment.clear ();
  99. weights.resize ( noClasses, 0 );
  100. assignment.resize ( features.size(), 0 );
  101. // ----------- routine argument -------------
  102. // refactor-nice.pl: check this substitution
  103. // old: string routineCMD = "W = KMeansInterface('" + inputFN + "', '" + outputFN + "');\n";
  104. std::string routineCMD = "W = KMeansInterface('" + inputFN + "', '" + outputFN + "');\n";
  105. int dimension;
  106. if ( (int)features.size() >= noClasses )
  107. dimension = features[0].size();
  108. else {
  109. fprintf (stderr, "FATAL ERROR: Not enough feature vectors provided for KMeansMatlab\n");
  110. exit(-1);
  111. }
  112. FILE *fi = fopen ( inputFN.c_str(), "w" );
  113. if ( fi == NULL )
  114. {
  115. fprintf (stderr, "KMeansMatlab: FATAL ERROR cannot write features!\n");
  116. exit(-1);
  117. }
  118. fwrite (&noClasses, sizeof(int), 1, fi );
  119. int n = features.size();
  120. fwrite (&n, sizeof(int), 1, fi );
  121. int d = features[0].size();
  122. fwrite (&d, sizeof(int), 1, fi );
  123. for ( size_t i = 0 ; i < features.size() ; i++ )
  124. for ( size_t k = 0 ; k < features[i].size() ; k++ )
  125. // refactor-nice.pl: check this substitution
  126. fwrite ( &(features[i][k]), sizeof(double), 1, fi);
  127. fclose(fi);
  128. // refactor-nice.pl: check this substitution
  129. // old: string chdirCMD = "cd '" + kmeansDir + "'\n";
  130. std::string chdirCMD = "cd '" + kmeansDir + "'\n";
  131. // refactor-nice.pl: check this substitution
  132. // old: string execCMD = matlabExec + " " + matlabArgs;
  133. std::string execCMD = matlabExec + " " + matlabArgs;
  134. matlabPipe = popen ( execCMD.c_str(), "w");
  135. if ( matlabPipe == NULL )
  136. {
  137. fprintf (stderr, "KMeansMatlab: FATAL ERROR cannot execute matlab!\n");
  138. exit(-1);
  139. }
  140. fputs (chdirCMD.c_str(), matlabPipe);
  141. fputs (routineCMD.c_str(), matlabPipe);
  142. pclose ( matlabPipe );
  143. FILE *g = fopen ( outputFN.c_str(), "r" );
  144. if ( g == NULL )
  145. {
  146. fprintf (stderr, "KMeansMatlab::teach: FATAL ERROR cannot read matlab result!\n");
  147. exit(-1);
  148. }
  149. for ( size_t j = 0 ; j < features.size() ; j++ )
  150. {
  151. int val = 0;
  152. if ( fread ( &val, sizeof(int), 1, g) <= 0 )
  153. {
  154. // refactor-nice.pl: check this substitution
  155. // old: fprintf (stderr, "KMeansMatlab::cluster: FATAL ERROR reading vector file\n");
  156. fprintf (stderr, "KMeansMatlab::cluster: FATAL ERROR reading std::vector file\n");
  157. exit(-1);
  158. }
  159. assignment[j] = val-1;
  160. }
  161. fclose(g);
  162. for ( int k = 0 ; k < noClasses ; k++ )
  163. {
  164. // fprintf (stderr, "KMeansMatlab::cluster prototype init constructor\n");
  165. prototypes.push_back( Vector( dimension ) );
  166. prototypes[k].set(0);
  167. }
  168. if ( compute_prototypes ( features, prototypes, weights, assignment ) < 0 )
  169. {
  170. fprintf (stderr, "KMeansMatlab::cluster failure !!\n");
  171. exit(-1);
  172. }
  173. }