/** * @file KMeansMatlab.cpp * @brief K-Means * @author Erik Rodner * @date 02/04/2008 */ #include #include "vislearning/math/cluster/KMeansMatlab.h" #include using namespace OBJREC; using namespace std; // refactor-nice.pl: check this substitution // old: using namespace ice; using namespace NICE; #undef DEBUG_KMeansMatlab KMeansMatlab::KMeansMatlab( const Config *conf, const std::string & _section ) { this->noClusters = conf->gI( _section, "noClusters", 20); kmeansDir = conf->gS(_section, "source_root", "/home/rodner/osl/labor/cvs/osl/") + "/kernel/"; inputFN = conf->gS(_section, "tmpInput", "/tmp/KMeansMatlab.input" ); outputFN = conf->gS(_section, "tmpOutput", "/tmp/KMeansMatlab.output" ); matlabExec = conf->gS(_section, "matlab_exec", "matlab"); matlabArgs = conf->gS(_section, "matlab_args", "-nosplash -nojvm -nodesktop"); } KMeansMatlab::~KMeansMatlab() { if ( matlabPipe != NULL ) pclose (matlabPipe); } int KMeansMatlab::compute_prototypes ( const VVector & features, VVector & prototypes, std::vector & weights, const std::vector & assignment ) { int j = 0; // fprintf (stderr, "KMeansMatlab::compute_prototypes: init noClusters=%d\n", noClusters); for ( int k = 0 ; k < noClusters ; k++ ) { prototypes[k].set(0); weights[k] = 0; } // fprintf (stderr, "KMeansMatlab::compute_prototypes: compute means\n"); for ( VVector::const_iterator i = features.begin(); i != features.end(); i++, j++ ) { int k = assignment[j]; // refactor-nice.pl: check this substitution // old: Vector & p = prototypes[k]; NICE::Vector & p = prototypes[k]; // refactor-nice.pl: check this substitution // old: const Vector & x = *i; const NICE::Vector & x = *i; #ifdef DEBUG_KMeansMatlab // refactor-nice.pl: check this substitution // old: fprintf (stderr, "KMeansMatlab::compute_prototypes: vector %d has assignment %d\n", j, k ); fprintf (stderr, "KMeansMatlab::compute_prototypes: std::vector %d has assignment %d\n", j, k ); #endif p += x; #ifdef DEBUG_KMeansMatlab cerr << "vector was : " << x << endl; cerr << "prototype for this class is now : " << p << endl; #endif weights[k]++; } // fprintf (stderr, "KMeansMatlab::compute_prototypes: scaling\n"); for ( int k = 0 ; k < noClusters ; k++ ) { // refactor-nice.pl: check this substitution // old: Vector & p = prototypes[k]; NICE::Vector & p = prototypes[k]; #ifdef DEBUG_KMeansMatlab cerr << "prototype for this class before scaling : " << p << endl; #endif if ( weights[k] <= 0 ) { return -1; } p *= ( 1.0 / weights[k] ); weights[k] = weights[k] / features.size(); #ifdef DEBUG_KMeansMatlab cerr << "prototype for this class after scaling with " << weights[k] << " : " << p << endl; #endif } return 0; } void KMeansMatlab::cluster ( const VVector & features, VVector & prototypes, std::vector & weights, std::vector & assignment ) { prototypes.clear(); weights.clear(); assignment.clear (); weights.resize ( noClusters, 0 ); assignment.resize ( features.size(), 0 ); // ----------- routine argument ------------- // refactor-nice.pl: check this substitution // old: string routineCMD = "W = KMeansInterface('" + inputFN + "', '" + outputFN + "');\n"; std::string routineCMD = "W = KMeansInterface('" + inputFN + "', '" + outputFN + "');\n"; int dimension; if ( (int)features.size() >= noClusters ) dimension = features[0].size(); else { fprintf (stderr, "FATAL ERROR: Not enough feature vectors provided for KMeansMatlab\n"); exit(-1); } FILE *fi = fopen ( inputFN.c_str(), "w" ); if ( fi == NULL ) { fprintf (stderr, "KMeansMatlab: FATAL ERROR cannot write features!\n"); exit(-1); } fwrite (&noClusters, sizeof(int), 1, fi ); int n = features.size(); fwrite (&n, sizeof(int), 1, fi ); int d = features[0].size(); fwrite (&d, sizeof(int), 1, fi ); for ( size_t i = 0 ; i < features.size() ; i++ ) for ( size_t k = 0 ; k < features[i].size() ; k++ ) // refactor-nice.pl: check this substitution fwrite ( &(features[i][k]), sizeof(double), 1, fi); fclose(fi); // refactor-nice.pl: check this substitution // old: string chdirCMD = "cd '" + kmeansDir + "'\n"; std::string chdirCMD = "cd '" + kmeansDir + "'\n"; // refactor-nice.pl: check this substitution // old: string execCMD = matlabExec + " " + matlabArgs; std::string execCMD = matlabExec + " " + matlabArgs; matlabPipe = popen ( execCMD.c_str(), "w"); if ( matlabPipe == NULL ) { fprintf (stderr, "KMeansMatlab: FATAL ERROR cannot execute matlab!\n"); exit(-1); } fputs (chdirCMD.c_str(), matlabPipe); fputs (routineCMD.c_str(), matlabPipe); pclose ( matlabPipe ); FILE *g = fopen ( outputFN.c_str(), "r" ); if ( g == NULL ) { fprintf (stderr, "KMeansMatlab::teach: FATAL ERROR cannot read matlab result!\n"); exit(-1); } for ( size_t j = 0 ; j < features.size() ; j++ ) { int val = 0; if ( fread ( &val, sizeof(int), 1, g) <= 0 ) { // refactor-nice.pl: check this substitution // old: fprintf (stderr, "KMeansMatlab::cluster: FATAL ERROR reading vector file\n"); fprintf (stderr, "KMeansMatlab::cluster: FATAL ERROR reading std::vector file\n"); exit(-1); } assignment[j] = val-1; } fclose(g); for ( int k = 0 ; k < noClusters ; k++ ) { // fprintf (stderr, "KMeansMatlab::cluster prototype init constructor\n"); prototypes.push_back( Vector( dimension ) ); prototypes[k].set(0); } if ( compute_prototypes ( features, prototypes, weights, assignment ) < 0 ) { fprintf (stderr, "KMeansMatlab::cluster failure !!\n"); exit(-1); } }