/** 
* @file KCGPRegression.cpp
* @brief Gaussian Process Regression for Classification
* @author Erik Rodner
* @date 12/03/2009

*/
#include <iostream>
#include <typeinfo>

#include "core/vector/Algorithms.h"

#include "vislearning/regression/gpregression/RegGaussianProcess.h"
#include "KCGPRegression.h"


using namespace std;
using namespace NICE;
using namespace OBJREC;


KCGPRegression::KCGPRegression( const Config *conf, Kernel *kernel, const string & section ) 
	: KernelClassifier ( conf, kernel )
{
	regressionAlgorithm = new RegGaussianProcess ( conf, kernel, section );

}

KCGPRegression::KCGPRegression( const KCGPRegression & src ) : KernelClassifier ( src )
{
	regressionAlgorithm = src.regressionAlgorithm->clone();
	y = src.y;
}

KCGPRegression::~KCGPRegression()
{
	delete regressionAlgorithm;
}


void KCGPRegression::teach ( KernelData *kernelData, const NICE::Vector & y )
{
	if ( y.size() <= 0 ) {
		fthrow(Exception, "Number of training vectors is zero!");
	}
	
	this->y.resize ( y.size() );
	this->y = y;
	this->y = 2*this->y;
	this->y += -1.0;

	if ( (this->y.Min() != -1) || (this->y.Max() != 1) ) {
		fthrow(Exception, "This classifier is suitable only for binary classification problems" );
	}

	regressionAlgorithm->teach ( kernelData, this->y );
}

ClassificationResult KCGPRegression::classifyKernel ( const NICE::Vector & kernelVector, double kernelSelf ) const
{
	double yEstimate = regressionAlgorithm->predictKernel ( kernelVector, kernelSelf );

	FullVector scores ( 2 );
	scores[0] = 0.0;
	scores[1] = yEstimate;
	ClassificationResult r ( (yEstimate < 0) ? 0 : 1, scores );

	return r;
}

KCGPRegression *KCGPRegression::clone() const
{
	return new KCGPRegression ( *this );
}