/*************************************************************************
* 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: 11 May 2011
// Last modified:




#include "Global.h"
#ifdef DEMON_EALIB
#include "../EAGL/EAGL.h"
#endif

/// Add problems here. Note: the orders must be same as appeared in ProblemTag in StructDec.h
string gProName[]={
"Sphere","Sphere_Noisy","S_Sphere","R_Sphere","RS_Sphere","S_Sphere_CEC05", "Sphere_Noisy_CEC05"
,"Rastrigin","Rastrigin_Noisy","S_Rastrigin","R_Rastrigin","RS_Rastrigin","S_Rastrigin_CEC05","RS_Rastrigin_CEC05"
,"Weierstrass","RS_Weierstrass","R_Weierstrass","RS_Weierstrass_CEC05"
,"Griewank","R_Griewank","RS_Griewank", "RS_Griewank_noBounds_CEC05", "Griewank_Rosenbrock_F13_CEC05", "S_Griewank_Rosenbrock_F13_CEC05"
,"Ackley","Ackley_Noisy","S_Ackley","R_Ackley","RS_Ackley","RS_Ackley_Bound_CEC05"
,"Step"
,"Quartic_Noisy"
,"Scaffer_F6", "Expanded_Scaffer_F6_CEC05", "Noncont_Expanded_Scaffer_F6_CEC05", "RS_Expanded_Scaffer_F6_CEC05"
,"Rosenbrock","S_Rosenbrock","S_Rosenbrock_CEC05"
,"Schwefel_2_13_CEC05"
,"Schwefel_2_22","Schwefel_2_22_Noisy","S_Schwefel_2_22","R_Schwefel_2_22","RS_Schwefel_2_22"
,"Schwefel","Schwefel_Noisy","S_Schwefel","R_Schwefel","RS_Schwefel"
,"Schwefel_1_2","Schwefel_1_2_Noisy","S_Schwefel_1_2","S_Schwefel_1_2_Noisy","R_Schwefel_1_2","RS_Schwefel_1_2", "S_Schwefel_1_2_CEC05", "S_Schwefel_1_2_Noisy_CEC05"
,"Schwefel_2_21"
,"Schwefel_2_6_Bound_CEC05"
,"Penalized_1"
,"Penalized_2"
,"Noncont_Rastrigin"
,"RS_Elliptic_CEC05","Elliptic"
,"Com","R_Com","Com_CEC05","H_Com_CEC05","H_Com_Noisy_CEC05"
,"RH_Com_CEC05","RH_Com_NarrowBasin_CEC05","RH_Com_Bound_CEC05"
,"RH_Com_F21_CEC05", "RH_Com_HighConNumMatrix_F22_CEC05", "Noncont_RH_Com_F23_CEC05", "RH_Com_F24_CEC05", "RH_Com_noBounds_F25_CEC05"
,"M_global1","M_global2","M_global3","M_global4","M_global5"
,"S_Sphere_CEC08","Schwefel_2_21_CEC08","S_Rosenbrock_CEC08","S_Rastrigin_CEC08","S_Griewank_CEC08","S_Ackley_CEC08"
,"RW_Gear_Train","RW_ParEst_FMSoundWaves"
,"CompositionDBG_DOP","RotationDBG_DOP","MovingPeak_DOP","DF1_DOP","Binary_DOP"};

/// Add new algorithms here. Note: the orders must be same as appeared in AlgorithmTag in StructDec.h
string gAlgName[]={
    //PSO
    "SPSO","SPSO07","SLPSO","APSO","CPSOH",
    //DE
    "SDE","CRDE",
    //GA
    "SGA_REAL",
    //dynamic optimization
    "CPSO", "CPSOR","CDER","ESCA","SPSO_Parrott","rSPSO","mCPSO","mQSO","PSO_CP","HmSO","SOS","DynDE",
    "CPSORL","CPSORC","mPSO","mDE","CPSOD",
    //Ming_DE
    "Ming_DE", "SaPDE", "JADE",  "jDE", "SaDE", "dynNPDE", "cDE",
    //CMAES
    "CMAES",
    "CLPSO",
    "HRCGA"
};

 map<string, ProblemTag>gProblem;
 map<string, AlgorithmTag>gAlgorithm;
 bool **gAlgPro;

 BasicFunc gFunctionInstance;

int  Global::g_dimNumber;

Cauchy *Global::gp_cauchyPro;
Normal *Global::gp_normalPro;
Uniform *Global::gp_uniformPro;
Levy *Global::gp_levyPro;
Cauchy *Global::gp_cauchyAlg;
Normal *Global::gp_normalAlg;
Uniform *Global::gp_uniformAlg;
Levy *Global::gp_levyAlg;

ProblemTag Global::g_proNumber;
AlgorithmTag  Global::g_algNumber;
Problem *Global::gp_problem=0;
Algorithm *Global::gp_algorithm=0;

float Global::g_sigma=0.0001;

int Global::g_numRuns;
int Global::g_tEvals;
int Global::g_changeFre;
int Global::g_sampleFre;
int Global::g_runIdx=0;

int Global::g_gPopsize=10;
int Global::g_subSize;
float Global::g_overlapDegree;
float Global::g_diversityDegree;


#ifdef DEMON_EALIB
extern bool g_computThrdTermination;
#endif
void gInitializeRandomArray(int * a,const int &dim,const bool mode){
	int * temp=new int[dim];
	for(int i=0;i<dim;i++)	temp[i]=i;
	int d=dim;
	for(int i=0;i<dim;i++){
		int t;
		if(mode)t=	(int)(d*Global::gp_uniformAlg->Next());
		else t=	(int)(d*Global::gp_uniformPro->Next());
		a[i]=temp[t];
		for(int k=t;k<d-1;k++)
			temp[k]=temp[k+1];
		d--;
	}
	delete []temp;
}

int gSign(const double x){
	if(x>0) return 1;
	else if(x<0) return -1;
	else return 0;
}

int gRandInt( const int min, const int max,const bool mode){
	if(mode)
	return static_cast<int>(min+(max-min)*Global::gp_uniformAlg->Next());
	else
	return static_cast<int>(min+(max-min)*Global::gp_uniformPro->Next());
}
double gRandFloat(const double min, const double max,const bool mode){
	if(mode)
	return min+(max-min)*Global::gp_uniformAlg->Next();
	else
		return min+(max-min)*Global::gp_uniformPro->Next();

}
void gCreateRandPro(double seed){

	 Global::gp_cauchyPro=new Cauchy(seed);
	 Global::gp_normalPro=new Normal(seed);
	 Global::gp_uniformPro=new Uniform(seed);
	 Global::gp_levyPro=new Levy(1.4,seed);

}
void gCreateRandAlg(double seed){

	 Global::gp_cauchyAlg=new Cauchy(seed);
	 Global::gp_normalAlg=new Normal(seed);
	 Global::gp_uniformAlg=new Uniform(seed);
	 Global::gp_levyAlg=new Levy(1.4,seed);;

}
void gDeleteRandPro(){

	if(Global::gp_cauchyPro ){delete  Global::gp_cauchyPro; Global::gp_cauchyPro=0;}
	if(Global::gp_normalPro) {delete 	Global::gp_normalPro; Global::gp_normalPro=0;}
	if(Global::gp_uniformPro){delete 	Global::gp_uniformPro; Global::gp_uniformPro=0;}
	if(	Global::gp_levyPro){delete 	Global::gp_levyPro; 	Global::gp_levyPro=0;}

}


void gDeleteRandAlg(){

	if(Global::gp_cauchyAlg){delete 	Global::gp_cauchyAlg; Global::gp_cauchyAlg=0;}
	if( Global::gp_normalAlg){delete 	Global::gp_normalAlg; Global::gp_normalAlg=0;}
	if(	Global::gp_uniformAlg){delete 	Global::gp_uniformAlg; 	Global::gp_uniformAlg=0;}
	if(Global::gp_levyAlg){delete 	Global::gp_levyAlg; Global::gp_levyAlg=0;}
}

bool gIsTerminate(){
	#ifdef EALIB
    if(Global::gp_problem->getEvaluations()>=Global::g_tEvals) return true;
    else return false;
	#endif

	#ifdef DEMON_EALIB
	if(g_computThrdTermination) return true;
	else return false;
	#endif	
}
bool gIsDynamicAlg(){
	if(Global::g_algNumber==ALG_CPSO||Global::g_algNumber==ALG_CPSOR||Global::g_algNumber==ALG_CDER||Global::g_algNumber==ALG_ESCA||Global::g_algNumber==ALG_SPSO_Parrott||Global::g_algNumber==ALG_rSPSO||Global::g_algNumber==ALG_mCPSO||Global::g_algNumber==ALG_mQSO||Global::g_algNumber==ALG_PSO_CP||Global::g_algNumber== ALG_HmSO||Global::g_algNumber== ALG_SOS||Global::g_algNumber==ALG_DynDE||Global::g_algNumber== ALG_CPSORL||Global::g_algNumber== ALG_CPSORC||Global::g_algNumber== ALG_mPSO||Global::g_algNumber== ALG_mDE||Global::g_algNumber==ALG_CPSOD)


	return true;
	else return false;
}
