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

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

    setSearchRange<double>(-500,500);

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

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


void FSchwefel::initialize()
{
    setOriginalGlobalOpt();
    switch(m_id)
    {
    case Schwefel:
    case Schwefel_Noisy:
        break;
    case S_Schwefel:
        loadTranslation();
        break;
    case R_Schwefel:
        setConditionNumber(2);
        loadRotation();
        break;
    case RS_Schwefel:
        setConditionNumber(2);
        loadTranslation();
        loadRotation();
        break;
    default:
        Throw(Invalid_argument("Error: please check the problem ID"));
        exit(0);
        break;
    }
    setGlobalOpt();
    setAccuracy(1.0e-2);

}
void FSchwefel::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]+=420.9687;
    m_globalOpt.m_value=BenchmarkFunction::evaluate(m_globalOpt.mp_location,false);

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


double FSchwefel::evaluate_(double const *x)
{

    double fitness=0;
    for(int i=0; i<m_dimNumber; i++)
    {
        fitness+=-x[i]*sin(sqrt(fabs(x[i])));
    }
    //fitness+=418.9829*m_dimNumber;
    return fitness+m_bias;

}
