/*************************************************************************
* Project: Library of Evolutionary Algoriths
*************************************************************************
* Author: Changhe Li & Ming Yang
* Email: changhe.lw@google.com Or yangming0702@gmail.com
* Language: C++
*************************************************************************
*  This file is part of EAlib. This library is free software;
*  you can redistribute it and/or modify it under the terms of the
*  GNU General Public License as published by the Free Software
*  Foundation; either version 2, or (at your option) any later version.
*************************************************************************/
// Created: 21 July 2011
// Last modified:
#include "FPenalized_1.h"

FPenalized_1::FPenalized_1(){
    //ctor
}
FPenalized_1::FPenalized_1(const int rId, const int rDimNumber, char *rName):BenchmarkFunction(rId, rDimNumber, rName){

    setSearchRange<double>(-50,50);

     initialize();
}
FPenalized_1::FPenalized_1(const int rId, const int rDimNumber, char *rName, double rL, double rU):BenchmarkFunction(rId, rDimNumber, rName){
    setSearchRange<double>(rL,rU);
    initialize();
}
FPenalized_1::FPenalized_1(const int rId, const int rDimNumber, char *rName, double *rL, double *rU):BenchmarkFunction(rId, rDimNumber, rName){

    setSearchRange<double>(rL,rU);
    initialize();
}
FPenalized_1::~FPenalized_1(){
    //dtor
}


void FPenalized_1::initialize(){
    setOriginalGlobalOpt();
    setGlobalOpt();

}
void FPenalized_1::setGlobalOpt(){
    m_globalOpt.m_knownFlag=true;
    gCopy(m_globalOpt.mp_location,mp_translation,m_dimNumber);
    for(int i=0;i<m_dimNumber;i++) m_globalOpt.mp_location[i]+=m_originalGlobalOpt.mp_location[i];
    m_globalOpt.m_value=BenchmarkFunction::evaluate(m_globalOpt.mp_location,false);

}
void FPenalized_1::setOriginalGlobalOpt(){
    m_originalGlobalOpt.m_knownFlag=true;
    for(int i=0;i<m_dimNumber;i++) m_originalGlobalOpt.mp_location[i]=-1.;
    m_originalGlobalOpt.m_value=BenchmarkFunction::evaluate(m_originalGlobalOpt.mp_location,false);
}


double FPenalized_1::evaluate_(double const *x){
    double * y = new double[m_dimNumber];
	for(int i=0;i<m_dimNumber;i++) y[i]=(x[i]+1)/4.+1;
	double s=0;
	for(int i=0;i<m_dimNumber-1;i++)
		s+=(y[i]-1)*(y[i]-1)*(1+10*sin(PI*y[i+1])*sin(PI*y[i+1]));
	s+=(y[m_dimNumber-1]-1)*(y[m_dimNumber-1]-1)+10*sin(PI*y[0])*sin(PI*y[0]);
	s=s*PI/m_dimNumber;
	for(int i=0;i<m_dimNumber;i++) {
		s+=u(x[i],10,100,4);
	}
	delete []y;
	return s+m_bias;

}
double FPenalized_1::u(double x, double a, double k, double m)const{
	if(x>a) return k*pow(x-a,m);
	else if(x<-a) return k*pow(-x-a,m);
	else return 0;
}
