/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#pragma once
#include "../comparator_stdheaders.h"
#include "RWFBase.h"

namespace smartcomparator
{
	namespace weights
	{
		/** 
		 * Rank weight based on zscore. This is global version of zscore, 
		 * i.e., probability of base event is counted as TF/W, where TF is 
		 * global term frequency for a word and W is number of token in corpus.
		 */
		class SMART_COMPARATOR_API RWFZScore : public RWFBase
		{
			public:
				/**
				 * \param threshold - minimum value for z-score
				 */
				RWFZScore(Matrices::SuperMatrixPtr m, RankBuilderPtr pRankBuilder, double threshold = 2.57);

				virtual ~RWFZScore(void);

			protected:
				virtual void DoWeight(size_t row_no, Matrices::CompressedVector *v, std::set<size_t> &filteredIndices, 
						std::multimap<double,size_t> &val_to_col_no);

				double m_dTreshold;
				double W;

		};

		/////////////////////////////////////

		/**
		 * Rank weigt function based on zscore. In this version we narrow
		 * probability space to only observed co-ocurrances. That is, we 
		 * want to know which one of observed co-ocurrances of two words
		 * is significantly more important of others co-ocurrances. We 
		 * remove independence occurances of words from the equation.
		 */
		class SMART_COMPARATOR_API RWFZScoreInMatrixWeight : public RWFBase
		{
			public:
				/**
				 * \param rank_size Size of ranking.
				 * \param uniformRank if true rank starts at rank_size and goes down. 
				 * If false rank starts from number of cells above t-test treshold, 
				 * e.g. if only 50 cells are above t-test treshold (or only 50 cells are non-zero) 
				 * and rank_size = 100, then best cell will have value of 50 when uniformRank = true 
				 * and 100 when uniformRank = false.
				 * \param minrz Minimum value of z-score
				 */
				RWFZScoreInMatrixWeight(Matrices::SuperMatrixPtr m, RankBuilderPtr pRankBuilder, double minrz = 2.57);
				virtual ~RWFZScoreInMatrixWeight(void);


			protected:
				void CountMatrixSum();
				virtual void DoWeight(size_t row_no, Matrices::CompressedVector *v, std::set<size_t> &filteredIndices, std::multimap<double,size_t> &val_to_col_no);

				double m_dMinRz;
				double m_dMatrixSum;
		};


		/**
		 * Rank weight based on z-score. This version goes to extreme with defining
		 * basic event. We want to check which one of co-occurance of two words are
		 * most important, but we ignore all other words in the equation. 
		 */ 
		class SMART_COMPARATOR_API RWFLocalZScoreWeight : public RWFBase
		{
			public:
				/**
				 * \param rank_size Size of ranking.
				 * \param uniformRank if true rank starts at rank_size and goes down. 
				 * If false rank starts from number of cells above t-test treshold, 
				 * e.g. if only 50 cells are above t-test treshold (or only 50 cells are non-zero) 
				 * and rank_size = 100, then best cell will have value of 50 when uniformRank = true 
				 * and 100 when uniformRank = false.
				 * \param cdf_Pmin Minimum comulative disribution.
				 */
				RWFLocalZScoreWeight(Matrices::SuperMatrixPtr m, RankBuilderPtr pRankBuilder, double minrz=2.57);
				virtual ~RWFLocalZScoreWeight(void);

			protected:
				virtual void DoWeight(size_t row_no, Matrices::CompressedVector *v, std::set<size_t> &filteredIndices,
						std::multimap<double,size_t> &val_to_col_no) ;
				double m_dMinRz;
		};
	}
}


