123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- /**
- * @file KMeansMatlab.cpp
- * @brief K-Means
- * @author Erik Rodner
- * @date 02/04/2008
- */
- #include <iostream>
- #include "vislearning/math/cluster/KMeansMatlab.h"
- #include <set>
- using namespace OBJREC;
- using namespace std;
- // refactor-nice.pl: check this substitution
- // old: using namespace ice;
- using namespace NICE;
- #undef DEBUG_KMeansMatlab
- ///////////////////// ///////////////////// /////////////////////
- // CONSTRUCTORS / DESTRUCTORS
- ///////////////////// ///////////////////// /////////////////////
- KMeansMatlab::KMeansMatlab() : ClusterAlgorithm()
- {
- this->noClusters = 20;
-
- this->kmeansDir = "/home/rodner/osl/labor/cvs/osl/kernel/";
- this->inputFN = "/tmp/KMeansMatlab.input";
- this->outputFN = "/tmp/KMeansMatlab.output" ;
- this->matlabExec = "matlab";
- this->matlabArgs = "-nosplash -nojvm -nodesktop";
- }
- KMeansMatlab::KMeansMatlab( const NICE::Config * _conf, const std::string & _confSection )
- {
- this->initFromConfig ( _conf, _confSection );
- }
- KMeansMatlab::~KMeansMatlab()
- {
- if ( matlabPipe != NULL )
- pclose (matlabPipe);
- }
- void KMeansMatlab::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
- {
- this->noClusters = _conf->gI( _confSection, "noClusters", 20);
-
- this->kmeansDir = _conf->gS(_confSection, "source_root", "/home/rodner/osl/labor/cvs/osl/") + "/kernel/";
- this->inputFN = _conf->gS(_confSection, "tmpInput", "/tmp/KMeansMatlab.input" );
- this->outputFN = _conf->gS(_confSection, "tmpOutput", "/tmp/KMeansMatlab.output" );
- this->matlabExec = _conf->gS(_confSection, "matlab_exec", "matlab");
- this->matlabArgs = _conf->gS(_confSection, "matlab_args", "-nosplash -nojvm -nodesktop");
- }
- ///////////////////// ///////////////////// /////////////////////
- // CLUSTERING STUFF
- ///////////////////// ///////////////////// //////////////////
- int KMeansMatlab::compute_prototypes ( const VVector & features,
- VVector & prototypes,
- std::vector<double> & weights,
- const std::vector<int> & 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<double> & weights,
- std::vector<int> & 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);
- }
- }
- ///////////////////// INTERFACE PERSISTENT /////////////////////
- // interface specific methods for store and restore
- ///////////////////// INTERFACE PERSISTENT /////////////////////
- void KMeansMatlab::restore ( std::istream & is, int format )
- {
- //delete everything we knew so far...
- this->clear();
-
-
- if ( is.good() )
- {
-
- std::string tmp;
- is >> tmp; //class name
-
- if ( ! this->isStartTag( tmp, "KMeansMatlab" ) )
- {
- std::cerr << " WARNING - attempt to restore KMeansMatlab, but start flag " << tmp << " does not match! Aborting... " << std::endl;
- throw;
- }
-
- bool b_endOfBlock ( false ) ;
-
- while ( !b_endOfBlock )
- {
- is >> tmp; // start of block
-
- if ( this->isEndTag( tmp, "KMeansMatlab" ) )
- {
- b_endOfBlock = true;
- continue;
- }
-
- tmp = this->removeStartTag ( tmp );
-
- if ( tmp.compare("noClusters") == 0 )
- {
- is >> this->noClusters;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("kmeansDir") == 0 )
- {
- is >> this->kmeansDir;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("inputFN") == 0 )
- {
- is >> this->inputFN;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("outputFN") == 0 )
- {
- is >> this->outputFN;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("matlabExec") == 0 )
- {
- is >> this->matlabExec;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("matlabArgs") == 0 )
- {
- is >> this->matlabArgs;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else
- {
- std::cerr << "WARNING -- unexpected KMeansMatlab object -- " << tmp << " -- for restoration... aborting" << std::endl;
- throw;
- }
- }
- }
- else
- {
- std::cerr << "KMeansMatlab::restore -- InStream not initialized - restoring not possible!" << std::endl;
- throw;
- }
- }
- void KMeansMatlab::store ( std::ostream & os, int format ) const
- {
- if (os.good())
- {
- // show starting point
- os << this->createStartTag( "KMeansMatlab" ) << std::endl;
-
- os << this->createStartTag( "noClusters" ) << std::endl;
- os << this->noClusters << std::endl;
- os << this->createEndTag( "noClusters" ) << std::endl;
- os << this->createStartTag( "kmeansDir" ) << std::endl;
- os << this->kmeansDir << std::endl;
- os << this->createEndTag( "kmeansDir" ) << std::endl;
-
- os << this->createStartTag( "inputFN" ) << std::endl;
- os << this->inputFN << std::endl;
- os << this->createEndTag( "inputFN" ) << std::endl;
- os << this->createStartTag( "outputFN" ) << std::endl;
- os << this->outputFN << std::endl;
- os << this->createEndTag( "outputFN" ) << std::endl;
- os << this->createStartTag( "matlabExec" ) << std::endl;
- os << this->matlabExec << std::endl;
- os << this->createEndTag( "matlabExec" ) << std::endl;
-
- os << this->createStartTag( "matlabArgs" ) << std::endl;
- os << this->matlabArgs << std::endl;
- os << this->createEndTag( "matlabArgs" ) << std::endl;
-
- // done
- os << this->createEndTag( "KMeansMatlab" ) << std::endl;
- }
- else
- {
- std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
- }
- }
- void KMeansMatlab::clear ()
- {
- }
|