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

#include "../comparator_stdheaders.h"
#include "PMINoLog.h"

namespace smartcomparator
{
	namespace weights
	{
		PMINoLog::PMINoLog(Matrices::SuperMatrixPtr pMatrix, bool discount, double mi_threshold)
			: WeightFeature(pMatrix),
			m_bDiscount(discount),
			threshold(mi_threshold)
		{
			Initalize();
		}

		PMINoLog::~PMINoLog()
		{
		}
		void PMINoLog::Weight(size_t rowindex, Matrices::CompressedVector *v, std::set<size_t> &filteredIndices)
		{
			Matrices::Feature &row_feature = (*m_pMatrix->GetRowFeatures())[rowindex];
			double row_tf = row_feature.GetTermFrequency();
			for(std::set<size_t>::const_iterator iter = filteredIndices.begin(); iter != filteredIndices.end();iter++)
			{
				double val = (*v)[*iter];
				double column_tf = (double) (* m_pMatrix->GetColumnFeatures())[*iter].GetTermFrequency();
				double nom = val * m_dN;
				double denom = row_tf * column_tf;
				double mi = nom/denom;
				if (mi < 0 || mi < threshold )
					mi = 0;
				if( m_bDiscount )
				{
					double a = val/(val+1);
					double m = row_tf <  column_tf? row_tf : column_tf;
					double b = m/(m+1);
					double discount =  a*b;
					mi *= discount;
					v->SetElement( *iter, mi);
				}
				else v->SetElement( *iter, mi);
			}
		}

		void PMINoLog::Initalize()
		{
			size_t N = 0;
			for(size_t row_no = 0; row_no < m_pMatrix->NumberOfRows(); row_no++)
				N += (* (m_pMatrix->GetRowFeatures()))[row_no].GetTermFrequency();
			m_dN = (double) (N);
		}


		PMINoLogQuantifiedWeight::PMINoLogQuantifiedWeight(Matrices::SuperMatrixPtr m, bool discount)
			: QuantizationWeight(m, WeightFeaturePtr(new PMINoLog(m, discount)) )
		{
		}

	}//	namespace weights
}//namespace smartcomparator
