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

#pragma once
#include "../comparator_stdheaders.h"
#include "WeightFeature.h"

namespace smartcomparator {
	namespace weights {

class SMART_COMPARATOR_API Beta : public WeightFeature {
public:
	struct Modifier {
		virtual double operator()(double pBetaValue) const;
	};
	typedef boost::shared_ptr<Modifier> ModifierPtrS;

	struct ModifierLn : public Modifier {
		virtual double operator()(double pBetaValue) const;
	};

	struct ModifierInverse : public Modifier {
		virtual double operator()(double pBetaValue) const;
	};

	struct ModifierMultiplier : public Modifier {
		ModifierMultiplier(double pMultiplier);
		virtual double operator()(double pBetaValue) const;
	private:
		double mMultiplier;
	};


public:
	struct Params {
		double q;
		double r;
		double s;
		double t;
	};


public:
	Beta(
		Matrices::SuperMatrixPtr& 	pMatrix,
		Params const&				pParams,
		ModifierPtrS const&			pModifier = ModifierPtrS(new Modifier()));

	virtual void Weight(
		size_t 						pRowIndex,			// row index in matrix
		Matrices::CompressedVector* pRow, 				// row from matrix, original not copy!
		std::set<size_t>& 			pFilteredIndices);	// indices of non zero values in this row

	void setParams(Params const& pParams);


private:
	ModifierPtrS 	mModifier;
	Params 			mParams;
	double 			mN;

private:
	void 	build();

	double 	countValue(double pFx, double pFy, double pFxy);
};

	}
}
