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

namespace smartcomparator
{
	namespace weights
	{
		LogEntWeight::LogEntWeight(Matrices::SuperMatrixPtr m,  bool useFilteredEntropy) 
			: WeightFeature(m),
			m_UseFilteredEntropy(useFilteredEntropy)
		{
		}

		LogEntWeight::~LogEntWeight(void)
		{
		}


		void LogEntWeight::Weight(size_t rowindex, Matrices::CompressedVector *v, std::set<size_t> &filteredIndices) 
		{
			if(v->GetValues()->size() == 0 )
				return;

			Matrices::FeatureVectorPtr row_features = m_pMatrix->GetRowFeatures();
			double entropy = (*row_features)[rowindex].GetEntropy();

			DevideByEntropy(v, filteredIndices, entropy);

		}

		void LogEntWeight::DevideByEntropy(Matrices::CompressedVector *v, std::set<size_t> &filteredIndices, double entropy)
		{
			if(entropy)
			{
				if(m_UseFilteredEntropy)
				{
					for(std::set<size_t>::const_iterator iter = filteredIndices.begin(); iter != filteredIndices.end();iter++)
					{

						double val = (*v)[(*iter)];
						if(val == 0 )
							continue;
						v->SetElement(*iter, log(val) / entropy);
					}
				}//if(m_UseFilteredEntropy)
				else
				{
					std::map<size_t, double> m = *(v->GetValues());
					for(std::map<size_t, double>::iterator iter = m.begin(); iter != m.end();++iter)
					{
						double val = iter->second;
						if(val == 0 )
							continue;
						v->SetElement(iter->first, log(val) / entropy);
					}
				}// else if(m_UseFilteredEntropy)
			}// if(entropy)
		}// DevideByEntropy
	}
}
