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

#define BOOST_TEST_MODULE master
#include <boost/test/included/unit_test.hpp>
#include "sum_flex.h"

void matrixCompare(Matrices::SuperMatrixPtr m1, Matrices::SuperMatrixPtr m2, double precision = 0.0001)
{
	BOOST_CHECK(m1->NumberOfRows() == m2->NumberOfRows() && m1->NumberOfColumns() == m2->NumberOfColumns());
	Matrices::FeatureVectorPtr rowFeatures = m1->GetRowFeatures();
	for (size_t i = 0; i<m1->NumberOfRows(); i++)
	{
		std::string label = (*rowFeatures)[i].GetLabel();
		Matrices::CompressedVectorPtr row1 = m1->GetCRS()->GetCompressedRow(i);
		Matrices::CompressedVectorPtr row2 = m2->GetCRS()->GetCompressedRow(i);

		for (size_t j = 0; j<m1->NumberOfColumns(); j++)
		{
			BOOST_CHECK_CLOSE((*row1)[j],(*row2)[j],precision);
		}
	}
}

void rowCompare(Matrices::CompressedVectorPtr r1, Matrices::CompressedVectorPtr r2, size_t columns, double precision = 0.00001)
{
	for (size_t i = 0; i<columns; i++)
	{
		BOOST_CHECK_CLOSE((*r1)[i],(*r2)[i],precision);
	}
}

BOOST_AUTO_TEST_CASE(sanity_check)
{
	Matrices::SuperMatrixPtr m1;

	m1 = Matrices::IO::LoadSuperMatrix(".","landauer_processed");
	matrixCompare(m1,m1);
}

BOOST_AUTO_TEST_CASE(self_transform)
{
	Matrices::SuperMatrixPtr m1;
	Matrices::SuperMatrixPtr m2;

	m1 = Matrices::IO::LoadSuperMatrix(".","landauer_processed");
	m2 = sum_flex::getOutputMatrix(m1,"foobar");
	matrixCompare(m1,m2);
}

BOOST_AUTO_TEST_CASE(check_out_my_doubles)
{
	Matrices::SuperMatrixPtr m1;
	Matrices::SuperMatrixPtr m2;

	size_t source_row = 0;
	size_t target_row = 3;

	m1 = Matrices::IO::LoadSuperMatrix(".","landauer_processed");

	m1->GetCRS()->SetCompressedRow(target_row, m1->GetCRS()->GetCompressedRow(source_row));
	Matrices::FeatureVectorPtr rowFeatures = m1->GetRowFeatures();
	(*rowFeatures)[target_row] = (*rowFeatures)[source_row];

	Matrices::CompressedVectorPtr temporary(new Matrices::CompressedVector(0,NULL));
	(*temporary) += (*m1->GetRow(source_row));
	(*temporary) += (*m1->GetRow(source_row));
	m2 = sum_flex::getOutputMatrix(m1,"foobar");

	Matrices::CompressedVectorPtr r1 = m2->GetCRS()->GetCompressedRow(source_row);

	rowCompare(r1,temporary,m1->NumberOfColumns());

	Matrices::Feature source_feature = (*m1->GetRowFeatures())[source_row];
	Matrices::Feature result_feature = (*m2->GetRowFeatures())[source_row];

	BOOST_CHECK_EQUAL(2*source_feature.GetGlobalTermFrequency(), result_feature.GetGlobalTermFrequency());
	BOOST_CHECK_EQUAL(2*source_feature.GetTermFrequency(), result_feature.GetTermFrequency());
	BOOST_CHECK_EQUAL(source_feature.GetNZ(), result_feature.GetNZ());
	BOOST_CHECK_CLOSE(source_feature.GetEntropy(), result_feature.GetEntropy(),0.0001);
}
