
#ifndef PARTIAL_MSR2_BASE_H_
#define PARTIAL_MSR2_BASE_H_

#include "SimilarityFunction.h"

#include "partialmsr/SynsetClassSet.h"


namespace smartcomparator
{
	namespace simfunctions
	{
		/*
		 * Base class for PartialMSR2 functions, this class in init create:
		 * + Class(rows) x Features(columns) weighted matrix
		 * + Features Mapping from weighted words matrix to class x features weighted matrix
		 */
		class SMART_COMPARATOR_API PartialMSR2Base : public SimilarityFunction
		{
		public:
			typedef std::vector<size_t>	SparseIndices;

			struct Params {
				size_t 			numberOfClasses;
				float			minTreesCutEquality;	// 0-1
				double			featuresPercentToRemove;
				double 			minFeatureWeightForLemma;
				std::string		weightCmpFunction;
			};

		public:
			static Matrices::SuperMatrixPtr	LoadFrequencies( std::string const& pDir, std::string const& pName );

			static void updateFeatures(
				Matrices::CRSMatrixPtr& 	pMtx,
				Matrices::FeatureVectorPtr& pRowsFeatures,
				Matrices::FeatureVectorPtr& pColumnsFeatures,
				bool 						pUpdateTf );

			static void updateColumnFeatures(
				Matrices::CRSMatrixPtr& 	pMtx,
				Matrices::FeatureVectorPtr& pColumnsFeatures,
				bool 						pUpdateTf );

			static boost::shared_ptr< std::vector<double> > countFeaturesMeans( Matrices::SuperMatrixPtr& pMtx );
			static double									findFeaturesEntrophyMargin( Matrices::FeatureVector const& pFeatures, double pPercentToRemove );
			static boost::shared_ptr< std::set<size_t> >	findFeaturesByEntrophy( Matrices::FeatureVector const& pFeatures, double pPercentToRemove );

			static boost::shared_ptr< std::vector<size_t> > buildFeaturesMapping(
				Matrices::SuperMatrixPtr 	pMtxFrom,
				Matrices::SuperMatrixPtr 	pMtxTo );


		protected:
			SimilarityFunctionPtr mSimFunction;

			SynsetClassSetPtrS			mSynsetClasses;
			ClassIdsSetByLemmasMapPtrS	mLemmasMapping;
			Matrices::SuperMatrixPtr 	mSmCxF;
			double						mMaxEntrophy;

			Params mParams;

			//Features from weighted words to features from weighted class
			boost::shared_ptr< std::vector<size_t> > mWWordsToWClass;


		public:
			PartialMSR2Base(
				Matrices::SuperMatrixPtr&		pWeightsMatrix,
				SimilarityFunctionPtr&			pSimilarityFunction,
				SynsetClassSetPtrS&				pSynsetClasses,
				Params&							pParams );

			virtual ~PartialMSR2Base();

			virtual double MinValue() const;

			Matrices::SuperMatrixPtr 	getSuperMatrixCxF();
			SynsetClassSetPtrS			getSynsetClasses();
			ClassIdsSetByLemmasMapPtrS	getLemmasMapping();

			virtual void init( Matrices::SuperMatrixPtr& pFrequencies );

		protected:
			void splitClasses();
			void mapLemmasToClasses();
			void createMatrixCxF( Matrices::SuperMatrixPtr pFreqMatrix );
			void weightMatrixCxF();
		};

		typedef boost::shared_ptr<PartialMSR2Base> PartialMSR2BasePtrS;
	}
}


#endif	/* PARTIAL_MSR2_BASE_H_ */
