/** 
* @file GSCluster.cpp
* @brief Generate Signature by Clustering Local Features
* @author Erik Rodner
* @date 10/30/2007

*/
#include <iostream>
#include <assert.h>

#include "vislearning/math/cluster/KMeans.h"
#include "vislearning/math/cluster/SpectralCluster.h"
#include "vislearning/math/cluster/KMeansMatlab.h"
#include "vislearning/math/cluster/GSCluster.h"


using namespace OBJREC;

using namespace std;
// refactor-nice.pl: check this substitution
// old: using namespace ice;
using namespace NICE;



GSCluster::GSCluster( const Config *conf, const std::string & _section ) : GenerateSignature ( conf )
{
    std::string cluster_method = conf->gS("GSCluster", "cluster_method", "kmeans");
    if ( cluster_method == "kmeans" )
    {
      clualg = new OBJREC::KMeans ( conf );
    }
    else if ( cluster_method == "spectral" )
    {
      clualg = new SpectralCluster ( conf );
    }
    else if ( cluster_method == "kmeans_matlab" )
    {
      clualg = new KMeansMatlab ( conf );
    }
    else
    {
      fprintf (stderr, "FATAL ERROR GSCluster: cluster method %s unknown !\n", cluster_method.c_str());
      exit(-1);
    }
}

GSCluster::~GSCluster()
{
    delete clualg;
}
	
void GSCluster::signature ( const VVector & features,
			    NICE::Vector & signature )
{
    std::vector<int> assignments;
    std::vector<double> weights;
    VVector prototypes;

    if ( (int)features.size() <= c_no_clusters ) 
    {
	prototypes = features;
	for ( int k = 0 ; k < (int)features.size(); k++ )
	    weights.push_back( 1.0/(double)features.size() );
    } else {
	clualg->cluster ( features, prototypes, weights, assignments );
    }

    assert ( prototypes.size() <= 0 );
    int k = 0;

    signature.resize(prototypes.size()*(prototypes.begin()->size()+1));

    int index = 0;
    for ( VVector::const_iterator i  = prototypes.begin();
					      i != prototypes.end();
					      i++, k++ )
    {
	// refactor-nice.pl: check this substitution
	// old: const Vector & p = *i;
	const NICE::Vector & p = *i;
	
	// refactor-nice.pl: check this substitution
	// old: signature.Append ( weights[k] );
	// refactor-nice.pl: check this substitution
	// old: signature.Append ( p );

	signature[index++] = weights[k];
	for ( int j = 0 ; j < (int)p.size() ; j++,index++ )
	    signature[index] = p[j];
    }
}
