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

static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("SuperMatrix.matrices.SuperMatrixSplitter"));

namespace Matrices
{
	void SuperMatrixSplitter::splitMatrix(Matrices::SuperMatrixPtr baseMatrix, std::map<std::string, Matrices::SuperMatrixPtr>& boundaryMap)
	{
		boundaryMap.clear();
		std::map<size_t, std::string > boundaries = baseMatrix->Boundaries();

		int lastColumnIndex=-1;
		Matrices::FeatureVectorPtr rowFeatures = baseMatrix->GetRowFeatures();
		Matrices::FeatureVectorPtr baseColFeatures = baseMatrix->GetColumnFeatures();


		for(std::map<size_t, std::string >::iterator iterBound=boundaries.begin();iterBound!=boundaries.end();++iterBound)
		{

			Matrices::CCSMatrixPtr ccsMatrix (new Matrices::CCSMatrix("ccs",rowFeatures->size(),
										  (*iterBound).first-lastColumnIndex-1));
			Matrices::CRSMatrixPtr crsMatrix (new Matrices::CRSMatrix("crs",rowFeatures->size(),
										  (*iterBound).first-lastColumnIndex-1));
			LOG4CXX_INFO(logger,"Created new ccs and crs matrices "<<rowFeatures->size()<<"x"<<(*iterBound).first-lastColumnIndex-1);
			//Copying matrices
			for(int i=0;i<(int)rowFeatures->size();i++)

			{
				Matrices::STDoubleMapPtr currentRow = baseMatrix->GetRow(i)->GetValues();
				for(Matrices::STDoubleMapIter iter=currentRow->begin();
				iter!=currentRow->end() && (*iter).first <(*iterBound).first;++iter)
				{
					if((int)(*iter).first > lastColumnIndex)
					{
						ccsMatrix->SetCell((*iter).second,i,(*iter).first-lastColumnIndex-1);
						crsMatrix->SetCell((*iter).second,i,(*iter).first-lastColumnIndex-1);
					}
				}
				rowFeatures->at(i).SetNZ(crsMatrix->GetCompressedRow(i)->GetValues()->size());
				rowFeatures->at(i).SetEntropy(Measures::CountVectorEntropy(*(crsMatrix->GetCompressedRow(i))));
				rowFeatures->at(i).SetTermFrequnecy(Measures::CountVectorSum(crsMatrix->GetCompressedRow(i)));

			}
			Matrices::FeatureVectorPtr colFeatures (new Matrices::FeatureVector);
			for(int i=lastColumnIndex+1;i<(int)(*iterBound).first;i++)
				colFeatures->push_back(baseColFeatures->at(i));
			std::map<size_t,std::string> newBoundaries;
			newBoundaries.insert(std::pair<size_t,std::string>((*iterBound).first-lastColumnIndex-1,(*iterBound).second));

			Matrices::SuperMatrixPtr newMatrix(new Matrices::SuperMatrix((*iterBound).second,ccsMatrix,crsMatrix,rowFeatures,colFeatures,
										     baseMatrix->GetTokenCount(),baseMatrix->GetCorpusInfo(),newBoundaries));

			boundaryMap[(*iterBound).second] = newMatrix;
			LOG4CXX_INFO(logger,"Copied boundary "<<(*iterBound).second);
			lastColumnIndex = (*iterBound).first-1;
		}
	}
}
