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

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

    setSearchRange<double>(-0.5,0.5);

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

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


void FWeierstrass::initialize(){

    setOriginalGlobalOpt();
    switch(m_id){
        case Weierstrass:
            break;
        case R_Weierstrass:
            setConditionNumber(2);
            loadRotation();
            break;
        case RS_Weierstrass:
            setConditionNumber(5);
            loadTranslation();
            loadRotation();
            break;
        case RS_Weierstrass_CEC05:
            setConditionNumber(5);
            loadTranslation();
            loadRotation();
             setBias(90);
            break;
        default:
        Throw(Invalid_argument("Error: please check the problem ID"));
        exit(0);
        break;
    }
    setGlobalOpt();
    setAccuracy(1.0e-2);

}
void FWeierstrass::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 FWeierstrass::evaluate_(double const *x){

	double a=0.5,b=3;
	int kmax=20;
	double fit=0,s=0;
	for(int i=0;i<m_dimNumber;i++)
		for(int k=0;k<=kmax;k++)
			fit+=pow(a,k)*cos(2*PI*pow(b,k)*(x[i]+0.5));

	for(int k=0;k<=kmax;k++)
			s+=pow(a,k)*cos(2*PI*pow(b,k)*0.5);
	s=s*m_dimNumber;
	return fit-s+m_bias;

}
