/*
    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 "TScoreSelector.h"

static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("SuperMatrix.comparator.selectors.TScoreSelector"));

namespace smartcomparator
{
	namespace selectors
	{
		TScoreSelector::TScoreSelector(Matrices::SuperMatrixPtr jm, double t) 
			: Selector(jm),
			m_dTreshold(t)
		{
			W = (double) m_pMatrix->GetTokenCount();

			if(W <= 0 )
			{
				W = 254524624.;
				LOG4CXX_ERROR(logger, "Matrix does not contain information about number of tokens in corpus... Using "
							  << W << " as this value (number of tokens in IPIC 2.0)");
				
			}
		}

		TScoreSelector::~TScoreSelector(void)
		{
		}

		void TScoreSelector::SelectBestFeatures(size_t rowIndex, const std::set<size_t> &filteredIndices, 
			std::set<size_t> &out)
		{
			Matrices::FeatureVectorPtr column_features = m_pMatrix->GetColumnFeatures();
			Matrices::FeatureVectorPtr row_features = m_pMatrix->GetRowFeatures();
			double TFn = (double) (*row_features)[rowIndex].GetGlobalTermFrequency();

			Matrices::CompressedVectorPtr row = m_pMatrix->GetCRS()->GetCompressedRow(rowIndex);
			
			for(std::set<size_t>::const_iterator i = filteredIndices.begin(); i != filteredIndices.end(); i++)
			{
				double Cnc = (*row)[*i];
				if(Cnc == 0) 
					continue;
				double part = (TFn*(*column_features)[*i].GetGlobalTermFrequency()) / W;

				double Rz = (Cnc - part) / sqrt(part);

				if(Rz > m_dTreshold)
					out.insert(*i);
			}
		}
	}
}
