KMeansMatlab.cpp 5.8 KB

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