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

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

    setSearchRange<double>(-100,100);

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

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

void FSchwefel_1_2::initialize(){

    setOriginalGlobalOpt();

    switch(m_id){
        case Schwefel_1_2: case Schwefel_1_2_Noisy:
            break;
        case S_Schwefel_1_2: case S_Schwefel_1_2_Noisy:
            loadTranslation();
            break;
        case R_Schwefel_1_2:
            setConditionNumber(2);
            loadRotation();
            break;
        case RS_Schwefel_1_2:
            setConditionNumber(2);
            loadTranslation();
            loadRotation();
            break;
        case S_Schwefel_1_2_CEC05: case S_Schwefel_1_2_Noisy_CEC05:
            setBias(-450);
            loadTranslation();
            break;
        default:
        Throw(Invalid_argument("Error: please check the problem ID"));
        exit(0);
        break;
    }
    setGlobalOpt();
    setAccuracy(1.0e-2);
}
void FSchwefel_1_2::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 FSchwefel_1_2::evaluate_(double const *x){

    double s1=0,s2=0;

    if(m_id==Schwefel_1_2_Noisy||m_id==S_Schwefel_1_2_Noisy){
        double noise;
        for(int i=0;i<m_dimNumber;i++){
            for(int j=0;j<=i;j++){
                noise=0.01*Global::gp_uniformPro->Next();
                s1+=(x[j]+noise);
            }
            s2+=s1*s1;
            s1=0;
        }
    }
    else if(m_id==S_Schwefel_1_2_Noisy_CEC05) {
          for(int i=0;i<m_dimNumber;i++){
               for(int j=0;j<=i;j++)
                    s1+=x[j];
               s2+=s1*s1;
               s1=0;
          }
          s2 *= (1.0 + 0.4 * fabs(Global::gp_normalPro->Next()));
    }
    else{
        for(int i=0;i<m_dimNumber;i++){
		for(int j=0;j<=i;j++)
			s1+=x[j];
		s2+=s1*s1;
		s1=0;
        }
    }

 return s2+m_bias;

}
