/*
    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 <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>

#include <test_utils/utils.h>


BOOST_AUTO_TEST_CASE(SVDTransformation_MatrixUandSTest)
{
	Matrices::SuperMatrixPtr testMatrix = getTestMatrix();

	smartcomparator::transformations::SVDTransformation svdTrans(testMatrix,9,true);
	svdTrans.TransformMatrix();

	Matrices::CRSMatrixPtr U=svdTrans.getTestUCRS();
	Matrices::CRSMatrixPtr S=svdTrans.getTestSCRS();

	//====== Matrix S checking=========//

	int iterC=0;
	int iterR=0;
	BOOST_CHECK_CLOSE(3.34,S->GetCell(iterC,iterR),5.0);
	iterR++;
	iterC++;
	BOOST_CHECK_CLOSE(2.54,S->GetCell(iterC,iterR),5.0);
	iterR++;
	iterC++;
	BOOST_CHECK_CLOSE(2.35,S->GetCell(iterC,iterR),5.0);
	iterR++;
	iterC++;
	BOOST_CHECK_CLOSE(1.64,S->GetCell(iterC,iterR),5.0);
	iterR++;
	iterC++;
	BOOST_CHECK_CLOSE(1.50,S->GetCell(iterC,iterR),5.0);
	iterR++;
	iterC++;
	BOOST_CHECK_CLOSE(1.31,S->GetCell(iterC,iterR),5.0);
	iterR++;
	iterC++;
	BOOST_CHECK_CLOSE(0.85,S->GetCell(iterC,iterR),5.0);
	iterR++;
	iterC++;
	BOOST_CHECK_CLOSE(0.56,S->GetCell(iterC,iterR),5.0);
	iterR++;
	iterC++;
	BOOST_CHECK_CLOSE(0.36,S->GetCell(iterC,iterR),5.0);

	//====== Matrix U checking=========//
	iterR=0;
	iterC=0;
	BOOST_CHECK_CLOSE(0.22,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.20,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.24,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.40,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.64,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.27,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.27,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.30,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.21,U->GetCell(iterC,iterR),5.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.01,U->GetCell(iterC,iterR),30.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.04,U->GetCell(iterC,iterR),25.0);
	iterC++;
	BOOST_CHECK_CLOSE(0.03,U->GetCell(iterC,iterR),25.0);


}

BOOST_AUTO_TEST_CASE(SVDDimensionsTest)
{
	Matrices::SuperMatrixPtr testMatrix = getTestMatrix();
	smartcomparator::transformations::SVDTransformation trans(testMatrix);

	trans.TransformMatrix();
	Matrices::CompressedVectorPtr v= testMatrix->GetCRS()->GetCompressedRow(0);
	std::map<size_t, double> mp = *(v->GetValues());
	BOOST_REQUIRE_EQUAL(mp.size(), 9);

	Matrices::SuperMatrixPtr testMatrix1 = getTestMatrix();
	trans= smartcomparator::transformations::SVDTransformation(testMatrix1, 5);
	trans.TransformMatrix();
	v= testMatrix1->GetCRS()->GetCompressedRow(1);
	mp = *(v->GetValues());


	BOOST_REQUIRE_EQUAL(mp.size(), 5);


	/*  TEST za dużego parametru dimensions
	testMatrix = getTestMatrix();
	comp = smartcomparator::compare::FunctionFactory::CreateFunction
							("cmp(simfunction=cosine(), weight=svd(svdPath=/home/lukasz/tools/SVDLIBC/svd, dimensions=10))", testMatrix);
	comp->WeighMatrixCopy();
	testMatrix=comp->GetMatrix();
	v= testMatrix->GetCRS()->GetCompressedRow(0);
	mp = *(v->GetValues());
	BOOST_REQUIRE_EQUAL(mp.size(), 5);
	*/
}
