/** 
* @file VCSVMLight.h
* @brief Interface to SVMLight from T. Joachims
* @author Erik Rodner
* @date 10/25/2007

*/
#ifndef VCSVMLightINCLUDE
#define VCSVMLightINCLUDE

#ifdef NICE_USELIB_SVMLIGHT

#include <vislearning/nice.h>

extern "C" {
#include <svm_common.h>
#include <svm_learn.h>
}

#include "vislearning/cbaselib/LabeledSet.h"
#include "vislearning/classifier/classifierbase/VecClassifier.h"
#include "VCLogisticRegression.h"


namespace OBJREC {

/** Interface to SVMLight from T. Joachims */
class VCSVMLight : public VecClassifier
{

    protected:
		NICE::Vector max;
		NICE::Vector min;

		int normalization_type;

		enum {
			SVM_NORMALIZATION_EUCLIDEAN = 0,
			SVM_NORMALIZATION_01,
			SVM_NORMALIZATION_NONE
		};

		int kernel_type;

		/** @brief kernel parameters
			Use toyExample to see the effects of this parameter
		*/
		double poly_degree;
		double rbf_gamma;
		double sigmoidpoly_scale;
		double sigmoidpoly_bias;

		/** regularization parameter of SVM */
		double svm_c;
		
		bool use_crossvalidation;
		bool optimize_parameters;

		/** cross validation settings */
		double rbf_gamma_min;
		double rbf_gamma_max;
		double rbf_gamma_step;
		double svm_c_min;
		double svm_c_max;
		double svm_c_step;

		/** SVMLight model */
		MODEL *finalModel;
		VCLogisticRegression *logreg;

		void readDocuments(
				DOC ***docs, 
				double **label, 
				long int *totwords, 
				long int *totdoc, 
				const LabeledSetVector & train );

		void svmLightTraining ( 
			const LabeledSetVector & trainSet );

		MODEL *singleTraining ( DOC **docs, 
			double *target, long int totwords, long int totdoc, 
			MODEL *model, KERNEL_PARM *kernel_parm,
			LEARN_PARM *learn_parm );

		void initParameters ( 
			LEARN_PARM *learn_parm,
			KERNEL_PARM *kernel_parm );

		void initMainParameters ( LEARN_PARM *learn_parm,
			KERNEL_PARM *kernel_parm );

		void estimateMaxMin ( const LabeledSetVector & train );

		void normalizeVector ( int normalization_type, NICE::Vector & x ) const;

		double getSVMScore ( const NICE::Vector & x ) const;

		MODEL *optimizeParameters ( DOC **docs, 
			double *target, long int totwords, long int totdoc, 
			MODEL *model, KERNEL_PARM *kernel_parm,
			LEARN_PARM *learn_parm );

    public:
  
		/** using a config file to read some settings */
		VCSVMLight( const NICE::Config *conf, const std::string & section = "VCSVMLight" );

		/** simple copy constructor */
		VCSVMLight ( const VCSVMLight & src );
	  
		/** simple destructor */
		virtual ~VCSVMLight();
		 
		/** classify using simple vector */
		ClassificationResult classify ( const NICE::Vector & x ) const;

		/** classify using a simple vector */
		void teach ( const LabeledSetVector & teachSet );
		
		void finishTeaching();

		/** clone this object */
		virtual VCSVMLight *clone(void) const;

		void clear ();

		void read (const std::string& s, int format = 0);
		void save (const std::string& s, int format = 0) const;

		void store ( std::ostream & os, int format = 0 ) const;
		void restore ( std::istream & is, int format = 0 );
};


} // namespace

#endif
#endif