1 /*
2  *  cMutationalNeighborhood.cc
3  *  Avida
4  *
5  *  Created by David on 6/13/06.
6  *  Copyright 1999-2011 Michigan State University. All rights reserved.
7  *
8  *
9  *  This file is part of Avida.
10  *
11  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
12  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
13  *
14  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
18  *  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #include "cMutationalNeighborhood.h"
23 
24 #include "cAnalyze.h"
25 #include "cAnalyzeJobQueue.h"
26 #include "cCPUTestInfo.h"
27 #include "cEnvironment.h"
28 #include "cInstSet.h"
29 #include "cHardwareManager.h"
30 #include "cOrganism.h"
31 #include "cPhenotype.h"
32 #include "cStats.h"
33 #include "cTestCPU.h"
34 #include "cWorld.h"
35 #include "tAnalyzeJob.h"
36 
37 using namespace std;
38 
39 
cMutationalNeighborhood(cWorld * world,const Genome & genome,int target)40 cMutationalNeighborhood::cMutationalNeighborhood(cWorld* world, const Genome& genome, int target)
41   : m_world(world), m_initialized(false), m_inst_set(m_world->GetHardwareManager().GetInstSet(genome.GetInstSet()))
42   , m_target(target), m_base_genome(genome)
43 {
44   // Acquire write lock, to prevent any cMutationalNeighborhoodResults instances before computing
45   m_rwlock.WriteLock();
46 }
47 
48 
Process(cAvidaContext & ctx)49 void cMutationalNeighborhood::Process(cAvidaContext& ctx)
50 {
51   m_mutex.Lock();
52   if (m_initialized) {
53     int cur_site = m_cur_site++;
54     m_mutex.Unlock();
55 
56     if (cur_site < m_base_genome.GetSize()) {
57       // Create test infrastructure
58       cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU(ctx);
59       cCPUTestInfo test_info;
60 
61       // Setup One Step Data
62       sStep& opdata = m_onestep_point[cur_site];
63       opdata.peak_fitness = m_base_fitness;
64       opdata.peak_genome = m_base_genome;
65       opdata.site_count.Resize(m_base_genome.GetSize(), 0);
66 
67       sStep& oidata = m_onestep_insert[cur_site];
68       oidata.peak_fitness = m_base_fitness;
69       oidata.peak_genome = m_base_genome;
70       oidata.site_count.Resize(m_base_genome.GetSize() + 1, 0);
71 
72       sStep& oddata = m_onestep_delete[cur_site];
73       oddata.peak_fitness = m_base_fitness;
74       oddata.peak_genome = m_base_genome;
75       oddata.site_count.Resize(m_base_genome.GetSize(), 0);
76 
77 
78       // Setup Data Used in Two Step
79       sStep& tpdata = m_twostep_point[cur_site];
80       tpdata.peak_fitness = m_base_fitness;
81       tpdata.peak_genome = m_base_genome;
82       tpdata.site_count.Resize(m_base_genome.GetSize(), 0);
83 
84       sStep& tidata = m_twostep_insert[cur_site];
85       tidata.peak_fitness = m_base_fitness;
86       tidata.peak_genome = m_base_genome;
87       tidata.site_count.Resize(m_base_genome.GetSize() + 2, 0);
88 
89       sStep& tddata = m_twostep_delete[cur_site];
90       tddata.peak_fitness = m_base_fitness;
91       tddata.peak_genome = m_base_genome;
92       tddata.site_count.Resize(m_base_genome.GetSize(), 0);
93 
94 
95       sStep& tipdata = m_insert_point[cur_site];
96       tipdata.peak_fitness = m_base_fitness;
97       tipdata.peak_genome = m_base_genome;
98       tipdata.site_count.Resize(m_base_genome.GetSize() + 1, 0);
99 
100       sStep& tiddata = m_insert_delete[cur_site];
101       tiddata.peak_fitness = m_base_fitness;
102       tiddata.peak_genome = m_base_genome;
103       tiddata.site_count.Resize(m_base_genome.GetSize() + 1, 0);
104 
105       sStep& tdpdata = m_delete_point[cur_site];
106       tdpdata.peak_fitness = m_base_fitness;
107       tdpdata.peak_genome = m_base_genome;
108       tdpdata.site_count.Resize(m_base_genome.GetSize(), 0);
109 
110 
111       // Do the processing, starting with One Step
112       ProcessOneStepPoint(ctx, testcpu, test_info, cur_site);
113       ProcessOneStepInsert(ctx, testcpu, test_info, cur_site);
114       ProcessOneStepDelete(ctx, testcpu, test_info, cur_site);
115 
116       // Process the hanging insertion on the first cycle through (to balance execution time)
117       if (cur_site == 0) {
118         cur_site = m_base_genome.GetSize();
119 
120         sStep& oidata2 = m_onestep_insert[cur_site];
121         oidata2.peak_fitness = m_base_fitness;
122         oidata2.peak_genome = m_base_genome;
123         oidata2.site_count.Resize(m_base_genome.GetSize() + 1, 0);
124 
125         sStep& tidata2 = m_twostep_insert[cur_site];
126         tidata2.peak_fitness = m_base_fitness;
127         tidata2.peak_genome = m_base_genome;
128         tidata2.site_count.Resize(m_base_genome.GetSize() + 2, 0);
129 
130         sStep& tipdata2 = m_insert_point[cur_site];
131         tipdata2.peak_fitness = m_base_fitness;
132         tipdata2.peak_genome = m_base_genome;
133         tipdata2.site_count.Resize(m_base_genome.GetSize() + 1, 0);
134 
135         sStep& tiddata2 = m_insert_delete[cur_site];
136         tiddata2.peak_fitness = m_base_fitness;
137         tiddata2.peak_genome = m_base_genome;
138         tiddata2.site_count.Resize(m_base_genome.GetSize() + 1, 0);
139 
140         ProcessOneStepInsert(ctx, testcpu, test_info, cur_site);
141       }
142 
143       // Cleanup
144       delete testcpu;
145     }
146   } else {
147     ProcessInitialize(ctx);
148     return;
149   }
150 
151   m_mutex.Lock();
152   if (++m_completed == m_base_genome.GetSize()) ProcessComplete(ctx);
153   m_mutex.Unlock();
154 }
155 
156 
ProcessInitialize(cAvidaContext & ctx)157 void cMutationalNeighborhood::ProcessInitialize(cAvidaContext& ctx)
158 {
159   // Generate base information
160   cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU(ctx);
161   cCPUTestInfo test_info;
162   testcpu->TestGenome(ctx, test_info, m_base_genome);
163 
164   cPhenotype& phenotype = test_info.GetColonyOrganism()->GetPhenotype();
165   m_base_fitness = test_info.GetColonyFitness();
166   m_base_merit = phenotype.GetMerit().GetDouble();
167   m_base_gestation = phenotype.GetGestationTime();
168   m_base_tasks = phenotype.GetLastTaskCount();
169 
170   m_neut_min = m_base_fitness * nHardware::FITNESS_NEUTRAL_MIN;
171   m_neut_max = m_base_fitness * nHardware::FITNESS_NEUTRAL_MAX;
172 
173   // If invalid target supplied, set to the last task
174   if (m_target >= m_base_tasks.GetSize() || m_target < 0) m_target = m_base_tasks.GetSize() - 1;
175 
176   delete testcpu;
177 
178   // Setup state to begin processing
179   m_onestep_point.ResizeClear(m_base_genome.GetSize());
180   m_onestep_insert.ResizeClear(m_base_genome.GetSize() + 1);
181   m_onestep_delete.ResizeClear(m_base_genome.GetSize());
182 
183   m_twostep_point.ResizeClear(m_base_genome.GetSize());
184   m_twostep_insert.ResizeClear(m_base_genome.GetSize() + 1);
185   m_twostep_delete.ResizeClear(m_base_genome.GetSize());
186 
187   m_insert_point.ResizeClear(m_base_genome.GetSize() + 1);
188   m_insert_delete.ResizeClear(m_base_genome.GetSize() + 1);
189   m_delete_point.ResizeClear(m_base_genome.GetSize());
190 
191   m_fitness_point.ResizeClear(m_base_genome.GetSize(), m_inst_set.GetSize());
192   m_fitness_insert.ResizeClear(m_base_genome.GetSize() + 1, m_inst_set.GetSize());
193   m_fitness_delete.ResizeClear(m_base_genome.GetSize(), 1);
194 
195   m_cur_site = 0;
196   m_completed = 0;
197   m_initialized = true;
198 
199   // Unlock internal mutex (was locked on Process() entrance)
200   //  - will allow workers to begin processing if job queue already active
201   m_mutex.Unlock();
202 
203   // Load enough jobs to process all sites
204   cAnalyzeJobQueue& jobqueue = m_world->GetAnalyze().GetJobQueue();
205   for (int i = 0; i < m_base_genome.GetSize(); i++)
206     jobqueue.AddJob(new tAnalyzeJob<cMutationalNeighborhood>(this, &cMutationalNeighborhood::Process));
207 
208   jobqueue.Start();
209 }
210 
211 
ProcessOneStepPoint(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site)212 void cMutationalNeighborhood::ProcessOneStepPoint(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info, int cur_site)
213 {
214   const int inst_size = m_inst_set.GetSize();
215   sStep& odata = m_onestep_point[cur_site];
216 
217   Genome mod_genome(m_base_genome);
218   Sequence& seq = mod_genome.GetSequence();
219 
220   // Loop through all the lines of genome, testing trying all combinations.
221   int cur_inst = seq[cur_site].GetOp();
222 
223   // Fill in unmutated entry in fitness table with base fitness
224   m_fitness_point[cur_site][cur_inst] = m_base_fitness;
225 
226   // Loop through all instructions...
227   for (int inst_num = 0; inst_num < inst_size; inst_num++) {
228     if (cur_inst == inst_num) continue;
229 
230     seq[cur_site].SetOp(inst_num);
231     m_fitness_point[cur_site][inst_num] = ProcessOneStepGenome(ctx, testcpu, test_info, mod_genome, odata, cur_site);
232 
233     ProcessTwoStepPoint(ctx, testcpu, test_info, cur_site, mod_genome);
234   }
235 }
236 
ProcessOneStepInsert(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site)237 void cMutationalNeighborhood::ProcessOneStepInsert(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info, int cur_site)
238 {
239   const int inst_size = m_inst_set.GetSize();
240   sStep& odata = m_onestep_insert[cur_site];
241 
242   Genome mod_genome(m_base_genome);
243   Sequence& seq = mod_genome.GetSequence();
244   seq.Insert(cur_site, cInstruction(0));
245 
246   // Loop through all instructions...
247   for (int inst_num = 0; inst_num < inst_size; inst_num++) {
248     seq[cur_site].SetOp(inst_num);
249     m_fitness_insert[cur_site][inst_num] = ProcessOneStepGenome(ctx, testcpu, test_info, mod_genome, odata, cur_site);
250 
251     ProcessTwoStepInsert(ctx, testcpu, test_info, cur_site, mod_genome);
252     ProcessInsertPointCombo(ctx, testcpu, test_info, cur_site, mod_genome);
253     ProcessInsertDeleteCombo(ctx, testcpu, test_info, cur_site, mod_genome);
254   }
255 }
256 
257 
ProcessOneStepDelete(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site)258 void cMutationalNeighborhood::ProcessOneStepDelete(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info, int cur_site)
259 {
260   sStep& odata = m_onestep_delete[cur_site];
261 
262   Genome mod_genome(m_base_genome);
263   Sequence& seq = mod_genome.GetSequence();
264   seq.Remove(cur_site);
265 
266   m_fitness_delete[cur_site][0] = ProcessOneStepGenome(ctx, testcpu, test_info, mod_genome, odata, cur_site);
267   ProcessTwoStepDelete(ctx, testcpu, test_info, cur_site, mod_genome);
268   ProcessDeletePointCombo(ctx, testcpu, test_info, cur_site, mod_genome);
269 }
270 
271 
ProcessOneStepGenome(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,const Genome & mod_genome,sStep & odata,int cur_site)272 double cMutationalNeighborhood::ProcessOneStepGenome(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info,
273                                                      const Genome& mod_genome, sStep& odata, int cur_site)
274 {
275   // Run the modified genome through the Test CPU
276   testcpu->TestGenome(ctx, test_info, mod_genome);
277 
278   // Collect the calculated fitness
279   double test_fitness = test_info.GetColonyFitness();
280 
281 
282   odata.total_fitness += test_fitness;
283   odata.total_sqr_fitness += test_fitness * test_fitness;
284   odata.total++;
285   if (test_fitness == 0.0) {
286     odata.dead++;
287   } else if (test_fitness < m_neut_min) {
288     odata.neg++;
289     odata.size_neg += test_fitness;
290   } else if (test_fitness <= m_neut_max) {
291     odata.neut++;
292   } else {
293     odata.pos++;
294     odata.size_pos += test_fitness;
295     if (test_fitness > odata.peak_fitness) {
296       odata.peak_fitness = test_fitness;
297       odata.peak_genome = mod_genome;
298     }
299   }
300 
301   if (test_fitness >= m_neut_min) odata.site_count[cur_site]++;
302 
303   if (test_fitness != 0.0) { // Only count tasks if the organism is alive
304     const tArray<int>& cur_tasks = test_info.GetColonyOrganism()->GetPhenotype().GetLastTaskCount();
305     bool knockout = false;
306     bool anytask = false;
307     for (int i = 0; i < m_base_tasks.GetSize(); i++) {
308       if (m_base_tasks[i] && !cur_tasks[i]) knockout = true;
309       else if (!m_base_tasks[i] && cur_tasks[i]) anytask = true;
310     }
311     if (knockout) {
312       odata.task_knockout++;
313       odata.task_size_knockout += test_fitness;
314     }
315     if (anytask) {
316       odata.task_total++;
317       odata.task_size_total += test_fitness;
318     }
319     if (m_base_tasks.GetSize() && !m_base_tasks[m_target] && cur_tasks[m_target]) {
320       odata.task_target++;
321       odata.task_size_target += test_fitness;
322     }
323   }
324 
325   return test_fitness;
326 }
327 
328 
329 
ProcessTwoStepPoint(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site,Genome & mod_genome)330 void cMutationalNeighborhood::ProcessTwoStepPoint(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info,
331                                                   int cur_site, Genome& mod_genome)
332 {
333   const int inst_size = m_inst_set.GetSize();
334   Sequence& seq = mod_genome.GetSequence();
335   sTwoStep& tdata = m_twostep_point[cur_site];
336   sPendFit cur(m_fitness_point, cur_site, seq[cur_site].GetOp());
337 
338   // Loop through remaining lines of genome, testing trying all combinations.
339   for (int line_num = cur_site + 1; line_num < m_base_genome.GetSize(); line_num++) {
340     int cur_inst = seq[line_num].GetOp();
341 
342     // Loop through all instructions...
343     for (int inst_num = 0; inst_num < inst_size; inst_num++) {
344       if (cur_inst == inst_num) continue;
345 
346       seq[line_num].SetOp(inst_num);
347       ProcessTwoStepGenome(ctx, testcpu, test_info, mod_genome, tdata, sPendFit(m_fitness_point, line_num, inst_num), cur);
348     }
349 
350     seq[line_num].SetOp(cur_inst);
351   }
352 }
353 
354 
ProcessTwoStepInsert(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site,Genome & mod_genome)355 void cMutationalNeighborhood::ProcessTwoStepInsert(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info,
356                                                    int cur_site, Genome& mod_genome)
357 {
358   const int inst_size = m_inst_set.GetSize();
359   const int mod_size = mod_genome.GetSize();
360   Sequence& seq = mod_genome.GetSequence();
361   sTwoStep& tdata = m_twostep_insert[cur_site];
362   sPendFit cur(m_fitness_insert, cur_site, seq[cur_site].GetOp());
363 
364   // Loop through all instructions...
365   for (int line_num = cur_site + 1; line_num <= mod_size; line_num++) {
366     seq.Insert(line_num, cInstruction(0));
367 
368     for (int inst_num = 0; inst_num < inst_size; inst_num++) {
369       seq[cur_site].SetOp(inst_num);
370       ProcessTwoStepGenome(ctx, testcpu, test_info, mod_genome, tdata, sPendFit(m_fitness_insert, line_num - 1, inst_num), cur);
371     }
372     seq.Remove(line_num);
373   }
374 }
375 
376 
ProcessTwoStepDelete(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site,Genome & mod_genome)377 void cMutationalNeighborhood::ProcessTwoStepDelete(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info,
378                                                    int cur_site, Genome& mod_genome)
379 {
380   const int mod_size = mod_genome.GetSize();
381   Sequence& seq = mod_genome.GetSequence();
382   sTwoStep& tdata = m_twostep_delete[cur_site];
383   sPendFit cur(m_fitness_delete, cur_site, 0); // Delete 'inst' is always 0
384 
385   // Loop through all instructions...
386   for (int line_num = cur_site; line_num < mod_size; line_num++) {
387     int cur_inst = seq[line_num].GetOp();
388     seq.Remove(line_num);
389     ProcessTwoStepGenome(ctx, testcpu, test_info, mod_genome, tdata, sPendFit(m_fitness_delete, line_num + 1, 0), cur);
390     seq.Insert(line_num, cInstruction(cur_inst));
391   }
392 }
393 
394 
ProcessInsertPointCombo(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site,Genome & mod_genome)395 void cMutationalNeighborhood::ProcessInsertPointCombo(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info,
396                                                       int cur_site, Genome& mod_genome)
397 {
398   const int inst_size = m_inst_set.GetSize();
399   Sequence& seq = mod_genome.GetSequence();
400   sTwoStep& tdata = m_insert_point[cur_site];
401   sPendFit cur(m_fitness_insert, cur_site, seq[cur_site].GetOp());
402 
403   // Loop through all lines of genome, testing trying all combinations.
404   for (int line_num = 0; line_num < seq.GetSize(); line_num++) {
405     if (line_num == cur_site) continue; // Skip the site of the insertion
406     int actual = (line_num < cur_site) ? line_num : (line_num - 1); // if at or past insertion site, adjust pending target site
407 
408     int cur_inst = seq[line_num].GetOp();
409 
410     // Loop through all instructions...
411     for (int inst_num = 0; inst_num < inst_size; inst_num++) {
412       if (cur_inst == inst_num) continue;
413 
414       seq[line_num].SetOp(inst_num);
415       ProcessTwoStepGenome(ctx, testcpu, test_info, mod_genome, tdata, sPendFit(m_fitness_point, actual, inst_num), cur);
416     }
417 
418     seq[line_num].SetOp(cur_inst);
419   }
420 }
421 
422 
ProcessInsertDeleteCombo(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site,Genome & mod_genome)423 void cMutationalNeighborhood::ProcessInsertDeleteCombo(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info,
424                                                        int cur_site, Genome& mod_genome)
425 {
426   Sequence& seq = mod_genome.GetSequence();
427   sTwoStep& tdata = m_insert_delete[cur_site];
428   sPendFit cur(m_fitness_insert, cur_site, seq[cur_site].GetOp());
429 
430   // Loop through all lines of genome, testing trying all combinations.
431   for (int line_num = 0; line_num < seq.GetSize(); line_num++) {
432     if (line_num == cur_site) continue; // Skip the site of the insertion
433     int actual = (line_num < cur_site) ? line_num : (line_num - 1); // if at or past insertion site, adjust pending target site
434 
435     int cur_inst = seq[line_num].GetOp();
436     seq.Remove(line_num);
437     ProcessTwoStepGenome(ctx, testcpu, test_info, mod_genome, tdata, sPendFit(m_fitness_delete, actual, 0), cur);
438     seq.Insert(line_num, cInstruction(cur_inst));
439   }
440 }
441 
442 
ProcessDeletePointCombo(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,int cur_site,Genome & mod_genome)443 void cMutationalNeighborhood::ProcessDeletePointCombo(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info,
444                                                       int cur_site, Genome& mod_genome)
445 {
446   const int inst_size = m_inst_set.GetSize();
447   Sequence& seq = mod_genome.GetSequence();
448   sTwoStep& tdata = m_delete_point[cur_site];
449   sPendFit cur(m_fitness_delete, cur_site, 0); // Delete 'inst' is always 0
450 
451   // Loop through all lines of genome, testing trying all combinations.
452   for (int line_num = 0; line_num < seq.GetSize(); line_num++) {
453     int cur_inst = seq[line_num].GetOp();
454     int actual = (line_num < cur_site) ? line_num : (line_num + 1); // if at or past deletion site, adjust pending target site
455 
456     // Loop through all instructions...
457     for (int inst_num = 0; inst_num < inst_size; inst_num++) {
458       if (cur_inst == inst_num) continue;
459 
460       seq[line_num].SetOp(inst_num);
461       ProcessTwoStepGenome(ctx, testcpu, test_info, mod_genome, tdata, sPendFit(m_fitness_point, actual, inst_num), cur);
462     }
463 
464     seq[line_num].SetOp(cur_inst);
465   }
466 }
467 
468 
ProcessTwoStepGenome(cAvidaContext & ctx,cTestCPU * testcpu,cCPUTestInfo & test_info,const Genome & mod_genome,sTwoStep & tdata,const sPendFit & cur,const sPendFit & oth)469 double cMutationalNeighborhood::ProcessTwoStepGenome(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info,
470                                                      const Genome& mod_genome, sTwoStep& tdata,
471                                                      const sPendFit& cur, const sPendFit& oth)
472 {
473   // Run the modified genome through the Test CPU
474   testcpu->TestGenome(ctx, test_info, mod_genome);
475 
476   // Collect the calculated fitness
477   double test_fitness = test_info.GetColonyFitness();
478 
479   tdata.total_fitness += test_fitness;
480   tdata.total_sqr_fitness += test_fitness * test_fitness;
481   tdata.total++;
482   if (test_fitness == 0.0) {
483     tdata.dead++;
484   } else if (test_fitness < m_neut_min) {
485     tdata.neg++;
486     tdata.size_neg += test_fitness;
487   } else if (test_fitness <= m_neut_max) {
488     tdata.neut++;
489   } else {
490     tdata.pos++;
491     tdata.size_pos += test_fitness;
492     if (test_fitness > tdata.peak_fitness) {
493       tdata.peak_fitness = test_fitness;
494       tdata.peak_genome = mod_genome;
495     }
496   }
497 
498   if (test_fitness >= m_neut_min) tdata.site_count[cur.site]++;
499 
500   if (test_fitness != 0.0) { // Only count tasks if the organism is alive
501     const tArray<int>& cur_tasks = test_info.GetColonyOrganism()->GetPhenotype().GetLastTaskCount();
502     bool knockout = false;
503     bool anytask = false;
504     for (int i = 0; i < m_base_tasks.GetSize(); i++) {
505       if (m_base_tasks[i] && !cur_tasks[i]) knockout = true;
506       else if (!m_base_tasks[i] && cur_tasks[i]) anytask = true;
507     }
508     if (knockout) {
509       tdata.task_knockout++;
510       tdata.task_size_knockout += test_fitness;
511     }
512     if (anytask) {
513       tdata.task_total++;
514       tdata.task_size_total += test_fitness;
515     }
516     if (m_base_tasks.GetSize() && !m_base_tasks[m_target] && cur_tasks[m_target]) {
517       tdata.task_target++;
518       tdata.task_size_target += test_fitness;
519 
520       // Push both instructions as possible first mutations, for post determination of first step fitness effect
521       tdata.pending.Push(new sPendFit(oth));
522       tdata.pending.Push(new sPendFit(cur));
523     }
524   }
525 
526   return test_fitness;
527 }
528 
ProcessComplete(cAvidaContext & ctx)529 void cMutationalNeighborhood::ProcessComplete(cAvidaContext& ctx)
530 {
531   m_op.peak_fitness = m_base_fitness;
532   m_op.peak_genome = m_base_genome;
533   m_op.site_count.Resize(m_base_genome.GetSize(), 0);
534   AggregateOneStep(m_onestep_point, m_op);
535 
536   m_oi.peak_fitness = m_base_fitness;
537   m_oi.peak_genome = m_base_genome;
538   m_oi.site_count.Resize(m_base_genome.GetSize() + 1, 0);
539   AggregateOneStep(m_onestep_insert, m_oi);
540 
541   m_od.peak_fitness = m_base_fitness;
542   m_od.peak_genome = m_base_genome;
543   m_od.site_count.Resize(m_base_genome.GetSize(), 0);
544   AggregateOneStep(m_onestep_delete, m_od);
545 
546 
547   // Collect totals across all one step mutants
548   m_ot.total = m_op.total + m_oi.total + m_od.total;
549   m_ot.total_fitness = m_op.total_fitness + m_oi.total_fitness + m_od.total_fitness;
550   m_ot.total_sqr_fitness = m_op.total_sqr_fitness + m_oi.total_sqr_fitness + m_od.total_sqr_fitness;
551 
552   if (m_op.peak_fitness >= m_oi.peak_fitness && m_op.peak_fitness >= m_od.peak_fitness) {
553     m_ot.peak_fitness = m_op.peak_fitness;
554     m_ot.peak_genome = m_op.peak_genome;
555   } else if (m_oi.peak_fitness >= m_od.peak_fitness) {
556     m_ot.peak_fitness = m_oi.peak_fitness;
557     m_ot.peak_genome = m_oi.peak_genome;
558   } else {
559     m_ot.peak_fitness = m_od.peak_fitness;
560     m_ot.peak_genome = m_od.peak_genome;
561   }
562 
563   m_ot.pos = m_op.pos + m_oi.pos + m_od.pos;
564   m_ot.neg = m_op.neg + m_oi.neg + m_od.neg;
565   m_ot.neut = m_op.neut + m_oi.neut + m_od.neut;
566   m_ot.dead = m_op.dead + m_oi.dead + m_od.dead;
567   m_ot.size_pos = m_op.size_pos + m_oi.size_pos + m_od.size_pos;
568   m_ot.size_neg = m_op.size_neg + m_oi.size_neg + m_od.size_neg;
569 
570   m_ot.task_target = m_op.task_target + m_oi.task_target + m_od.task_target;
571   m_ot.task_total = m_op.task_total + m_oi.task_total + m_od.task_total;
572   m_ot.task_knockout = m_op.task_knockout + m_oi.task_knockout + m_od.task_knockout;
573 
574   m_ot.task_size_target = m_op.task_size_target + m_oi.task_size_target + m_od.task_size_target;
575   m_ot.task_size_total = m_op.task_size_total + m_oi.task_size_total + m_od.task_size_total;
576   m_ot.task_size_knockout = m_op.task_size_knockout + m_oi.task_size_knockout + m_od.task_size_knockout;
577 
578 
579 
580 
581   m_tp.peak_fitness = m_base_fitness;
582   m_tp.peak_genome = m_base_genome;
583   m_tp.site_count.Resize(m_base_genome.GetSize(), 0);
584   AggregateTwoStep(m_twostep_point, m_tp);
585 
586   m_ti.peak_fitness = m_base_fitness;
587   m_ti.peak_genome = m_base_genome;
588   m_ti.site_count.Resize(m_base_genome.GetSize() + 2, 0);
589   AggregateTwoStep(m_twostep_insert, m_ti);
590 
591   m_td.peak_fitness = m_base_fitness;
592   m_td.peak_genome = m_base_genome;
593   m_td.site_count.Resize(m_base_genome.GetSize(), 0);
594   AggregateTwoStep(m_twostep_delete, m_td);
595 
596 
597   m_tip.peak_fitness = m_base_fitness;
598   m_tip.peak_genome = m_base_genome;
599   m_tip.site_count.Resize(m_base_genome.GetSize() + 1, 0);
600   AggregateTwoStep(m_insert_point, m_tip);
601 
602   m_tid.peak_fitness = m_base_fitness;
603   m_tid.peak_genome = m_base_genome;
604   m_tid.site_count.Resize(m_base_genome.GetSize() + 1, 0);
605   AggregateTwoStep(m_insert_delete, m_tid);
606 
607   m_tdp.peak_fitness = m_base_fitness;
608   m_tdp.peak_genome = m_base_genome;
609   m_tdp.site_count.Resize(m_base_genome.GetSize(), 0);
610   AggregateTwoStep(m_delete_point, m_tdp);
611 
612 
613   // Collect totals across all two step mutants
614   m_tt.total = m_tp.total + m_ti.total + m_td.total + m_tip.total + m_tid.total + m_tdp.total;
615   m_tt.total_fitness = m_tp.total_fitness + m_ti.total_fitness + m_td.total_fitness
616                        + m_tip.total_fitness + m_tid.total_fitness + m_tdp.total_fitness;
617   m_tt.total_sqr_fitness = m_tp.total_sqr_fitness + m_ti.total_sqr_fitness + m_td.total_sqr_fitness
618                            + m_tip.total_sqr_fitness + m_tid.total_sqr_fitness + m_tdp.total_sqr_fitness;
619 
620   const double pftp = m_tp.peak_fitness;
621   const double pfti = m_ti.peak_fitness;
622   const double pftd = m_td.peak_fitness;
623   const double pftip = m_tip.peak_fitness;
624   const double pftid = m_tid.peak_fitness;
625   const double pftdp = m_tdp.peak_fitness;
626 
627   if (pftp >= pfti && pftp >= pftd && pftp >= pftip && pftp >= pftid && pftp >= pftdp) {
628     m_tt.peak_fitness = m_tp.peak_fitness;
629     m_tt.peak_genome = m_tp.peak_genome;
630   } else if (pfti >= pftd && pfti >= pftip && pfti >= pftid && pfti >= pftdp) {
631     m_tt.peak_fitness = m_ti.peak_fitness;
632     m_tt.peak_genome = m_ti.peak_genome;
633   } else if (pftd >= pftip && pftd >= pftid && pftd >= pftdp) {
634     m_tt.peak_fitness = m_td.peak_fitness;
635     m_tt.peak_genome = m_td.peak_genome;
636   } else if (pftip >= pftid && pftip >= pftdp) {
637     m_tt.peak_fitness = m_tip.peak_fitness;
638     m_tt.peak_genome = m_tip.peak_genome;
639   } else if (pftid >= pftdp) {
640     m_tt.peak_fitness = m_tid.peak_fitness;
641     m_tt.peak_genome = m_tid.peak_genome;
642   } else {
643     m_tt.peak_fitness = m_tdp.peak_fitness;
644     m_tt.peak_genome = m_tdp.peak_genome;
645   }
646 
647   m_tt.pos = m_tp.pos + m_ti.pos + m_td.pos + m_tip.pos + m_tid.pos + m_tdp.pos;
648   m_tt.neg = m_tp.neg + m_ti.neg + m_td.neg + m_tip.neg + m_tid.neg + m_tdp.neg;
649   m_tt.neut = m_tp.neut + m_ti.neut + m_td.neut + m_tip.neut + m_tid.neut + m_tdp.neut;
650   m_tt.dead = m_tp.dead + m_ti.dead + m_td.dead + m_tip.dead + m_tid.dead + m_tdp.dead;
651   m_tt.size_pos = m_tp.size_pos + m_ti.size_pos + m_td.size_pos + m_tip.size_pos + m_tid.size_pos + m_tdp.size_pos;
652   m_tt.size_neg = m_tp.size_neg + m_ti.size_neg + m_td.size_neg + m_tip.size_neg + m_tid.size_neg + m_tdp.size_neg;
653 
654   m_tt.task_target = m_tp.task_target + m_ti.task_target + m_td.task_target
655                      + m_tip.task_target + m_tid.task_target + m_tdp.task_target;
656   m_tt.task_target_pos = m_tp.task_target_pos + m_ti.task_target_pos + m_td.task_target_pos
657                          + m_tip.task_target_pos + m_tid.task_target_pos + m_tdp.task_target_pos;
658   m_tt.task_target_neg = m_tp.task_target_neg + m_ti.task_target_neg + m_td.task_target_neg
659                          + m_tip.task_target_neg + m_tid.task_target_neg + m_tdp.task_target_neg;
660   m_tt.task_target_neut = m_tp.task_target_neut + m_ti.task_target_neut + m_td.task_target_neut
661                           + m_tip.task_target_neut + m_tid.task_target_neut + m_tdp.task_target_neut;
662   m_tt.task_target_dead = m_tp.task_target_dead + m_ti.task_target_dead + m_td.task_target_dead
663                           + m_tip.task_target_dead + m_tid.task_target_dead + m_tdp.task_target_dead;
664   m_tt.task_total = m_tp.task_total + m_ti.task_total + m_td.task_total
665                     + m_tip.task_total + m_tid.task_total + m_tdp.task_total;
666   m_tt.task_knockout = m_tp.task_knockout + m_ti.task_knockout + m_td.task_knockout
667                        + m_tip.task_knockout + m_tid.task_knockout + m_tdp.task_knockout;
668 
669   m_tt.task_size_target = m_tp.task_size_target + m_ti.task_size_target + m_td.task_size_target
670                           + m_tip.task_size_target + m_tid.task_size_target + m_tdp.task_size_target;
671   m_tt.task_size_target_pos = m_tp.task_size_target_pos + m_ti.task_size_target_pos + m_td.task_size_target_pos
672                               + m_tip.task_size_target_pos + m_tid.task_size_target_pos + m_tdp.task_size_target_pos;
673   m_tt.task_size_target_neg = m_tp.task_size_target_neg + m_ti.task_size_target_neg + m_td.task_size_target_neg
674                               + m_tip.task_size_target_neg + m_tid.task_size_target_neg + m_tdp.task_size_target_neg;
675   m_tt.task_size_total = m_tp.task_size_total + m_ti.task_size_total + m_td.task_size_total
676                          + m_tip.task_size_total + m_tid.task_size_total + m_tdp.task_size_total;
677   m_tt.task_size_knockout = m_tp.task_size_knockout + m_ti.task_size_knockout + m_td.task_size_knockout
678                             + m_tip.task_size_knockout + m_tid.task_size_knockout + m_tdp.task_size_knockout;
679 
680   // Unlock data for reading
681   m_rwlock.WriteUnlock();
682 
683   // Cleanup state information
684   m_onestep_point.Resize(0);
685   m_onestep_insert.Resize(0);
686   m_onestep_delete.Resize(0);
687 
688   m_twostep_point.Resize(0);
689   m_twostep_insert.Resize(0);
690   m_twostep_delete.Resize(0);
691 
692   m_insert_point.Resize(0);
693   m_insert_delete.Resize(0);
694   m_delete_point.Resize(0);
695 
696   m_fitness_point.Resize(0, 0);
697   m_fitness_insert.Resize(0, 0);
698   m_fitness_delete.Resize(0, 0);
699 }
700 
AggregateOneStep(tArray<sStep> & steps,sOneStepAggregate & osa)701 void cMutationalNeighborhood::AggregateOneStep(tArray<sStep>& steps, sOneStepAggregate& osa)
702 {
703   for (int i = 0; i < steps.GetSize(); i++) {
704     sStep& odata = steps[i];
705     osa.total += odata.total;
706     osa.total_fitness += odata.total_fitness;
707     osa.total_sqr_fitness += odata.total_sqr_fitness;
708     osa.pos += odata.pos;
709     osa.neg += odata.neg;
710     osa.neut += odata.neut;
711     osa.dead += odata.dead;
712     osa.size_pos += odata.size_pos;
713     osa.size_neg += odata.size_neg;
714 
715     if (odata.peak_fitness > osa.peak_fitness) {
716       osa.peak_genome = odata.peak_genome;
717       osa.peak_fitness = odata.peak_fitness;
718     }
719 
720 
721     for (int j = 0; j < osa.site_count.GetSize(); j++) {
722       osa.site_count[j] += odata.site_count[j];
723     }
724 
725     osa.task_target += odata.task_target;
726     osa.task_total += odata.task_total;
727     osa.task_knockout += odata.task_knockout;
728 
729     osa.task_size_target += odata.task_size_target;
730     osa.task_size_total += odata.task_size_total;
731     osa.task_size_knockout += odata.task_size_knockout;
732   }
733 
734   const double max_ent = log(static_cast<double>(m_inst_set.GetSize()));
735   for (int i = 0; i < m_base_genome.GetSize(); i++) {
736     // Per-site entropy is the log of the number of legal states for that
737     // site.  Add one to account for the unmutated state.
738     osa.total_entropy += log(static_cast<double>(osa.site_count[i] + 1)) / max_ent;
739   }
740   osa.complexity = m_base_genome.GetSize() - osa.total_entropy;
741 }
742 
743 
AggregateTwoStep(tArray<sTwoStep> & steps,sTwoStepAggregate & tsa)744 void cMutationalNeighborhood::AggregateTwoStep(tArray<sTwoStep>& steps, sTwoStepAggregate& tsa)
745 {
746   sPendFit* pend = NULL;
747 
748   for (int i = 0; i < steps.GetSize(); i++) {
749     sTwoStep& tdata = steps[i];
750     tsa.total += tdata.total;
751     tsa.total_fitness += tdata.total_fitness;
752     tsa.total_sqr_fitness += tdata.total_sqr_fitness;
753     tsa.pos += tdata.pos;
754     tsa.neg += tdata.neg;
755     tsa.neut += tdata.neut;
756     tsa.dead += tdata.dead;
757     tsa.size_pos += tdata.size_pos;
758     tsa.size_neg += tdata.size_neg;
759 
760     if (tdata.peak_fitness > tsa.peak_fitness) {
761       tsa.peak_genome = tdata.peak_genome;
762       tsa.peak_fitness = tdata.peak_fitness;
763     }
764 
765 
766     for (int j = 0; j < tsa.site_count.GetSize(); j++) {
767       tsa.site_count[j] += tdata.site_count[j];
768     }
769 
770     tsa.task_target += tdata.task_target;
771     tsa.task_total += tdata.task_total;
772     tsa.task_knockout += tdata.task_knockout;
773 
774     tsa.task_size_target += tdata.task_size_target;
775     tsa.task_size_total += tdata.task_size_total;
776     tsa.task_size_knockout += tdata.task_size_knockout;
777 
778     while ((pend = tdata.pending.Pop())) {
779       double fitness = pend->GetFitness();
780 
781       if (fitness == 0.0) {
782         tsa.task_target_dead++;
783       } else if (fitness < m_neut_min) {
784         tsa.task_target_neg++;
785         tsa.task_size_target_neg += fitness;
786       } else if (fitness <= m_neut_max) {
787         tsa.task_target_neut++;
788       } else {
789         tsa.task_target_pos++;
790         tsa.task_size_target_pos += fitness;
791       }
792 
793       delete pend;
794     }
795   }
796 
797   const double max_ent = log(static_cast<double>(m_inst_set.GetSize()));
798   for (int i = 0; i < m_base_genome.GetSize(); i++) {
799     // Per-site entropy is the log of the number of legal states for that
800     // site.  Add one to account for the unmutated state.
801     tsa.total_entropy += log(static_cast<double>(tsa.site_count[i] + 1)) / max_ent;
802   }
803   tsa.complexity = m_base_genome.GetSize() - tsa.total_entropy;
804 
805 }
806 
807 
PrintStats(cDataFile & df,int update) const808 void cMutationalNeighborhood::PrintStats(cDataFile& df, int update) const
809 {
810   df.Write(update, "Update/Tree Depth");
811 
812   df.Write(GetTargetTask(), "Target Task");
813 
814   df.Write(GetBaseFitness(), "Base Fitness");
815   df.Write(GetBaseMerit(), "Base Merit");
816   df.Write(GetBaseGestation(), "Base Gestation");
817   df.Write(GetBaseGenome().GetSize(), "Base Genome Length");
818   df.Write(GetBaseTargetTask(), "Base Performs Target Task");
819 
820   df.Write(Get1SAggregateTotal(), "Total 1-Step Mutants");
821   df.Write(Get1SAggregateProbBeneficial(), "1-Step Probability Beneficial");
822   df.Write(Get1SAggregateProbDeleterious(), "1-Step Probability Deleterious");
823   df.Write(Get1SAggregateProbNeutral(), "1-Step Probability Neutral");
824   df.Write(Get1SAggregateProbLethal(), "1-Step Probability Lethal");
825   df.Write(Get1SAggregateAverageSizeBeneficial(), "1-Step Average Beneficial Size");
826   df.Write(Get1SAggregateAverageSizeDeleterious(), "1-Step Average Deleterious Size");
827   df.Write(Get1SAggregatePeakFitness(), "1-Step Peak Fitness");
828   df.Write(Get1SAggregateAverageFitness(), "1-Step Average Fitness");
829   df.Write(Get1SAggregateAverageSqrFitness(), "1-Step Average Square Fitness");
830 //  df.Write(Get1SAggregateTotalEntropy(), "1-Step Total Entropy");
831 //  df.Write(Get1SAggregateComplexity(), "1-Step Total Complexity");
832   df.Write(Get1SAggregateTargetTask(), "1-Step Confers Target Task");
833   df.Write(Get1SAggregateProbTargetTask(), "1-Step Probability Confers Target Task");
834   df.Write(Get1SAggregateAverageSizeTargetTask(), "1-Step Average Size of Target Task Conferral");
835   df.Write(Get1SAggregateTask(), "1-Step Confers Any Task");
836   df.Write(Get1SAggregateProbTask(), "1-Step Probability Confers Any Task");
837   df.Write(Get1SAggregateAverageSizeTask(), "1-Step Average Size of Any Task Conferral");
838   df.Write(Get1SAggregateKnockout(), "1-Step Knockout Task");
839   df.Write(Get1SAggregateProbKnockout(), "1-Step Probability Knockout Task");
840   df.Write(Get1SAggregateAverageSizeKnockout(), "1-Step Average Size of Task Knockout");
841 
842   df.Write(Get1SPointTotal(), "Total 1-Step Point Mutants");
843   df.Write(Get1SPointProbBeneficial(), "1-Step Point Probability Beneficial");
844   df.Write(Get1SPointProbDeleterious(), "1-Step Point Probability Deleterious");
845   df.Write(Get1SPointProbNeutral(), "1-Step Point Probability Neutral");
846   df.Write(Get1SPointProbLethal(), "1-Step Point Probability Lethal");
847   df.Write(Get1SPointAverageSizeBeneficial(), "1-Step Point Average Beneficial Size");
848   df.Write(Get1SPointAverageSizeDeleterious(), "1-Step Point Average Deleterious Size");
849   df.Write(Get1SPointPeakFitness(), "1-Step Point Peak Fitness");
850   df.Write(Get1SPointAverageFitness(), "1-Step Point Average Fitness");
851   df.Write(Get1SPointAverageSqrFitness(), "1-Step Point Average Square Fitness");
852   df.Write(Get1SPointTotalEntropy(), "1-Step Point Total Entropy");
853   df.Write(Get1SPointComplexity(), "1-Step Point Total Complexity");
854   df.Write(Get1SPointTargetTask(), "1-Step Point Confers Target Task");
855   df.Write(Get1SPointProbTargetTask(), "1-Step Point Probability Confers Target Task");
856   df.Write(Get1SPointAverageSizeTargetTask(), "1-Step Point Average Size of Target Task Conferral");
857   df.Write(Get1SPointTask(), "1-Step Point Confers Any Task");
858   df.Write(Get1SPointProbTask(), "1-Step Point Probability Confers Any Task");
859   df.Write(Get1SPointAverageSizeTask(), "1-Step Point Average Size of Any Task Conferral");
860   df.Write(Get1SPointKnockout(), "1-Step Point Knockout Task");
861   df.Write(Get1SPointProbKnockout(), "1-Step Point Probability Knockout Task");
862   df.Write(Get1SPointAverageSizeKnockout(), "1-Step Point Average Size of Task Knockout");
863 
864   df.Write(Get1SInsertTotal(), "Total 1-Step Insert Mutants");
865   df.Write(Get1SInsertProbBeneficial(), "1-Step Insert Probability Beneficial");
866   df.Write(Get1SInsertProbDeleterious(), "1-Step Insert Probability Deleterious");
867   df.Write(Get1SInsertProbNeutral(), "1-Step Insert Probability Neutral");
868   df.Write(Get1SInsertProbLethal(), "1-Step Insert Probability Lethal");
869   df.Write(Get1SInsertAverageSizeBeneficial(), "1-Step Insert Average Beneficial Size");
870   df.Write(Get1SInsertAverageSizeDeleterious(), "1-Step Insert Average Deleterious Size");
871   df.Write(Get1SInsertPeakFitness(), "1-Step Insert Peak Fitness");
872   df.Write(Get1SInsertAverageFitness(), "1-Step Insert Average Fitness");
873   df.Write(Get1SInsertAverageSqrFitness(), "1-Step Insert Average Square Fitness");
874   df.Write(Get1SInsertTotalEntropy(), "1-Step Insert Total Entropy");
875   df.Write(Get1SInsertComplexity(), "1-Step Insert Total Complexity");
876   df.Write(Get1SInsertTargetTask(), "1-Step Insert Confers Target Task");
877   df.Write(Get1SInsertProbTargetTask(), "1-Step Insert Probability Confers Target Task");
878   df.Write(Get1SInsertAverageSizeTargetTask(), "1-Step Insert Average Size of Target Task Conferral");
879   df.Write(Get1SInsertTask(), "1-Step Insert Confers Any Task");
880   df.Write(Get1SInsertProbTask(), "1-Step Insert Probability Confers Any Task");
881   df.Write(Get1SInsertAverageSizeTask(), "1-Step Insert Average Size of Any Task Conferral");
882   df.Write(Get1SInsertKnockout(), "1-Step Insert Knockout Task");
883   df.Write(Get1SInsertProbKnockout(), "1-Step Insert Probability Knockout Task");
884   df.Write(Get1SInsertAverageSizeKnockout(), "1-Step Insert Average Size of Task Knockout");
885 
886   df.Write(Get1SDeleteTotal(), "Total 1-Step Delete Mutants");
887   df.Write(Get1SDeleteProbBeneficial(), "1-Step Delete Probability Beneficial");
888   df.Write(Get1SDeleteProbDeleterious(), "1-Step Delete Probability Deleterious");
889   df.Write(Get1SDeleteProbNeutral(), "1-Step Delete Probability Neutral");
890   df.Write(Get1SDeleteProbLethal(), "1-Step Delete Probability Lethal");
891   df.Write(Get1SDeleteAverageSizeBeneficial(), "1-Step Delete Average Beneficial Size");
892   df.Write(Get1SDeleteAverageSizeDeleterious(), "1-Step Delete Average Deleterious Size");
893   df.Write(Get1SDeletePeakFitness(), "1-Step Delete Peak Fitness");
894   df.Write(Get1SDeleteAverageFitness(), "1-Step Delete Average Fitness");
895   df.Write(Get1SDeleteAverageSqrFitness(), "1-Step Delete Average Square Fitness");
896   df.Write(Get1SDeleteTotalEntropy(), "1-Step Delete Total Entropy");
897   df.Write(Get1SDeleteComplexity(), "1-Step Delete Total Complexity");
898   df.Write(Get1SDeleteTargetTask(), "1-Step Delete Confers Target Task");
899   df.Write(Get1SDeleteProbTargetTask(), "1-Step Delete Probability Confers Target Task");
900   df.Write(Get1SDeleteAverageSizeTargetTask(), "1-Step Delete Average Size of Target Task Conferral");
901   df.Write(Get1SDeleteTask(), "1-Step Delete Confers Any Task");
902   df.Write(Get1SDeleteProbTask(), "1-Step Delete Probability Confers Any Task");
903   df.Write(Get1SDeleteAverageSizeTask(), "1-Step Delete Average Size of Any Task Conferral");
904   df.Write(Get1SDeleteKnockout(), "1-Step Delete Knockout Task");
905   df.Write(Get1SDeleteProbKnockout(), "1-Step Delete Probability Knockout Task");
906   df.Write(Get1SDeleteAverageSizeKnockout(), "1-Step Delete Average Size of Task Knockout");
907 
908   df.Write(Get2SAggregateTotal(), "Total 2-Step Mutants");
909   df.Write(Get2SAggregateProbBeneficial(), "2-Step Probability Beneficial");
910   df.Write(Get2SAggregateProbDeleterious(), "2-Step Probability Deleterious");
911   df.Write(Get2SAggregateProbNeutral(), "2-Step Probability Neutral");
912   df.Write(Get2SAggregateProbLethal(), "2-Step Probability Lethal");
913   df.Write(Get2SAggregateAverageSizeBeneficial(), "2-Step Average Beneficial Size");
914   df.Write(Get2SAggregateAverageSizeDeleterious(), "2-Step Average Deleterious Size");
915   df.Write(Get2SAggregatePeakFitness(), "2-Step Peak Fitness");
916   df.Write(Get2SAggregateAverageFitness(), "2-Step Average Fitness");
917   df.Write(Get2SAggregateAverageSqrFitness(), "2-Step Average Square Fitness");
918 //  df.Write(Get2SAggregateTotalEntropy(), "2-Step Total Entropy");
919 //  df.Write(Get2SAggregateComplexity(), "2-Step Total Complexity");
920   df.Write(Get2SAggregateTargetTask(), "2-Step Confers Target Task");
921   df.Write(Get2SAggregateProbTargetTask(), "2-Step Probability Confers Target Task");
922   df.Write(Get2SAggregateAverageSizeTargetTask(), "2-Step Average Size of Target Task Conferral");
923   df.Write(Get2SAggregateTargetTaskBeneficial(), "2-Step Confers Target - Previous Beneficial");
924   df.Write(Get2SAggregateProbTargetTaskBeneficial(), "2-Step Prob. Confers Target - Previous Beneficial");
925   df.Write(Get2SAggregateAverageSizeTargetTaskBeneficial(), "2-Step Ave. Size of Previous Beneficial in Target Conferral");
926   df.Write(Get2SAggregateTargetTaskDeleterious(), "2-Step Confers Target - Previous Deleterious");
927   df.Write(Get2SAggregateProbTargetTaskDeleterious(), "2-Step Prob. Confers Target - Previous Deleterious");
928   df.Write(Get2SAggregateAverageSizeTargetTaskDeleterious(), "2-Step Ave. Size of Previous Deleterious in Target Conferral");
929   df.Write(Get2SAggregateTargetTaskNeutral(), "2-Step Confers Target - Previous Neutral");
930   df.Write(Get2SAggregateProbTargetTaskNeutral(), "2-Step Prob. Confers Target - Previous Neutral");
931   df.Write(Get2SAggregateTargetTaskLethal(), "2-Step Confers Target - Previous Lethal");
932   df.Write(Get2SAggregateProbTargetTaskLethal(), "2-Step Prob. Confers Target - Previous Lethal");
933   df.Write(Get2SAggregateTask(), "2-Step Confers Any Task");
934   df.Write(Get2SAggregateProbTask(), "2-Step Probability Confers Any Task");
935   df.Write(Get2SAggregateAverageSizeTask(), "2-Step Average Size of Any Task Conferral");
936   df.Write(Get2SAggregateKnockout(), "2-Step Knockout Task");
937   df.Write(Get2SAggregateProbKnockout(), "2-Step Probability Knockout Task");
938   df.Write(Get2SAggregateAverageSizeKnockout(), "2-Step Average Size of Task Knockout");
939 
940   df.Write(Get2SPointTotal(), "Total 2-Step Point Mutants");
941   df.Write(Get2SPointProbBeneficial(), "2-Step Point Probability Beneficial");
942   df.Write(Get2SPointProbDeleterious(), "2-Step Point Probability Deleterious");
943   df.Write(Get2SPointProbNeutral(), "2-Step Point Probability Neutral");
944   df.Write(Get2SPointProbLethal(), "2-Step Point Probability Lethal");
945   df.Write(Get2SPointAverageSizeBeneficial(), "2-Step Point Average Beneficial Size");
946   df.Write(Get2SPointAverageSizeDeleterious(), "2-Step Point Average Deleterious Size");
947   df.Write(Get2SPointPeakFitness(), "2-Step Point Peak Fitness");
948   df.Write(Get2SPointAverageFitness(), "2-Step Point Average Fitness");
949   df.Write(Get2SPointAverageSqrFitness(), "2-Step Point Average Square Fitness");
950   df.Write(Get2SPointTotalEntropy(), "2-Step Point Total Entropy");
951   df.Write(Get2SPointComplexity(), "2-Step Point Total Complexity");
952   df.Write(Get2SPointTargetTask(), "2-Step Point Confers Target Task");
953   df.Write(Get2SPointProbTargetTask(), "2-Step Point Probability Confers Target Task");
954   df.Write(Get2SPointAverageSizeTargetTask(), "2-Step Point Average Size of Target Task Conferral");
955   df.Write(Get2SPointTargetTaskBeneficial(), "2-Step Point Confers Target - Previous Beneficial");
956   df.Write(Get2SPointProbTargetTaskBeneficial(), "2-Step Point Prob. Confers Target - Previous Beneficial");
957   df.Write(Get2SPointAverageSizeTargetTaskBeneficial(), "2-Step Point Ave. Size of Previous Beneficial in Target Conferral");
958   df.Write(Get2SPointTargetTaskDeleterious(), "2-Step Point Confers Target - Previous Deleterious");
959   df.Write(Get2SPointProbTargetTaskDeleterious(), "2-Step Point Prob. Confers Target - Previous Deleterious");
960   df.Write(Get2SPointAverageSizeTargetTaskDeleterious(), "2-Step Point Ave. Size of Previous Deleterious in Target Conferral");
961   df.Write(Get2SPointTargetTaskNeutral(), "2-Step Point Confers Target - Previous Neutral");
962   df.Write(Get2SPointProbTargetTaskNeutral(), "2-Step Point Prob. Confers Target - Previous Neutral");
963   df.Write(Get2SPointTargetTaskLethal(), "2-Step Point Confers Target - Previous Lethal");
964   df.Write(Get2SPointProbTargetTaskLethal(), "2-Step Point Prob. Confers Target - Previous Lethal");
965   df.Write(Get2SPointTask(), "2-Step Point Confers Any Task");
966   df.Write(Get2SPointProbTask(), "2-Step Point Probability Confers Any Task");
967   df.Write(Get2SPointAverageSizeTask(), "2-Step Point Average Size of Any Task Conferral");
968   df.Write(Get2SPointKnockout(), "2-Step Point Knockout Task");
969   df.Write(Get2SPointProbKnockout(), "2-Step Point Probability Knockout Task");
970   df.Write(Get2SPointAverageSizeKnockout(), "2-Step Point Average Size of Task Knockout");
971 
972   df.Write(Get2SInsertTotal(), "Total 2-Step Insert Mutants");
973   df.Write(Get2SInsertProbBeneficial(), "2-Step Insert Probability Beneficial");
974   df.Write(Get2SInsertProbDeleterious(), "2-Step Insert Probability Deleterious");
975   df.Write(Get2SInsertProbNeutral(), "2-Step Insert Probability Neutral");
976   df.Write(Get2SInsertProbLethal(), "2-Step Insert Probability Lethal");
977   df.Write(Get2SInsertAverageSizeBeneficial(), "2-Step Insert Average Beneficial Size");
978   df.Write(Get2SInsertAverageSizeDeleterious(), "2-Step Insert Average Deleterious Size");
979   df.Write(Get2SInsertPeakFitness(), "2-Step Insert Peak Fitness");
980   df.Write(Get2SInsertAverageFitness(), "2-Step Insert Average Fitness");
981   df.Write(Get2SInsertAverageSqrFitness(), "2-Step Insert Average Square Fitness");
982   df.Write(Get2SInsertTotalEntropy(), "2-Step Insert Total Entropy");
983   df.Write(Get2SInsertComplexity(), "2-Step Insert Total Complexity");
984   df.Write(Get2SInsertTargetTask(), "2-Step Insert Confers Target Task");
985   df.Write(Get2SInsertProbTargetTask(), "2-Step Insert Probability Confers Target Task");
986   df.Write(Get2SInsertAverageSizeTargetTask(), "2-Step Insert Average Size of Target Task Conferral");
987   df.Write(Get2SInsertTargetTaskBeneficial(), "2-Step Insert Confers Target - Previous Beneficial");
988   df.Write(Get2SInsertProbTargetTaskBeneficial(), "2-Step Insert Prob. Confers Target - Previous Beneficial");
989   df.Write(Get2SInsertAverageSizeTargetTaskBeneficial(), "2-Step Insert Ave. Size of Previous Beneficial in Target Conferral");
990   df.Write(Get2SInsertTargetTaskDeleterious(), "2-Step Insert Confers Target - Previous Deleterious");
991   df.Write(Get2SInsertProbTargetTaskDeleterious(), "2-Step Insert Prob. Confers Target - Previous Deleterious");
992   df.Write(Get2SInsertAverageSizeTargetTaskDeleterious(), "2-Step Insert Ave. Size of Previous Deleterious in Target Conferral");
993   df.Write(Get2SInsertTargetTaskNeutral(), "2-Step Insert Confers Target - Previous Neutral");
994   df.Write(Get2SInsertProbTargetTaskNeutral(), "2-Step Insert Prob. Confers Target - Previous Neutral");
995   df.Write(Get2SInsertTargetTaskLethal(), "2-Step Insert Confers Target - Previous Lethal");
996   df.Write(Get2SInsertProbTargetTaskLethal(), "2-Step Insert Prob. Confers Target - Previous Lethal");
997   df.Write(Get2SInsertTask(), "2-Step Insert Confers Any Task");
998   df.Write(Get2SInsertProbTask(), "2-Step Insert Probability Confers Any Task");
999   df.Write(Get2SInsertAverageSizeTask(), "2-Step Insert Average Size of Any Task Conferral");
1000   df.Write(Get2SInsertKnockout(), "2-Step Insert Knockout Task");
1001   df.Write(Get2SInsertProbKnockout(), "2-Step Insert Probability Knockout Task");
1002   df.Write(Get2SInsertAverageSizeKnockout(), "2-Step Insert Average Size of Task Knockout");
1003 
1004   df.Write(Get2SDeleteTotal(), "Total 2-Step Delete Mutants");
1005   df.Write(Get2SDeleteProbBeneficial(), "2-Step Delete Probability Beneficial");
1006   df.Write(Get2SDeleteProbDeleterious(), "2-Step Delete Probability Deleterious");
1007   df.Write(Get2SDeleteProbNeutral(), "2-Step Delete Probability Neutral");
1008   df.Write(Get2SDeleteProbLethal(), "2-Step Delete Probability Lethal");
1009   df.Write(Get2SDeleteAverageSizeBeneficial(), "2-Step Delete Average Beneficial Size");
1010   df.Write(Get2SDeleteAverageSizeDeleterious(), "2-Step Delete Average Deleterious Size");
1011   df.Write(Get2SDeletePeakFitness(), "2-Step Delete Peak Fitness");
1012   df.Write(Get2SDeleteAverageFitness(), "2-Step Delete Average Fitness");
1013   df.Write(Get2SDeleteAverageSqrFitness(), "2-Step Delete Average Square Fitness");
1014   df.Write(Get2SDeleteTotalEntropy(), "2-Step Delete Total Entropy");
1015   df.Write(Get2SDeleteComplexity(), "2-Step Delete Total Complexity");
1016   df.Write(Get2SDeleteTargetTask(), "2-Step Delete Confers Target Task");
1017   df.Write(Get2SDeleteProbTargetTask(), "2-Step Delete Probability Confers Target Task");
1018   df.Write(Get2SDeleteAverageSizeTargetTask(), "2-Step Delete Average Size of Target Task Conferral");
1019   df.Write(Get2SDeleteTargetTaskBeneficial(), "2-Step Delete Confers Target - Previous Beneficial");
1020   df.Write(Get2SDeleteProbTargetTaskBeneficial(), "2-Step Delete Prob. Confers Target - Previous Beneficial");
1021   df.Write(Get2SDeleteAverageSizeTargetTaskBeneficial(), "2-Step Delete Ave. Size of Previous Beneficial in Target Conferral");
1022   df.Write(Get2SDeleteTargetTaskDeleterious(), "2-Step Delete Confers Target - Previous Deleterious");
1023   df.Write(Get2SDeleteProbTargetTaskDeleterious(), "2-Step Delete Prob. Confers Target - Previous Deleterious");
1024   df.Write(Get2SDeleteAverageSizeTargetTaskDeleterious(), "2-Step Delete Ave. Size of Previous Deleterious in Target Conferral");
1025   df.Write(Get2SDeleteTargetTaskNeutral(), "2-Step Delete Confers Target - Previous Neutral");
1026   df.Write(Get2SDeleteProbTargetTaskNeutral(), "2-Step Delete Prob. Confers Target - Previous Neutral");
1027   df.Write(Get2SDeleteTargetTaskLethal(), "2-Step Delete Confers Target - Previous Lethal");
1028   df.Write(Get2SDeleteProbTargetTaskLethal(), "2-Step Delete Prob. Confers Target - Previous Lethal");
1029   df.Write(Get2SDeleteTask(), "2-Step Delete Confers Any Task");
1030   df.Write(Get2SDeleteProbTask(), "2-Step Delete Probability Confers Any Task");
1031   df.Write(Get2SDeleteAverageSizeTask(), "2-Step Delete Average Size of Any Task Conferral");
1032   df.Write(Get2SDeleteKnockout(), "2-Step Delete Knockout Task");
1033   df.Write(Get2SDeleteProbKnockout(), "2-Step Delete Probability Knockout Task");
1034   df.Write(Get2SDeleteAverageSizeKnockout(), "2-Step Delete Average Size of Task Knockout");
1035 
1036   df.Write(GetInsPntTotal(), "Total Insert/Point Mutants");
1037   df.Write(GetInsPntProbBeneficial(), "Insert/Point Probability Beneficial");
1038   df.Write(GetInsPntProbDeleterious(), "Insert/Point Probability Deleterious");
1039   df.Write(GetInsPntProbNeutral(), "Insert/Point Probability Neutral");
1040   df.Write(GetInsPntProbLethal(), "Insert/Point Probability Lethal");
1041   df.Write(GetInsPntAverageSizeBeneficial(), "Insert/Point Average Beneficial Size");
1042   df.Write(GetInsPntAverageSizeDeleterious(), "Insert/Point Average Deleterious Size");
1043   df.Write(GetInsPntPeakFitness(), "Insert/Point Peak Fitness");
1044   df.Write(GetInsPntAverageFitness(), "Insert/Point Average Fitness");
1045   df.Write(GetInsPntAverageSqrFitness(), "Insert/Point Average Square Fitness");
1046   df.Write(GetInsPntTotalEntropy(), "Insert/Point Total Entropy");
1047   df.Write(GetInsPntComplexity(), "Insert/Point Total Complexity");
1048   df.Write(GetInsPntTargetTask(), "Insert/Point Confers Target Task");
1049   df.Write(GetInsPntProbTargetTask(), "Insert/Point Probability Confers Target Task");
1050   df.Write(GetInsPntAverageSizeTargetTask(), "Insert/Point Average Size of Target Task Conferral");
1051   df.Write(GetInsPntTargetTaskBeneficial(), "Insert/Point Confers Target - Previous Beneficial");
1052   df.Write(GetInsPntProbTargetTaskBeneficial(), "Insert/Point Prob. Confers Target - Previous Beneficial");
1053   df.Write(GetInsPntAverageSizeTargetTaskBeneficial(), "Insert/Point Ave. Size of Previous Beneficial in Target Conferral");
1054   df.Write(GetInsPntTargetTaskDeleterious(), "Insert/Point Confers Target - Previous Deleterious");
1055   df.Write(GetInsPntProbTargetTaskDeleterious(), "Insert/Point Prob. Confers Target - Previous Deleterious");
1056   df.Write(GetInsPntAverageSizeTargetTaskDeleterious(), "Insert/Point Ave. Size of Previous Deleterious in Target Conferral");
1057   df.Write(GetInsPntTargetTaskNeutral(), "Insert/Point Confers Target - Previous Neutral");
1058   df.Write(GetInsPntProbTargetTaskNeutral(), "Insert/Point Prob. Confers Target - Previous Neutral");
1059   df.Write(GetInsPntTargetTaskLethal(), "Insert/Point Confers Target - Previous Lethal");
1060   df.Write(GetInsPntProbTargetTaskLethal(), "Insert/Point Prob. Confers Target - Previous Lethal");
1061   df.Write(GetInsPntTask(), "Insert/Point Confers Any Task");
1062   df.Write(GetInsPntProbTask(), "Insert/Point Probability Confers Any Task");
1063   df.Write(GetInsPntAverageSizeTask(), "Insert/Point Average Size of Any Task Conferral");
1064   df.Write(GetInsPntKnockout(), "Insert/Point Knockout Task");
1065   df.Write(GetInsPntProbKnockout(), "Insert/Point Probability Knockout Task");
1066   df.Write(GetInsPntAverageSizeKnockout(), "Insert/Point Average Size of Task Knockout");
1067 
1068   df.Write(GetInsDelTotal(), "Total Insert/Delete Mutants");
1069   df.Write(GetInsDelProbBeneficial(), "Insert/Delete Probability Beneficial");
1070   df.Write(GetInsDelProbDeleterious(), "Insert/Delete Probability Deleterious");
1071   df.Write(GetInsDelProbNeutral(), "Insert/Delete Probability Neutral");
1072   df.Write(GetInsDelProbLethal(), "Insert/Delete Probability Lethal");
1073   df.Write(GetInsDelAverageSizeBeneficial(), "Insert/Delete Average Beneficial Size");
1074   df.Write(GetInsDelAverageSizeDeleterious(), "Insert/Delete Average Deleterious Size");
1075   df.Write(GetInsDelPeakFitness(), "Insert/Delete Peak Fitness");
1076   df.Write(GetInsDelAverageFitness(), "Insert/Delete Average Fitness");
1077   df.Write(GetInsDelAverageSqrFitness(), "Insert/Delete Average Square Fitness");
1078   df.Write(GetInsDelTotalEntropy(), "Insert/Delete Total Entropy");
1079   df.Write(GetInsDelComplexity(), "Insert/Delete Total Complexity");
1080   df.Write(GetInsDelTargetTask(), "Insert/Delete Confers Target Task");
1081   df.Write(GetInsDelProbTargetTask(), "Insert/Delete Probability Confers Target Task");
1082   df.Write(GetInsDelAverageSizeTargetTask(), "Insert/Delete Average Size of Target Task Conferral");
1083   df.Write(GetInsDelTargetTaskBeneficial(), "Insert/Delete Confers Target - Previous Beneficial");
1084   df.Write(GetInsDelProbTargetTaskBeneficial(), "Insert/Delete Prob. Confers Target - Previous Beneficial");
1085   df.Write(GetInsDelAverageSizeTargetTaskBeneficial(), "Insert/Delete Ave. Size of Previous Beneficial in Target Conferral");
1086   df.Write(GetInsDelTargetTaskDeleterious(), "Insert/Delete Confers Target - Previous Deleterious");
1087   df.Write(GetInsDelProbTargetTaskDeleterious(), "Insert/Delete Prob. Confers Target - Previous Deleterious");
1088   df.Write(GetInsDelAverageSizeTargetTaskDeleterious(), "Insert/Delete Ave. Size of Previous Deleterious in Target Conferral");
1089   df.Write(GetInsDelTargetTaskNeutral(), "Insert/Delete Confers Target - Previous Neutral");
1090   df.Write(GetInsDelProbTargetTaskNeutral(), "Insert/Delete Prob. Confers Target - Previous Neutral");
1091   df.Write(GetInsDelTargetTaskLethal(), "Insert/Delete Confers Target - Previous Lethal");
1092   df.Write(GetInsDelProbTargetTaskLethal(), "Insert/Delete Prob. Confers Target - Previous Lethal");
1093   df.Write(GetInsDelTask(), "Insert/Delete Confers Any Task");
1094   df.Write(GetInsDelProbTask(), "Insert/Delete Probability Confers Any Task");
1095   df.Write(GetInsDelAverageSizeTask(), "Insert/Delete Average Size of Any Task Conferral");
1096   df.Write(GetInsDelKnockout(), "Insert/Delete Knockout Task");
1097   df.Write(GetInsDelProbKnockout(), "Insert/Delete Probability Knockout Task");
1098   df.Write(GetInsDelAverageSizeKnockout(), "Insert/Delete Average Size of Task Knockout");
1099 
1100   df.Write(GetDelPntTotal(), "Total Delete/Point Mutants");
1101   df.Write(GetDelPntProbBeneficial(), "Delete/Point Probability Beneficial");
1102   df.Write(GetDelPntProbDeleterious(), "Delete/Point Probability Deleterious");
1103   df.Write(GetDelPntProbNeutral(), "Delete/Point Probability Neutral");
1104   df.Write(GetDelPntProbLethal(), "Delete/Point Probability Lethal");
1105   df.Write(GetDelPntAverageSizeBeneficial(), "Delete/Point Average Beneficial Size");
1106   df.Write(GetDelPntAverageSizeDeleterious(), "Delete/Point Average Deleterious Size");
1107   df.Write(GetDelPntPeakFitness(), "Delete/Point Peak Fitness");
1108   df.Write(GetDelPntAverageFitness(), "Delete/Point Average Fitness");
1109   df.Write(GetDelPntAverageSqrFitness(), "Delete/Point Average Square Fitness");
1110   df.Write(GetDelPntTotalEntropy(), "Delete/Point Total Entropy");
1111   df.Write(GetDelPntComplexity(), "Delete/Point Total Complexity");
1112   df.Write(GetDelPntTargetTask(), "Delete/Point Confers Target Task");
1113   df.Write(GetDelPntProbTargetTask(), "Delete/Point Probability Confers Target Task");
1114   df.Write(GetDelPntAverageSizeTargetTask(), "Delete/Point Average Size of Target Task Conferral");
1115   df.Write(GetDelPntTargetTaskBeneficial(), "Delete/Point Confers Target - Previous Beneficial");
1116   df.Write(GetDelPntProbTargetTaskBeneficial(), "Delete/Point Prob. Confers Target - Previous Beneficial");
1117   df.Write(GetDelPntAverageSizeTargetTaskBeneficial(), "Delete/Point Ave. Size of Previous Beneficial in Target Conferral");
1118   df.Write(GetDelPntTargetTaskDeleterious(), "Delete/Point Confers Target - Previous Deleterious");
1119   df.Write(GetDelPntProbTargetTaskDeleterious(), "Delete/Point Prob. Confers Target - Previous Deleterious");
1120   df.Write(GetDelPntAverageSizeTargetTaskDeleterious(), "Delete/Point Ave. Size of Previous Deleterious in Target Conferral");
1121   df.Write(GetDelPntTargetTaskNeutral(), "Delete/Point Confers Target - Previous Neutral");
1122   df.Write(GetDelPntProbTargetTaskNeutral(), "Delete/Point Prob. Confers Target - Previous Neutral");
1123   df.Write(GetDelPntTargetTaskLethal(), "Delete/Point Confers Target - Previous Lethal");
1124   df.Write(GetDelPntProbTargetTaskLethal(), "Delete/Point Prob. Confers Target - Previous Lethal");
1125   df.Write(GetDelPntTask(), "Delete/Point Confers Any Task");
1126   df.Write(GetDelPntProbTask(), "Delete/Point Probability Confers Any Task");
1127   df.Write(GetDelPntAverageSizeTask(), "Delete/Point Average Size of Any Task Conferral");
1128   df.Write(GetDelPntKnockout(), "Delete/Point Knockout Task");
1129   df.Write(GetDelPntProbKnockout(), "Delete/Point Probability Knockout Task");
1130   df.Write(GetDelPntAverageSizeKnockout(), "Delete/Point Average Size of Task Knockout");
1131 
1132   df.Endl();
1133 }
1134