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

FScaffer_F6::FScaffer_F6(){
    //ctor
}
FScaffer_F6::FScaffer_F6(const int rId, const int rDim, char *rName):BenchmarkFunction(rId, rDim, rName){

    setSearchRange<double>(-100,100);
     initialize();
}
FScaffer_F6::FScaffer_F6(const int rId,  const int rDim, char *rName, double rL, double rU):BenchmarkFunction(rId, rDim, rName){
    setSearchRange<double>(rL,rU);
    initialize();
}
FScaffer_F6::FScaffer_F6(const int rId, const int rDim,  char *rName, double *rL, double *rU):BenchmarkFunction(rId, rDim, rName){

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

void FScaffer_F6::initialize(){
     setOriginalGlobalOpt();
    switch(m_id){
        case RS_Expanded_Scaffer_F6_CEC05:
            setConditionNumber(3);
            loadTranslation();
            loadRotation();
            setBias(-300);
            break;
      default:
          setBias(0);
          break;
    }
    setGlobalOpt();
    setAccuracy(1.0e-2);
}
void FScaffer_F6::setGlobalOpt()
{
     m_globalOpt.m_knownFlag=true;
    gCopy(m_globalOpt.mp_location,mp_translation,m_dimNumber);
    m_globalOpt.m_value=BenchmarkFunction::evaluate(m_globalOpt.mp_location,false);
}

double FScaffer_F6::evaluate_(double const *x){
     double fitness = 0;
     if(m_id == RS_Expanded_Scaffer_F6_CEC05 || m_id == Expanded_Scaffer_F6_CEC05) {
          for(int i=0; i<m_dimNumber; ++i) {
               double result001 = 0;
               double x001 = x[i];
               double x002 = x[(i+1) % m_dimNumber];
               result001 = 0.5 + (pow(sin(sqrt(x001*x001+x002*x002)), 2.0)-0.5)/ pow((1+0.001*(x001*x001+x002*x002)), 2.0);
               fitness += result001;
          }
     }
     else if(m_id == Noncont_Expanded_Scaffer_F6_CEC05) {
          double *y=new double[m_dimNumber];
          for(int i=0;i<m_dimNumber;i++){
               if(fabs(x[i])<0.5) y[i]=x[i];
               else {
                    double a,b=2*x[i];
                    if(b <= 0 && b-(int)b<0.5) a=(int)b;
                    else if(b-(int)b<0.5) a=(int)b;
                    else a = (int)b + 1;
                    y[i]=a/2;
               }
               double result001 = 0;
               double x001 = y[i];
               double x002 = y[(i+1) % m_dimNumber];
               result001 = 0.5 + (pow(sin(sqrt(x001*x001+x002*x002)), 2.0)-0.5)/ pow((1+0.001*(x001*x001+x002*x002)), 2.0);
               fitness += result001;
          }
          delete[] y;
     }
	else {
          fitness=0.5+(sin(sqrt(x[0]*x[0]+x[1]*x[1]))*sin(sqrt(x[0]*x[0]+x[1]*x[1]))-0.5)/((1+0.001*(x[0]*x[0]+x[1]*x[1]))*(1+0.001*(x[0]*x[0]+x[1]*x[1])));
	}

	 return fitness+m_bias;

}
