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


BOOST_AUTO_TEST_CASE(length_vector)
{
	//Random sequence
	int N = 10000;
	std::vector<double> values;


	double squaresSum=0;

	for(int i=0;i<N;i++)
	{
		values.push_back(((double)rand()/(double)RAND_MAX)*100);
		squaresSum+=values[i]*values[i];
	}

	double len = sqrt(squaresSum);
	Matrices::CompressedVector vect(values);

	BOOST_CHECK_CLOSE(len,Measures::CountVectorLength(vect),0.000001);


	Measures::NormalizeVector(vect);
	BOOST_CHECK_CLOSE(1,Measures::CountVectorLength(vect),0.000001);

	values.clear();
	values.push_back(1);
	Matrices::CompressedVector vect2(values);
	BOOST_CHECK_CLOSE(1,Measures::CountVectorLength(vect2),0.000001);


	values.clear();
	values.push_back(0);

	Matrices::CompressedVector vect3(values);
	BOOST_CHECK_CLOSE(0,Measures::CountVectorLength(vect3),0.000001);

	values.clear();


	Matrices::CompressedVector vect4(values);
	BOOST_CHECK_CLOSE(0,Measures::CountVectorLength(vect4),0.000001);


	values.clear();
	values.push_back(1);
	values.push_back(1);
	Matrices::CompressedVector vect5(values);
	BOOST_CHECK_CLOSE(sqrt(2),Measures::CountVectorLength(vect5),0.000001);
}

BOOST_AUTO_TEST_CASE(length_vector_ptr)
{
	//Random sequence
	int N = 10000;
	std::vector<double> values;


	double squaresSum=0;

	for(int i=0;i<N;i++)
	{
		values.push_back(((double)rand()/(double)RAND_MAX)*100);
		squaresSum+=values[i]*values[i];
	}

	double len = sqrt(squaresSum);
	Matrices::CompressedVectorPtr vect(new Matrices::CompressedVector(values));

	BOOST_CHECK_CLOSE(len,Measures::CountVectorLength(vect),0.000001);


	Measures::NormalizeVector(vect);
	BOOST_CHECK_CLOSE(1,Measures::CountVectorLength(vect),0.000001);

	values.clear();
	values.push_back(1);
	Matrices::CompressedVectorPtr vect2(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(1,Measures::CountVectorLength(vect2),0.000001);


	values.clear();
	values.push_back(0);

	Matrices::CompressedVectorPtr vect3(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(0,Measures::CountVectorLength(vect3),0.000001);

	values.clear();


	Matrices::CompressedVectorPtr vect4(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(0,Measures::CountVectorLength(vect4),0.000001);


	values.clear();
	values.push_back(1);
	values.push_back(1);
	Matrices::CompressedVectorPtr vect5(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(sqrt(2),Measures::CountVectorLength(vect5),0.000001);
}

BOOST_AUTO_TEST_CASE(sum_vector)
{
	//Random sequence
	int N = 10000;
	std::vector<double> values;

	double vectorSum=0;

	for(int i=0;i<N;i++)
	{
		values.push_back(((double)rand()/(double)RAND_MAX)*100);
		vectorSum+=values[i];
	}

	Matrices::CompressedVector vect(values);

	BOOST_CHECK_CLOSE(vectorSum,Measures::CountVectorSum(vect),0.000001);

	values.clear();
	values.push_back(1);
	Matrices::CompressedVector vect2(values);
	BOOST_CHECK_CLOSE(1,Measures::CountVectorSum(vect2),0.000001);


	values.clear();
	values.push_back(0);

	Matrices::CompressedVector vect3(values);
	BOOST_CHECK_CLOSE(0,Measures::CountVectorSum(vect3),0.000001);

	values.clear();


	Matrices::CompressedVector vect4(values);
	BOOST_CHECK_CLOSE(0,Measures::CountVectorSum(vect4),0.000001);
}

BOOST_AUTO_TEST_CASE(sum_vector_ptr)
{
	//Random sequence
	int N = 10000;
	std::vector<double> values;

	double vectorSum=0;

	for(int i=0;i<N;i++)
	{
		values.push_back(((double)rand()/(double)RAND_MAX)*100);
		vectorSum+=values[i];
	}

	Matrices::CompressedVectorPtr vect(new Matrices::CompressedVector(values));


	BOOST_CHECK_CLOSE(vectorSum,Measures::CountVectorSum(vect),0.0001);



	values.clear();
	values.push_back(1);
	Matrices::CompressedVectorPtr vect2(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(1,Measures::CountVectorSum(vect2),0.000001);


	values.clear();
	values.push_back(0);

	Matrices::CompressedVectorPtr vect3(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(0,Measures::CountVectorSum(vect3),0.000001);

	values.clear();


	Matrices::CompressedVectorPtr vect4(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(0,Measures::CountVectorSum(vect3),0.000001);
}

BOOST_AUTO_TEST_CASE( entropy_vector)
{
	//Random sequence
	int N = 10000;
	std::vector<double> values;

	double vectorSum=0;

	for(int i=0;i<N;i++)
	{
		values.push_back(((double)rand()/(double)RAND_MAX)*100);
		vectorSum+=values[i];
	}

	Matrices::CompressedVector vect(values);


	double sum=0;

	double p;
	for(int i=0;i<(int)values.size();i++)
	{
		p=values[i]/vectorSum;
		sum+=p*log(p);
	}

	double entropy=-sum;

	BOOST_CHECK_CLOSE(entropy,Measures::CountVectorEntropy(vect),0.0001);

	//Entropy(1) = 0

	values.clear();
	values.push_back(1);
	Matrices::CompressedVector vect2(values);
	BOOST_CHECK_CLOSE(0,Measures::CountVectorEntropy(vect2),0.000001);


	values.clear();
	values.push_back(0);

	Matrices::CompressedVector vect3(values);
	BOOST_CHECK_CLOSE(0,Measures::CountVectorEntropy(vect3),0.000001);

	values.clear();


	Matrices::CompressedVector vect4(values);
	BOOST_CHECK_CLOSE(0,Measures::CountVectorEntropy(vect3),0.000001);
}

BOOST_AUTO_TEST_CASE( entropy_vector_ptr)
{
	//Random sequence
	int N = 10000;
	std::vector<double> values;

	double vectorSum=0;

	for(int i=0;i<N;i++)
	{
		values.push_back(((double)rand()/(double)RAND_MAX)*100);
		vectorSum+=values[i];
	}

	Matrices::CompressedVectorPtr vect(new Matrices::CompressedVector(values));


	double sum=0;

	double p;
	for(int i=0;i<(int)values.size();i++)
	{
		p=values[i]/vectorSum;
		sum+=p*log(p);
	}

	double entropy=-sum;

	BOOST_CHECK_CLOSE(entropy,Measures::CountVectorEntropy(vect),0.0001);

	//Entropy(1) = 0

	values.clear();
	values.push_back(1);
	Matrices::CompressedVectorPtr vect2(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(0,Measures::CountVectorEntropy(vect2),0.000001);


	values.clear();
	values.push_back(0);

	Matrices::CompressedVectorPtr vect3(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(0,Measures::CountVectorEntropy(vect3),0.000001);

	values.clear();


	Matrices::CompressedVectorPtr vect4(new Matrices::CompressedVector(values));
	BOOST_CHECK_CLOSE(0,Measures::CountVectorEntropy(vect3),0.000001);
}

//void init_measures_suite(boost::unit_test::test_suite* ts)
//{
//
//
//}
