/** 
* @file GPMSCLooEstimates.h
* @author Erik Rodner
* @date 03/07/2010

*/
#ifndef _NICE_OBJREC_GPMSCLOOESTIMATESINCLUDE
#define _NICE_OBJREC_GPMSCLOOESTIMATESINCLUDE

#include "core/vector/VectorT.h"
#include "vislearning/math/kernels/KernelData.h"
#include "vislearning/regression/gpregression/modelselcrit/GPModelSelectionCriterion.h"

#include "core/optimization/gradientBased/OptimizationProblemFirst.h"

namespace OBJREC {
  
/** @class GPMSCLooLikelihoodRegression
 * Estimates the LOO preditictive log probability
 * @author Erik Rodner
 */
class GPMSCLooLikelihoodRegression : public GPModelSelectionCriterion
{
	protected:
		bool weightedLooProb;
		NICE::Vector selection;

    public:
		GPMSCLooLikelihoodRegression ( bool weightedLooProb = false );

		GPMSCLooLikelihoodRegression ( bool weightedLooProb, const NICE::Vector & selection );
		
		virtual ~GPMSCLooLikelihoodRegression () {};

		virtual double computeObjective ( KernelData *kernelData, const NICE::Vector & labels ) const;
		
		virtual double computeObjective ( const NICE::Vector & invKernelMatrixDiag, const NICE::Vector & alpha, 
			const NICE::Vector & labels ) const;
};

/** @class GPMSCLooLikelihoodClassification
 * Estimates the LOO preditictive log probability (Regression with
 * additional squash function)
 * @author Erik Rodner
 */
class GPMSCLooLikelihoodClassification : public GPMSCLooLikelihoodRegression
{
	protected:

    public:
		GPMSCLooLikelihoodClassification ();

		GPMSCLooLikelihoodClassification ( const NICE::Vector & selection );
		
		virtual ~GPMSCLooLikelihoodClassification () {};

		virtual double computeObjective ( const NICE::Vector & invKernelMatrixDiag, const NICE::Vector & alpha, 
			const NICE::Vector & labels ) const;
};

/** @class GPMSCLooLikelihoodClassificationFixed
 * Estimates the LOO preditictive log probability (Regression with
 * additional fixed squash function)
 * @author Erik Rodner
 */
class GPMSCLooLikelihoodClassificationFixed : public GPMSCLooLikelihoodRegression
{
	protected:

    public:
		GPMSCLooLikelihoodClassificationFixed ();

		GPMSCLooLikelihoodClassificationFixed ( const NICE::Vector & selection );
		
		virtual ~GPMSCLooLikelihoodClassificationFixed () {};

		virtual double computeObjective ( const NICE::Vector & invKernelMatrixDiag, const NICE::Vector & alpha, 
			const NICE::Vector & labels ) const;
};

/** @class GPMSCLooLabor
 * @author Erik Rodner
 */
class GPMSCLooLabor : public GPMSCLooLikelihoodRegression
{
	protected:

    public:
		GPMSCLooLabor ();

		GPMSCLooLabor ( const NICE::Vector & selection );
		
		virtual ~GPMSCLooLabor () {};

		virtual double computeObjective ( const NICE::Vector & invKernelMatrixDiag, const NICE::Vector & alpha, 
			const NICE::Vector & labels ) const;
};

/** @class GPMSCLooLikelihoodClassificationOptProb
 * Optimizaton problem for 
 * Estimates the LOO preditictive log probability (Regression with
 * additional squash function)
 * as presented in Rasmussen, Williams (page 148)
 * @author Erik Rodner
 */
class GPMSCLooLikelihoodClassificationOptProb : public NICE::OptimizationProblemFirst
{
	protected:
		NICE::Vector labels;
		NICE::Vector selection;
		NICE::Vector looMu;
		NICE::Vector looVariance;
		bool verbose;

    public:
		
		GPMSCLooLikelihoodClassificationOptProb ( const NICE::Vector & labels,
			const NICE::Vector & selection, const NICE::Vector & looMu, const NICE::Vector & looVariance,
			bool verbose = false );
		
		double computeObjective();

		void computeGradient( NICE::Vector & newGradient );

};

/** @class GPMSCLooVarious
 * Estimates various measures using the LOO estimates
 * @author Erik Rodner
 */
class GPMSCLooVarious : public GPMSCLooLikelihoodRegression
{
	public:
		enum {
			P_RECOGNITIONRATE = 0,
			P_AUC,
			P_AVGPREC
		};

	protected:
		
		int type;

    public:
		GPMSCLooVarious ( int type );

		GPMSCLooVarious ( int type, const NICE::Vector & selection );
		
		virtual ~GPMSCLooVarious () {};

		virtual double computeObjective ( const NICE::Vector & invKernelMatrixDiag, const NICE::Vector & alpha, 
			const NICE::Vector & labels ) const;
};

/** @class GPMSCConditionalLikelihood
 * Estimates the conditional marginal likelihood
 * @author Erik Rodner
 */
class GPMSCConditionalLikelihood : public GPModelSelectionCriterion
{
	protected:
		NICE::Vector selection;

    public:
		GPMSCConditionalLikelihood ( const NICE::Vector & selection );
		
		virtual ~GPMSCConditionalLikelihood () {};

		virtual double computeObjective ( KernelData *kernelData, const NICE::Vector & labels ) const;
};

}

#endif
