//////////////////////////////////////////////////////////////////////
//
//	CostFunction.cpp: implementation of the CostFunction class.
//
//	Written By: Matthias Wacker
//
//////////////////////////////////////////////////////////////////////

#include "optimization/CostFunction.h"

using namespace opt;

CostFunction::CostFunction() : SuperClass()
{
	m_hasAnalyticGradient = false;
	m_hasAnalyticHessian = false;
	m_numEval = 0;

}

CostFunction::CostFunction(unsigned int numOfParameters) : SuperClass(numOfParameters)
{
	m_hasAnalyticGradient = false;
	m_hasAnalyticHessian = false;
	m_numEval = 0;
}


CostFunction::CostFunction(const CostFunction &func) : SuperClass(func)
{
	m_hasAnalyticGradient = func.m_hasAnalyticGradient;
	m_hasAnalyticHessian = func.m_hasAnalyticHessian;
	m_numEval = func.m_numEval;
}

CostFunction::~CostFunction()
{
}

CostFunction &CostFunction::operator=(const CostFunction &func)
{
		
	/*
			avoid self-copy
	*/
	if(this != &func)
	{
		
		/*
			=operator of SuperClass
		*/
		SuperClass::operator=(func);

		/*
			own values:
		*/
		m_hasAnalyticGradient = func.m_hasAnalyticGradient;
		m_hasAnalyticHessian = func.m_hasAnalyticHessian;
		m_numEval = func.m_numEval;
	
	}

  	return *this;
}


const matrix_type CostFunction::getAnalyticGradient(const matrix_type &x)
{
	/*
		FIXME: WACKER: Throw exception as default behaviour ?
	*/
	
	
	return x * 0;
}

void CostFunction::init()
{
}

const matrix_type CostFunction::getAnalyticHessian(const matrix_type &x)
{
	/*
		FIXME: WACKER: Throw exception as default behaviour
	*/
	
	
	return x * !x *0.0;
}

bool CostFunction::setX0(const matrix_type &x0)
{
	if(x0.rows() == static_cast<int>(m_numOfParameters) && x0.cols() == 1)
	{
		m_x_0 = x0;
		return true;
	}
	else
		return false;
}


bool CostFunction::setH0(const matrix_type &H0)
{
	if(H0.rows() == static_cast<int>(m_numOfParameters) && H0.cols() == 1)
	{
		m_h_0 = H0;
		return true;
	}
	else
		return false;
}

double CostFunction::evaluateSub(double lambda)
{
	return evaluate(m_x_0 + m_h_0 * lambda);
}