/*
    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.
*/

#ifndef SMARTCOMPARATOR_RWFLINWEIGHT_H
#define SMARTCOMPARATOR_RWFLINWEIGHT_H
#include "../comparator_stdheaders.h"
#include "RWFBase.h"

namespace smartcomparator
{
	namespace weights
	{
		class SMART_COMPARATOR_API RWFLinWeight : public RWFBase
		{
		public:
			/**
			 * Rank weight based on MI. For complete description see Lin's work on it.
			 * It uses similiar scheme to that of SimpleMIWeight, but it diffrenciates
			 * between relations (operator).
			 *
			 * \param operatorIndices indices of columns of last occurances of operators.
			 * Includes firstoperator, so in matrix created with only one operator the vector
			 * will contain only matrix.NumberOfColumns().
			 * \param miFilter filtering of columns (like in Geffet and Dagan)
			*/
			RWFLinWeight(Matrices::SuperMatrixPtr m, RankBuilderPtr pRankBuilder, double treshold = 0);
			RWFLinWeight(Matrices::SuperMatrixPtr m, const std::vector<size_t> & operatorIndices, double miFilter = 0);

			virtual ~RWFLinWeight();

			void FreeMem();

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

			double m_dMiFilter;
			void Initalize();



			bool m_bInitalized;

			std::vector<size_t> m_vOperatorIndices;

			/**
			 * Initizes m_pAnyWordForRelationWithWord and m_pAnyWordForRelationsWithAnyWord.
			 */
			void InitalizeAnyWordForRelationWithWordAndRelations();

			/**
			 * Initizes m_pWordForRelationWithAnyWord.
			 */
			void InitalizeWordForRelationWithAnyWord();

			/**
			Using Lin's notation this is || w, r, * || for any r (JOSKIPI operator).

			First array (m_pAnyWordInRelations[X]) holds data for every relation. The data for relation
			has a size that is equal to number of row of the matrix.
			*/
			double** m_pWordForRelationWithAnyWord;

			/**
			Using Lin's notation this is || *, r, w' ||. The array lenght is equal to number of columns in matrix.
			*/
			double* m_pAnyWordForRelationWithWord;

			/**
			Using Lin's notation this is || *, r, *||, i.e. the count of occurences of given relation r
			for any pair of words. The array lenght is equal to number of relations.
			*/
			double * m_pAnyWordForRelationsWithAnyWord;

		};
	}//namespace weights

}//namespace smartcomparator

#endif //SMARTCOMPARATOR_RWFLINWEIGHT_H
