# EASEA examples

## Reproducibility

Running evolutionary algorithms is a discipline that is very close to biology laboratory work, because if you use a different random seed each time you launch an experiment, you will always get different results.

Therefore, many tools used to manage wet labs can be of great inspiration when running evolutionary algorithms. Let me quote Rules 5, 6 and 7 from Santiago Schnell's excellent "Ten Simple Rules for a Computational Biologist’s Laboratory Notebook" that can be found here:

Schnell S (2015) Ten Simple Rules for a Computational Biologist’s Laboratory Notebook. PLoS Comput Biol 11(9): e1004385. doi:10.1371/journal.pcbi.1004385


Rule 5: Every Entry Should Be Recorded with a Date, Subject, and Protocol
The most logical organization of a lab notebook is chronological. Each entry should contain the date it was made and subject of the entry. If you make distinct sets of entries in the same day, you should separate them by using heading titles and leave sufficient space between the entries [1]. The titles of your entries are important. They should be short, sharp, and informative, as you will use them to build a table of contents for your lab notebook. If you are using a paper lab notebook, you will need to write the date and time stamp and make your entries legible, written in permanent ink and in a language accessible to everyone in the laboratory. If you use an electronic lab notebook, the date and time stamps will be entered automatically for each new subject.
You should also include a brief background for each entry [2]. It could be a short synopsis of your thought process that explains why this entry is important for your scientific work. You can support it with references published in the literature, ideas learned from a research talk, or a previous model developed by your laboratory. Then, record everything you do for this specific entry. If you make a mistake in your paper lab notebook, put a thin line through the mistake and write the new information next to it [1]. Never erase or destroy an entry, because errors or mistakes are an important part of the scientific process.
Rule 6: Keep a Record of How Every Result Was Produced
Rule 7: Use Version Control for Models, Algorithms, and Computer Code
As a mathematical and computational biologist, you will be updating your models, algorithms, or computer programs frequently. You will also create scripts containing initial conditions and parameters to run analyses or simulations. Changes in your models, algorithms, programs, or scripts could drastically change your results. If you do not systematically archive changes, it will be very difficult or impossible to track the codes that you used to generate certain results [8,9]. Nowadays, there are version control systems to track the evolution of algorithms and computer programs or changes in scripts. Bitbucket, Git, Subversion, and Mercurial are among the most widely used version-control systems. You should use a standardized name system to identify changes. If you have a paper lab notebook, you should record the name and location of the scripts. Those using electronic lab notebooks can add links to each version of their scripts or programs.
References
1. Thomson JA (2007). How to Start—and Keep—a Laboratory Notebook: Policy and Practical Guidelines. In: Intellectual Property Management in Health and Agricultural Innovation: A Handbook of Best Practices (eds. Krattiger A, Mahoney RT, Nelsen L, et al.). MIHR: Oxford, U.K., pp. 763–771.
2. National Institutes of Health, Office of Intramural Training and Education’s Webinar on Keeping a Lab Notebook. https://www.training.nih.gov/OITEtutorials/OITENotebook/Notebook.html
3. Sandefur CI (2014). Blogging for electronic record keeping and collaborative research. Am J Physiol Gastrointest Liver Physiol. 307:G1145–G1146. doi: 10.1152/ajpgi.00384.2014 PMID: 25359540
4. De Polavieja Lab. Open LabBook. http://www.neural-circuits.org/open-labbook
5. Todoroki S, Konishi T, Inoue S (2006). Blog-based research notebook: personal informatics workbench for high-throughput experimentation. Appl Surf Sci 252: 2640–2645.
6. Ruggiero P, Heckathorn MA (2012). Data backup options. Department of Homeland Security, United States Computer Readiness Plan. https://www.us-cert.gov/sites/default/files/publications/data_ backup_options.pdf.
7. Jasny BR, Chin G, Chong L, Vignieri S (2011). Data replication & reproducibility. Again, and again, and again .... Introduction. Science. 334(6060):1225. doi: 10.1126/science.334.6060.1225 PMID: 22144612
8. Sandve GK, Nekrutenko A, Taylor J, Hovig E (2013). Ten simple rules for reproducible computational research. PLoS Comput Biol. 9(10):e1003285. doi: 10.1371/journal.pcbi.1003285 PMID: 24204232
9. Peng RD (2011). Reproducible research in computational science. Science. 334:1226–7. doi: 10. 1126/science.1213847 PMID: 22144613
10. U.S. Department of Health & Human Services, Office of Research Integrity. Notebook and data management. http://ori.hhs.gov/education/products/wsu/data.html
11. U.S. Department of Health & Human Services, Office of Research Integrity. Data Management Responsibilities. http://ori.hhs.gov/education/products/unh_round1/www.unh.edu/rcr/DataMgt- Responsibilities01.htm

## Examples

Some working examples are already present in the examples/ directory. You can try those while changing various parameters.

## Weierstrass

Here a complete EASEA program, as found in the examples/ directory

In file weierstrass.ez:

 /*_________________________________________________________ 

Test functions 

log normal adaptive mutation 

Selection operator: Tournament 

__________________________________________________________*/ 

\User declarations : 

 define SIZE 100 define X_MIN -1. define X_MAX 1. define ITER 120 define Abs(x) ((x) < 0 ? -(x) : (x)) define MAX(x,y) ((x)>(y)?(x):(y)) define MIN(x,y) ((x)<(y)?(x):(y)) define SIGMA 1. /* mutation parameter */ define PI 3.141592654 float pMutPerGene=0.1; \end \User functions: include <math.h> __device__ __host__ inline static float SQR(float d) { return (d*d); } __device__ __host__ inline float rosenbrock( float const *x) { float qualitaet; int i; int DIM = SIZE; qualitaet = 0.0; for( i = DIM-2; i >= 0; --i) qualitaet += 100.*SQR(SQR(x[i])-x[i+1]) + SQR(1.-x[i]); return ( qualitaet); } /* f_rosenbrock() */ __device__ __host__ inline float Weierstrass(float x[SIZE], int n) // Weierstrass multimidmensionnel h = 0.25 { float res = 0.; float val[SIZE]; float b=2.; float h = 0.35; for (int i = 0;i<n; i++) { val[i] = 0.; for (int k=0;k<ITER;k++) val[i] += pow(b,-(float)k*h) * sin(pow(b,(float)k)*x[i]); res += Abs(val[i]); } return (res); } float gauss() /* Generates a normally distributed random value with variance 1 and 0 mean. Algorithm based on "gasdev" from Numerical recipes' pg. 203. */ { static int iset = 0; float gset = 0.0; float v1 = 0.0, v2 = 0.0, r = 0.0; float factor = 0.0; if (iset) { iset = 0; return gset; } else { do { v1 = (float)random(0.,1.) * 2.0 - 1.0; v2 = (float)random(0.,1.) * 2.0 - 1.0; r = v1 * v1 + v2 * v2; } while (r > 1.0); factor = sqrt (-2.0 * log (r) / r); gset = v1 * factor; iset = 1; return (v2 * factor); } } \end \User CUDA: \end \Before everything else function: { } \end \After everything else function: //cout << "After everything else function called" << endl; \end \At the beginning of each generation function:{ } \end \At the end of each generation function: //cout << "At the end of each generation function called" << endl; \end \At each generation before reduce function: //cout << "At each generation before replacement function called" << endl; \end \User classes : GenomeClass { float x[SIZE]; float sigma[SIZE]; // auto-adaptative mutation parameter } \end \GenomeClass::display: /* for( size_t i=0 ; i<SIZE ; i++){ */ /* // cout << Genome.x[i] << ":" << Genome.sigma[i] << "|"; */ /* printf("%.02f:%.02f|",Genome.x[i],Genome.sigma[i]); */ /* } */ \end \GenomeClass::initialiser : // "initializer" is also accepted for(int i=0; i<SIZE; i++ ) { Genome.x[i] = (float)random(X_MIN,X_MAX); Genome.sigma[i]=(float)random(0.,0.5); } \end \GenomeClass::crossover : for (int i=0; i<SIZE; i++) { float alpha = (float)random(0.,1.); // barycentric crossover child.x[i] = alpha*parent1.x[i] + (1.-alpha)*parent2.x[i]; } \end \GenomeClass::mutator : // Must return the number of mutations int NbMut=0; float pond = 1./sqrt((float)SIZE); for (int i=0; i<SIZE; i++) if (tossCoin(pMutPerGene)){ NbMut++; Genome.sigma[i] = Genome.sigma[i] * exp(SIGMA*pond*(float)gauss()); Genome.sigma[i] = MIN(0.5,Genome.sigma[i]); Genome.sigma[i] = MAX(0.,Genome.sigma[i]); Genome.x[i] += Genome.sigma[i]*(float)gauss(); Genome.x[i] = MIN(X_MAX,Genome.x[i]); // pour eviter les depassements Genome.x[i] = MAX(X_MIN,Genome.x[i]); } return NbMut; \end \GenomeClass::evaluator : // Returns the score { float Score= 0.0; Score= Weierstrass(Genome.x, SIZE); //Score= rosenbrock(Genome.x); return Score; } \end \User Makefile options: \end \Default run parameters : // Please let the parameters appear in this order Number of generations : 100 // NB_GEN Time limit: 0 // In seconds, 0 to deactivate Population size : 2048 //POP_SIZE Offspring size : 2048 // 40% Mutation probability : 1 // MUT_PROB Crossover probability : 1 // XOVER_PROB Evaluator goal : minimise // Maximise Selection operator: Tournament 2.0 Surviving parents: 100%//percentage or absolute Surviving offspring: 100% Reduce parents operator: Tournament 2 Reduce offspring operator: Tournament 2 Final reduce operator: Tournament 2 Elitism: Strong //Weak or Strong Elite: 1 Print stats: true //Default: 1 Generate csv stats file:false Generate gnuplot script:false Generate R script:false Plot stats:true //Default: 0 Remote island model: true IP file: ip.txt //File containing all the remote island's IP Server port : 2929 Migration probability: 0.33 Save population: false Start from file:false \end