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

namespace smartcomparator
{

	namespace compare
	{
		EnsembleCompareFunction::EnsembleCompareFunction(std::vector<CompareFunctionPtr> pCompare,
								 std::vector<double> vWeights):
		CompareFunction(pCompare[0]->GetMatrix())
		{
			weights = vWeights;
			comparators = pCompare;
			weightsum = 0;
			for (size_t i=0; i<vWeights.size(); i++)
			{
				weightsum += vWeights[i];
			}
		}
		EnsembleCompareFunction::EnsembleCompareFunction(Matrices::SuperMatrixPtr pMatrix):
				CompareFunction(pMatrix)
		{
		}

		EnsembleCompareFunction::~EnsembleCompareFunction()
		{
		}

		double EnsembleCompareFunction::Compare(size_t n1, size_t n2)
		{
			double sum = 0;
			int n = comparators.size();
			for (int i=0; i<n; i++)
			{
				sum += weights[i] * comparators[i]->Compare(n1,n2);
			}
			sum /= weightsum;
			return sum;
		}

		double EnsembleCompareFunction::MinValue() const
		{
			double sum = 0;
			int n = comparators.size();
			for (int i=0; i<n; i++)
			{
				sum += weights[i] * comparators[i]->MinValue();
			}
			sum /= weightsum;
			return sum;
		}

		bool EnsembleCompareFunction::IsSymmetrical() const
		{
			bool sym = true;
			for (size_t i=0; i<comparators.size() && sym; i++)
			{
				sym = sym && comparators[i]->IsSymmetrical();
			}
			return sym;
		}

		void EnsembleCompareFunction::WeightMatrixCopy()
		{
			for (int i = 0; i < comparators.size(); i++)
			{
				comparators[i]->WeightMatrixCopy();
			}
		}

	}
}
