1 /*
2  *  cPhenotype.cc
3  *  Avida
4  *
5  *  Called "phenotype.cc" prior to 12/5/05.
6  *  Copyright 1999-2011 Michigan State University. All rights reserved.
7  *  Copyright 1993-2003 California Institute of Technology.
8  *
9  *
10  *  This file is part of Avida.
11  *
12  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14  *
15  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
19  *  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include "cPhenotype.h"
24 #include "cContextPhenotype.h"
25 #include "cEnvironment.h"
26 #include "cDeme.h"
27 #include "cOrganism.h"
28 #include "cReactionResult.h"
29 #include "cTaskState.h"
30 #include "cWorld.h"
31 #include "tList.h"
32 
33 #include <fstream>
34 
35 using namespace std;
36 
37 
cPhenotype(cWorld * world,int parent_generation,int num_nops)38 cPhenotype::cPhenotype(cWorld* world, int parent_generation, int num_nops)
39 : m_world(world)
40 , initialized(false)
41 , energy_store(0.0)
42 , cur_task_count(m_world->GetEnvironment().GetNumTasks())
43 , cur_para_tasks(m_world->GetEnvironment().GetNumTasks())
44 , cur_host_tasks(m_world->GetEnvironment().GetNumTasks())
45 , cur_internal_task_count(m_world->GetEnvironment().GetNumTasks())
46 , eff_task_count(m_world->GetEnvironment().GetNumTasks())
47 , cur_task_quality(m_world->GetEnvironment().GetNumTasks())
48 , cur_task_value(m_world->GetEnvironment().GetNumTasks())
49 , cur_internal_task_quality(m_world->GetEnvironment().GetNumTasks())
50 , cur_rbins_total(m_world->GetEnvironment().GetResourceLib().GetSize())
51 , cur_rbins_avail(m_world->GetEnvironment().GetResourceLib().GetSize())
52 , cur_reaction_count(m_world->GetEnvironment().GetReactionLib().GetSize())
53 , first_reaction_cycles(m_world->GetEnvironment().GetReactionLib().GetSize())
54 , first_reaction_execs(m_world->GetEnvironment().GetReactionLib().GetSize())
55 , cur_stolen_reaction_count(m_world->GetEnvironment().GetReactionLib().GetSize())
56 , cur_reaction_add_reward(m_world->GetEnvironment().GetReactionLib().GetSize())
57 , cur_sense_count(m_world->GetStats().GetSenseSize())
58 , sensed_resources(m_world->GetEnvironment().GetResourceLib().GetSize())
59 , cur_task_time(m_world->GetEnvironment().GetNumTasks())   // Added for tracking time; WRE 03-18-07
60 , m_tolerance_immigrants()
61 , m_tolerance_offspring_own()
62 , m_tolerance_offspring_others()
63 , m_intolerances((m_world->GetConfig().TOLERANCE_VARIATIONS.Get() > 0) ? 1 : 3)
64 , mating_type(MATING_TYPE_JUVENILE)
65 , mate_preference(MATE_PREFERENCE_RANDOM)
66 , cur_mating_display_a(0)
67 , cur_mating_display_b(0)
68 , m_reaction_result(NULL)
69 , last_task_count(m_world->GetEnvironment().GetNumTasks())
70 , last_para_tasks(m_world->GetEnvironment().GetNumTasks())
71 , last_host_tasks(m_world->GetEnvironment().GetNumTasks())
72 , last_internal_task_count(m_world->GetEnvironment().GetNumTasks())
73 , last_task_quality(m_world->GetEnvironment().GetNumTasks())
74 , last_task_value(m_world->GetEnvironment().GetNumTasks())
75 , last_internal_task_quality(m_world->GetEnvironment().GetNumTasks())
76 , last_rbins_total(m_world->GetEnvironment().GetResourceLib().GetSize())
77 , last_rbins_avail(m_world->GetEnvironment().GetResourceLib().GetSize())
78 , last_collect_spec_counts()
79 , last_reaction_count(m_world->GetEnvironment().GetReactionLib().GetSize())
80 , last_reaction_add_reward(m_world->GetEnvironment().GetReactionLib().GetSize())
81 , last_sense_count(m_world->GetStats().GetSenseSize())
82 , last_mating_display_a(0)
83 , last_mating_display_b(0)
84 , generation(0)
85 , birth_cell_id(0)
86 , birth_group_id(0)
87 , birth_forager_type(-1)
88 , last_task_id(-1)
89 , num_new_unique_reactions(0)
90 , res_consumed(0)
91 , is_germ_cell(m_world->GetConfig().DEMES_ORGS_START_IN_GERM.Get())
92 , last_task_time(0)
93 
94 {
95   if (parent_generation >= 0) {
96     generation = parent_generation;
97     if (m_world->GetConfig().GENERATION_INC_METHOD.Get() != GENERATION_INC_BOTH) generation++;
98   }
99 
100   double num_resources = m_world->GetEnvironment().GetResourceLib().GetSize();
101   if (num_resources <= 0 || num_nops <= 0) return;
102   double most_nops_needed = ceil(log(num_resources) / log((double)num_nops));
103   cur_collect_spec_counts.Resize(int((pow((double)num_nops, most_nops_needed + 1.0) - 1.0) / ((double)num_nops - 1.0)));
104 }
105 
~cPhenotype()106 cPhenotype::~cPhenotype()
107 {
108   // Remove Task States
109   tArray<cTaskState*> task_states(0);
110   m_task_states.GetValues(task_states);
111   for (int i = 0; i < task_states.GetSize(); i++) delete task_states[i];
112   delete m_reaction_result;
113 }
114 
115 
cPhenotype(const cPhenotype & in_phen)116 cPhenotype::cPhenotype(const cPhenotype& in_phen) : m_reaction_result(NULL)
117 {
118   *this = in_phen;
119 }
120 
121 
operator =(const cPhenotype & in_phen)122 cPhenotype& cPhenotype::operator=(const cPhenotype& in_phen)
123 {
124 
125   m_world                  = in_phen.m_world;
126   initialized              = in_phen.initialized;
127 
128 
129   // 1. These are values calculated at the last divide (of self or offspring)
130   merit                    = in_phen.merit;
131   executionRatio           = in_phen.executionRatio;
132   energy_store             = in_phen.energy_store;
133   energy_tobe_applied      = in_phen.energy_tobe_applied;
134   energy_testament         = in_phen.energy_testament;
135   energy_received_buffer   = in_phen.energy_received_buffer;
136   genome_length            = in_phen.genome_length;
137   bonus_instruction_count  = in_phen.bonus_instruction_count;
138   copied_size              = in_phen.copied_size;
139   executed_size            = in_phen.executed_size;
140   gestation_time           = in_phen.gestation_time;
141 
142   gestation_start          = in_phen.gestation_start;
143   fitness                  = in_phen.fitness;
144   div_type                 = in_phen.div_type;
145 
146   // 2. These are "in progress" variables, updated as the organism operates
147   cur_bonus                = in_phen.cur_bonus;
148   cur_energy_bonus         = in_phen.cur_energy_bonus;
149   cur_num_errors           = in_phen.cur_num_errors;
150   cur_num_donates          = in_phen.cur_num_donates;
151   cur_task_count           = in_phen.cur_task_count;
152   cur_para_tasks           = in_phen.cur_para_tasks;
153   cur_host_tasks           = in_phen.cur_host_tasks;
154   eff_task_count           = in_phen.eff_task_count;
155   cur_internal_task_count  = in_phen.cur_internal_task_count;
156   cur_task_quality         = in_phen.cur_task_quality;
157   cur_internal_task_quality= in_phen.cur_internal_task_quality;
158   cur_task_value           = in_phen.cur_task_value;
159   cur_rbins_total          = in_phen.cur_rbins_total;
160   cur_rbins_avail          = in_phen.cur_rbins_avail;
161   cur_collect_spec_counts  = in_phen.cur_collect_spec_counts;
162   cur_reaction_count       = in_phen.cur_reaction_count;
163   first_reaction_cycles    = in_phen.first_reaction_cycles;
164   first_reaction_execs     = first_reaction_execs;
165   cur_reaction_add_reward  = in_phen.cur_reaction_add_reward;
166   cur_inst_count           = in_phen.cur_inst_count;
167   cur_sense_count          = in_phen.cur_sense_count;
168   sensed_resources         = in_phen.sensed_resources;
169   cur_task_time            = in_phen.cur_task_time;
170   m_tolerance_immigrants          = in_phen.m_tolerance_immigrants;
171   m_tolerance_offspring_own       = in_phen.m_tolerance_offspring_own;
172   m_tolerance_offspring_others    = in_phen.m_tolerance_offspring_others;
173   m_intolerances                  = in_phen.m_intolerances;
174   cur_child_germline_propensity = in_phen.cur_child_germline_propensity;
175   cur_stolen_reaction_count       = in_phen.cur_stolen_reaction_count;
176   mating_type = in_phen.mating_type; //@CHC
177   mate_preference = in_phen.mate_preference; //@CHC
178   cur_mating_display_a = in_phen.cur_mating_display_a;
179   cur_mating_display_b = in_phen.cur_mating_display_b;
180   last_mating_display_a = in_phen.last_mating_display_a;
181   last_mating_display_b = in_phen.last_mating_display_b;
182 
183   // Dynamically allocated m_task_states requires special handling
184   tList<cTaskState*> hash_values;
185   tList<void*>       hash_keys;
186   in_phen.m_task_states.AsLists(hash_keys, hash_values);
187   tListIterator<cTaskState*> vit(hash_values);
188   tListIterator<void*>       kit(hash_keys);
189   while(vit.Next() && kit.Next())
190   {
191     cTaskState* new_ts = new cTaskState(**(vit.Get()));
192     m_task_states.Set(*(kit.Get()), new_ts);
193   }
194 
195   // 3. These mark the status of "in progess" variables at the last divide.
196   last_merit_base          = in_phen.last_merit_base;
197   last_bonus               = in_phen.last_bonus;
198   last_energy_bonus        = in_phen.last_energy_bonus;
199   last_num_errors          = in_phen.last_num_errors;
200   last_num_donates         = in_phen.last_num_donates;
201   last_task_count          = in_phen.last_task_count;
202   last_host_tasks          = in_phen.last_host_tasks;
203   last_para_tasks          = in_phen.last_para_tasks;
204   last_internal_task_count = in_phen.last_internal_task_count;
205   last_task_quality        = in_phen.last_task_quality;
206   last_internal_task_quality=in_phen.last_internal_task_quality;
207   last_task_value          = in_phen.last_task_value;
208   last_rbins_total         = in_phen.last_rbins_total;
209   last_rbins_avail         = in_phen.last_rbins_avail;
210   last_collect_spec_counts = in_phen.last_collect_spec_counts;
211   last_reaction_count      = in_phen.last_reaction_count;
212   last_reaction_add_reward = in_phen.last_reaction_add_reward;
213   last_inst_count          = in_phen.last_inst_count;
214   last_sense_count         = in_phen.last_sense_count;
215   last_fitness             = in_phen.last_fitness;
216   last_child_germline_propensity = in_phen.last_child_germline_propensity;
217   total_energy_donated     = in_phen.total_energy_donated;
218   total_energy_received    = in_phen.total_energy_received;
219   total_energy_applied     = in_phen.total_energy_applied;
220 
221   // 4. Records from this organisms life...
222   num_divides              = in_phen.num_divides;
223   num_divides_failed       = in_phen.num_divides_failed;
224   generation               = in_phen.generation;
225   cpu_cycles_used          = in_phen.cpu_cycles_used;
226   time_used                = in_phen.time_used;
227   num_execs                = in_phen.num_execs;
228   age                      = in_phen.age;
229   fault_desc               = in_phen.fault_desc;
230   neutral_metric           = in_phen.neutral_metric;
231   life_fitness             = in_phen.life_fitness;
232   exec_time_born           = in_phen.exec_time_born;
233   birth_update             = in_phen.birth_update;
234   num_new_unique_reactions = in_phen.num_new_unique_reactions;
235   last_task_id             = in_phen.last_task_id;
236   last_task_time           = in_phen.last_task_time;
237   res_consumed             = in_phen.res_consumed;
238   is_germ_cell             = in_phen.is_germ_cell;
239 
240   // 5. Status Flags...  (updated at each divide)
241   to_die                  = in_phen.to_die;
242   to_delete               = in_phen.to_delete;
243   is_injected             = in_phen.is_injected;
244   is_donor_cur            = in_phen.is_donor_cur;
245   is_donor_last           = in_phen.is_donor_last;
246   is_donor_rand           = in_phen.is_donor_rand;
247   is_donor_rand_last      = in_phen.is_donor_rand_last;
248   is_donor_null           = in_phen.is_donor_null;
249   is_donor_null_last      = in_phen.is_donor_null_last;
250   is_donor_kin            = in_phen.is_donor_kin;
251   is_donor_kin_last       = in_phen.is_donor_kin_last;
252   is_donor_edit           = in_phen.is_donor_edit;
253   is_donor_edit_last      = in_phen.is_donor_edit_last;
254   is_donor_gbg            = in_phen.is_donor_gbg;
255   is_donor_gbg_last       = in_phen.is_donor_gbg_last;
256   is_donor_truegb         = in_phen.is_donor_truegb;
257   is_donor_truegb_last    = in_phen.is_donor_truegb_last;
258   is_donor_threshgb       = in_phen.is_donor_threshgb;
259   is_donor_threshgb_last  = in_phen.is_donor_threshgb_last;
260   is_donor_quanta_threshgb        = in_phen.is_donor_quanta_threshgb;
261   is_donor_quanta_threshgb_last   = in_phen.is_donor_quanta_threshgb_last;
262   is_donor_shadedgb       = in_phen.is_donor_shadedgb;
263   is_donor_shadedgb_last  = in_phen.is_donor_shadedgb_last;
264   is_donor_locus          = in_phen.is_donor_locus;
265   is_donor_locus_last     = in_phen.is_donor_locus_last;
266   num_thresh_gb_donations         = in_phen.num_thresh_gb_donations;
267   num_thresh_gb_donations_last    = in_phen.num_thresh_gb_donations_last;
268   num_quanta_thresh_gb_donations = in_phen.num_quanta_thresh_gb_donations;
269   num_quanta_thresh_gb_donations_last = in_phen.num_quanta_thresh_gb_donations_last;
270   num_shaded_gb_donations         = in_phen.num_shaded_gb_donations;
271   num_shaded_gb_donations_last    = in_phen.num_shaded_gb_donations_last;
272   num_donations_locus     = in_phen.num_donations_locus;
273   num_donations_locus_last = in_phen.num_donations_locus_last;
274   is_receiver             = in_phen.is_receiver;
275   is_receiver_last        = in_phen.is_receiver_last;
276   is_receiver_rand        = in_phen.is_receiver_rand;
277   is_receiver_kin         = in_phen.is_receiver_kin;
278   is_receiver_kin_last    = in_phen.is_receiver_kin_last;
279   is_receiver_edit        = in_phen.is_receiver_edit;
280   is_receiver_edit_last   = in_phen.is_receiver_edit_last;
281   is_receiver_gbg         = in_phen.is_receiver_gbg;
282   is_receiver_truegb      = in_phen.is_receiver_truegb;
283   is_receiver_truegb_last = in_phen.is_receiver_truegb_last;
284   is_receiver_threshgb    = in_phen.is_receiver_threshgb;
285   is_receiver_threshgb_last    = in_phen.is_receiver_threshgb_last;
286   is_receiver_quanta_threshgb  = in_phen.is_receiver_quanta_threshgb;
287   is_receiver_quanta_threshgb_last = in_phen.is_receiver_quanta_threshgb_last;
288   is_receiver_shadedgb    = in_phen.is_receiver_shadedgb;
289   is_receiver_shadedgb_last    = in_phen.is_receiver_shadedgb_last;
290   is_receiver_gb_same_locus = in_phen.is_receiver_gb_same_locus;
291   is_receiver_gb_same_locus_last = in_phen.is_receiver_gb_same_locus_last;
292   is_modifier             = in_phen.is_modifier;
293   is_modified             = in_phen.is_modified;
294   is_fertile              = in_phen.is_fertile;
295   is_mutated              = in_phen.is_mutated;
296   is_multi_thread         = in_phen.is_multi_thread;
297   parent_true             = in_phen.parent_true;
298   parent_sex              = in_phen.parent_sex;
299   parent_cross_num        = in_phen.parent_cross_num;
300 
301   is_energy_requestor     = in_phen.is_energy_requestor;
302   is_energy_donor         = in_phen.is_energy_donor;
303   is_energy_receiver      = in_phen.is_energy_receiver;
304   has_used_donated_energy = in_phen.has_used_donated_energy;
305   has_open_energy_request = in_phen.has_open_energy_request;
306   total_energy_donated    = in_phen.total_energy_donated;
307   total_energy_received   = in_phen.total_energy_received;
308   total_energy_applied    = in_phen.total_energy_applied;
309 
310   // 6. Child information...
311   copy_true               = in_phen.copy_true;
312   divide_sex              = in_phen.divide_sex;
313   mate_select_id          = in_phen.mate_select_id;
314   cross_num               = in_phen.cross_num;
315   child_fertile           = in_phen.child_fertile;
316   last_child_fertile      = in_phen.last_child_fertile;
317   child_copied_size       = in_phen.child_copied_size;
318 
319   // 7. Permanent information...
320   permanent_germline_propensity = in_phen.permanent_germline_propensity;
321 
322   return *this;
323 }
324 
325 
326 /**
327  * This function is run whenever a new organism is being constructed inside
328  * of its parent.
329  *
330  * Assumptions:
331  *     - parent_phenotype has had DivideReset run on it already!
332  *     - this is the first method run on an otherwise freshly built phenotype.
333  **/
334 
SetupOffspring(const cPhenotype & parent_phenotype,const Sequence & _genome)335 void cPhenotype::SetupOffspring(const cPhenotype& parent_phenotype, const Sequence& _genome)
336 {
337   // Copy divide values from parent, which should already be setup.
338   merit = parent_phenotype.merit;
339   if(m_world->GetConfig().INHERIT_EXE_RATE.Get() == 0)
340     executionRatio = 1.0;
341   else
342     executionRatio = parent_phenotype.executionRatio;
343 
344   energy_store    = min(energy_store, m_world->GetConfig().ENERGY_CAP.Get());
345   energy_tobe_applied = 0.0;
346   energy_testament = 0.0;
347   energy_received_buffer = 0.0;
348   genome_length   = _genome.GetSize();
349   copied_size     = parent_phenotype.child_copied_size;
350   executed_size   = parent_phenotype.executed_size;
351 
352   gestation_time  = parent_phenotype.gestation_time;
353   gestation_start = 0;
354   cpu_cycles_used = 0;
355   fitness         = parent_phenotype.fitness;
356   div_type        = parent_phenotype.div_type;
357 
358   assert(genome_length > 0);
359   assert(copied_size > 0);
360   assert(gestation_time >= 0); //@JEB 0 valid for some fitness methods
361   assert(div_type > 0);
362 
363   // Initialize current values, as neeeded.
364   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
365   cur_energy_bonus = 0.0;
366   cur_num_errors  = 0;
367   cur_num_donates  = 0;
368   cur_task_count.SetAll(0);
369   cur_internal_task_count.SetAll(0);
370   eff_task_count.SetAll(0);
371   cur_host_tasks.SetAll(0);
372   cur_para_tasks.SetAll(0);
373   cur_task_quality.SetAll(0);
374   cur_task_value.SetAll(0);
375   cur_internal_task_quality.SetAll(0);
376   cur_rbins_total.SetAll(0);  // total resources collected in lifetime
377   // parent's resources have already been halved or reset in DivideReset;
378   // offspring gets that value (half or 0) too.
379   cur_rbins_avail.SetAll(0);
380   for (int i = 0; i < cur_rbins_avail.GetSize(); i++) {
381     const int resource = m_world->GetConfig().COLLECT_SPECIFIC_RESOURCE.Get();
382     if (m_world->GetConfig().RESOURCE_GIVEN_AT_BIRTH.Get() > 0.0) {
383       cur_rbins_avail[resource] = m_world->GetConfig().RESOURCE_GIVEN_AT_BIRTH.Get();
384     }
385     if (m_world->GetConfig().SPLIT_ON_DIVIDE.Get()) {
386       cur_rbins_avail[i] = parent_phenotype.cur_rbins_avail[i];
387       cur_rbins_avail[resource] = cur_rbins_avail[resource] + m_world->GetConfig().RESOURCE_GIVEN_AT_BIRTH.Get();
388     }
389   }
390   cur_collect_spec_counts.SetAll(0);
391   cur_reaction_count.SetAll(0);
392   first_reaction_cycles.SetAll(-1);
393   first_reaction_execs.SetAll(-1);
394   cur_stolen_reaction_count.SetAll(0);
395   cur_reaction_add_reward.SetAll(0);
396   cur_inst_count.SetAll(0);
397   cur_sense_count.SetAll(0);
398   cur_task_time.SetAll(0.0);  // Added for time tracking; WRE 03-18-07
399   for (int j = 0; j < sensed_resources.GetSize(); j++) {
400     sensed_resources[j] =  parent_phenotype.sensed_resources[j];
401   }
402   cur_trial_fitnesses.Resize(0);
403   cur_trial_bonuses.Resize(0);
404   cur_trial_times_used.Resize(0);
405   trial_time_used = 0;
406   trial_cpu_cycles_used = 0;
407   m_tolerance_immigrants.Clear();
408   m_tolerance_offspring_own.Clear();
409   m_tolerance_offspring_others.Clear();
410   m_intolerances.SetAll(make_pair(-1, -1));
411   cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
412   mating_type = MATING_TYPE_JUVENILE; //@CHC
413   mate_preference = MATE_PREFERENCE_RANDOM; //@CHC
414 
415   cur_mating_display_a = 0;
416   cur_mating_display_b = 0;
417   last_mating_display_a = 0;
418   last_mating_display_b = 0;
419 
420   // Copy last values from parent
421   last_merit_base           = parent_phenotype.last_merit_base;
422   last_bonus                = parent_phenotype.last_bonus;
423   last_cpu_cycles_used      = parent_phenotype.last_cpu_cycles_used;
424   last_num_errors           = parent_phenotype.last_num_errors;
425   last_num_donates          = parent_phenotype.last_num_donates;
426   last_task_count           = parent_phenotype.last_task_count;
427   last_host_tasks           = parent_phenotype.last_host_tasks;
428   last_para_tasks           = parent_phenotype.last_para_tasks;
429   last_internal_task_count  = parent_phenotype.last_internal_task_count;
430   last_task_quality         = parent_phenotype.last_task_quality;
431   last_task_value           = parent_phenotype.last_task_value;
432   last_internal_task_quality= parent_phenotype.last_internal_task_quality;
433   last_rbins_total          = parent_phenotype.last_rbins_total;
434   last_rbins_avail          = parent_phenotype.last_rbins_avail;
435   last_collect_spec_counts  = parent_phenotype.last_collect_spec_counts;
436   last_reaction_count       = parent_phenotype.last_reaction_count;
437   last_reaction_add_reward  = parent_phenotype.last_reaction_add_reward;
438   last_inst_count           = parent_phenotype.last_inst_count;
439   last_sense_count          = parent_phenotype.last_sense_count;
440   last_fitness              = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
441   last_child_germline_propensity = parent_phenotype.last_child_germline_propensity;   // chance of child being a germline cell; @JEB
442 
443   // Setup other miscellaneous values...
444   num_divides     = 0;
445   num_divides_failed = 0;
446   generation      = parent_phenotype.generation;
447   if (m_world->GetConfig().GENERATION_INC_METHOD.Get() != GENERATION_INC_BOTH) generation++;
448   cpu_cycles_used = 0;
449   time_used       = 0;
450   num_execs       = 0;
451   age             = 0;
452   fault_desc      = "";
453   neutral_metric  = parent_phenotype.neutral_metric + m_world->GetRandom().GetRandNormal();
454   life_fitness    = fitness;
455   exec_time_born  = parent_phenotype.exec_time_born;  //@MRR treating offspring and parent as siblings; already set in DivideReset
456   birth_update    = parent_phenotype.birth_update;
457   num_new_unique_reactions = 0;
458   last_task_id             = -1;
459   res_consumed             = 0;
460   is_germ_cell             = parent_phenotype.is_germ_cell;
461   last_task_time           = 0;
462 
463   num_thresh_gb_donations = 0;
464   num_thresh_gb_donations_last = parent_phenotype.num_thresh_gb_donations_last;
465   num_quanta_thresh_gb_donations = 0;
466   num_quanta_thresh_gb_donations_last = parent_phenotype.num_thresh_gb_donations_last;
467   num_shaded_gb_donations = 0;
468   num_shaded_gb_donations_last = parent_phenotype.num_shaded_gb_donations_last;
469   num_donations_locus = 0;
470   num_donations_locus_last = parent_phenotype.num_donations_locus_last;
471 
472 
473   // Setup flags...
474   is_injected   = false;
475   is_donor_cur  = false;
476   is_donor_last = parent_phenotype.is_donor_last;
477   is_donor_rand = false;
478   is_donor_rand_last = parent_phenotype.is_donor_rand_last;
479   is_donor_null = false;
480   is_donor_null_last = parent_phenotype.is_donor_null_last;
481   is_donor_kin  = false;
482   is_donor_kin_last = parent_phenotype.is_donor_kin_last;
483   is_donor_edit  = false;
484   is_donor_edit_last = parent_phenotype.is_donor_edit_last;
485   is_donor_gbg  = false;
486   is_donor_gbg_last = parent_phenotype.is_donor_gbg_last;
487   is_donor_truegb  = false;
488   is_donor_truegb_last = parent_phenotype.is_donor_truegb_last;
489   is_donor_threshgb  = false;
490   is_donor_threshgb_last = parent_phenotype.is_donor_threshgb_last;
491   is_donor_quanta_threshgb  = false;
492   is_donor_quanta_threshgb_last = parent_phenotype.is_donor_quanta_threshgb_last;
493   is_donor_shadedgb  = false;
494   is_donor_shadedgb_last = parent_phenotype.is_donor_shadedgb_last;
495   is_donor_locus.SetAll(false);
496   is_donor_locus_last = parent_phenotype.is_donor_locus_last;
497 
498   is_receiver   = false;
499   is_receiver_last = parent_phenotype.is_receiver_last;
500   is_receiver_rand   = false;
501   is_receiver_kin    = false;
502   is_receiver_kin_last    = parent_phenotype.is_receiver_kin_last;
503   is_receiver_edit   = false;
504   is_receiver_edit_last    = parent_phenotype.is_receiver_edit_last;
505   is_receiver_gbg    = false;
506   is_receiver_truegb = false;
507   is_receiver_truegb_last = parent_phenotype.is_receiver_truegb_last;
508   is_receiver_threshgb = false;
509   is_receiver_threshgb_last = parent_phenotype.is_receiver_threshgb_last;
510   is_receiver_quanta_threshgb = false;
511   is_receiver_quanta_threshgb_last = parent_phenotype.is_receiver_quanta_threshgb_last;
512   is_receiver_shadedgb = false;
513   is_receiver_shadedgb_last = parent_phenotype.is_receiver_shadedgb_last;
514   is_receiver_gb_same_locus = false;
515   is_receiver_gb_same_locus_last = parent_phenotype.is_receiver_gb_same_locus;
516 
517   is_modifier   = false;
518   is_modified   = false;
519   is_fertile    = parent_phenotype.last_child_fertile;
520   is_mutated    = false;
521   if (m_world->GetConfig().INHERIT_MULTITHREAD.Get()) {
522     is_multi_thread = parent_phenotype.is_multi_thread;
523   } else {
524     is_multi_thread = false;
525   }
526 
527   parent_true   = parent_phenotype.copy_true;
528   parent_sex    = parent_phenotype.divide_sex;
529   parent_cross_num    = parent_phenotype.cross_num;
530   to_die = false;
531   to_delete = false;
532 
533   is_energy_requestor = false;
534   is_energy_donor = false;
535   is_energy_receiver = false;
536   has_used_donated_energy = false;
537   has_open_energy_request = false;
538   total_energy_donated = 0.0;
539   total_energy_received = 0.0;
540   total_energy_applied = 0.0;
541 
542   // Setup child info...
543   copy_true          = false;
544   divide_sex         = false;
545   mate_select_id     = -1;
546   cross_num          = 0;
547   last_child_fertile = is_fertile;
548   child_fertile      = true;
549   child_copied_size  = 0;
550 
551   // permanently set germline propensity of org (since DivideReset is called first, it is now in the "last" slot...)
552   permanent_germline_propensity  = parent_phenotype.last_child_germline_propensity;
553 
554   initialized = true;
555 }
556 
557 
558 /**
559  * This function is run whenever a new organism is being constructed via
560  * some form of injection into the population, or in a test environment.
561  *
562  * Assumptions:
563  *     - Updates to these values (i.e. resetting of merit) will occur afterward
564  *     - This is the first method run on an otherwise freshly built phenotype.
565  **/
566 
SetupInject(const Sequence & _genome)567 void cPhenotype::SetupInject(const Sequence& _genome)
568 {
569   // Setup reasonable initial values injected organism...
570   genome_length   = _genome.GetSize();
571   merit           = genome_length;
572   copied_size     = genome_length;
573   executed_size   = genome_length;
574   energy_store    = min(m_world->GetConfig().ENERGY_GIVEN_ON_INJECT.Get(), m_world->GetConfig().ENERGY_CAP.Get());
575   energy_tobe_applied = 0.0;
576   energy_testament = 0.0;
577   energy_received_buffer = 0.0;
578   executionRatio = 1.0;
579   gestation_time  = 0;
580   gestation_start = 0;
581   fitness         = 0;
582   div_type	  = 1;
583 
584   // Initialize current values, as neeeded.
585   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
586   cur_energy_bonus = 0.0;
587   cur_num_errors  = 0;
588   cur_num_donates  = 0;
589   cur_task_count.SetAll(0);
590   cur_para_tasks.SetAll(0);
591   cur_host_tasks.SetAll(0);
592   cur_internal_task_count.SetAll(0);
593   eff_task_count.SetAll(0);
594   cur_task_quality.SetAll(0);
595   cur_task_value.SetAll(0);
596   cur_internal_task_quality.SetAll(0);
597   cur_rbins_total.SetAll(0);
598   if (m_world->GetConfig().RESOURCE_GIVEN_ON_INJECT.Get() > 0.0) {
599     const int resource = m_world->GetConfig().COLLECT_SPECIFIC_RESOURCE.Get();
600     cur_rbins_avail[resource] = m_world->GetConfig().RESOURCE_GIVEN_ON_INJECT.Get();
601   }
602   else cur_rbins_avail.SetAll(0);
603   cur_collect_spec_counts.SetAll(0);
604   cur_reaction_count.SetAll(0);
605   first_reaction_cycles.SetAll(-1);
606   first_reaction_execs.SetAll(-1);
607   cur_stolen_reaction_count.SetAll(0);
608   cur_reaction_add_reward.SetAll(0);
609   cur_inst_count.SetAll(0);
610   sensed_resources.SetAll(0);
611   cur_sense_count.SetAll(0);
612   cur_task_time.SetAll(0.0);
613   cur_trial_fitnesses.Resize(0);
614   cur_trial_bonuses.Resize(0);
615   cur_trial_times_used.Resize(0);
616   trial_time_used = 0;
617   trial_cpu_cycles_used = 0;
618   m_tolerance_immigrants.Clear();
619   m_tolerance_offspring_own.Clear();
620   m_tolerance_offspring_others.Clear();
621   m_intolerances.SetAll(make_pair(-1, -1));
622   cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
623   mating_type = MATING_TYPE_JUVENILE; // @CHC
624   mate_preference = MATE_PREFERENCE_RANDOM; //@CHC
625 
626   // New organism has no parent and so cannot use its last values; initialize as needed
627   last_merit_base = genome_length;
628   last_bonus      = 1;
629   last_cpu_cycles_used = 0;
630   last_num_errors = 0;
631   last_num_donates = 0;
632   last_task_count.SetAll(0);
633   last_host_tasks.SetAll(0);
634   last_para_tasks.SetAll(0);
635   last_internal_task_count.SetAll(0);
636   last_task_quality.SetAll(0);
637   last_task_value.SetAll(0);
638   last_internal_task_quality.SetAll(0);
639   last_rbins_total.SetAll(0);
640   last_rbins_avail.SetAll(0);
641   last_collect_spec_counts.SetAll(0);
642   last_reaction_count.SetAll(0);
643   last_reaction_add_reward.SetAll(0);
644   last_inst_count.SetAll(0);
645   last_sense_count.SetAll(0);
646   last_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
647 
648   // Setup other miscellaneous values...
649   num_divides     = 0;
650   num_divides_failed = 0;
651   generation      = 0;
652   cpu_cycles_used = 0;
653   time_used       = 0;
654   num_execs       = 0;
655   age             = 0;
656   fault_desc      = "";
657   neutral_metric  = 0;
658   life_fitness    = 0;
659   exec_time_born  = 0;
660   birth_update     = m_world->GetStats().GetUpdate();
661 
662   num_thresh_gb_donations = 0;
663   num_thresh_gb_donations_last = 0;
664   num_quanta_thresh_gb_donations = 0;
665   num_quanta_thresh_gb_donations_last = 0;
666   num_shaded_gb_donations = 0;
667   num_shaded_gb_donations_last = 0;
668   num_donations_locus = 0;
669   num_donations_locus_last = 0;
670 
671   // Setup flags...
672   is_injected   = true;
673   is_donor_last = false;
674   is_donor_cur  = false;
675   is_donor_rand = false;
676   is_donor_rand_last = false;
677   is_donor_null = false;
678   is_donor_null_last = false;
679   is_donor_kin = false;
680   is_donor_kin_last = false;
681   is_donor_edit = false;
682   is_donor_edit_last = false;
683   is_donor_gbg = false;
684   is_donor_gbg_last = false;
685   is_donor_truegb = false;
686   is_donor_truegb_last = false;
687   is_donor_threshgb = false;
688   is_donor_threshgb_last = false;
689   is_donor_quanta_threshgb = false;
690   is_donor_quanta_threshgb_last = false;
691   is_donor_shadedgb = false;
692   is_donor_shadedgb_last = false;
693   is_donor_locus.SetAll(false);
694   is_donor_locus_last.SetAll(false);
695 
696   is_receiver   = false;
697   is_receiver_last   = false;
698   is_receiver_rand   = false;
699   is_receiver_kin   = false;
700   is_receiver_kin_last   = false;
701   is_receiver_edit   = false;
702   is_receiver_edit_last   = false;
703   is_receiver_gbg   = false;
704   is_receiver_truegb   = false;
705   is_receiver_truegb_last   = false;
706   is_receiver_threshgb   = false;
707   is_receiver_threshgb_last   = false;
708   is_receiver_quanta_threshgb   = false;
709   is_receiver_quanta_threshgb_last   = false;
710   is_receiver_shadedgb   = false;
711   is_receiver_shadedgb_last   = false;
712   is_receiver_gb_same_locus = false;
713   is_receiver_gb_same_locus_last = false;
714 
715   is_modifier   = false;
716   is_modified   = false;
717   is_fertile    = true;
718   is_mutated    = false;
719   is_multi_thread = false;
720   parent_true   = true;
721   parent_sex    = false;
722   parent_cross_num    = 0;
723   to_die = false;
724   to_delete = false;
725 
726   is_energy_requestor = false;
727   is_energy_donor = false;
728   is_energy_receiver = false;
729   has_used_donated_energy = false;
730   has_open_energy_request = false;
731   total_energy_donated = 0.0;
732   total_energy_received = 0.0;
733   total_energy_applied = 0.0;
734 
735   // Setup child info...
736   copy_true         = false;
737   divide_sex        = false;
738   mate_select_id    = -1;
739   cross_num         = 0;
740   child_fertile     = true;
741   last_child_fertile = true;
742   child_copied_size = 0;
743 
744   permanent_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
745 
746   initialized = true;
747 }
748 
749 
ResetMerit(const Sequence & _cgenome)750 void cPhenotype::ResetMerit(const Sequence & _cgenome)
751 {
752   int cur_merit_base = CalcSizeMerit();
753   const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
754   if (merit_default_bonus) {
755     cur_bonus = merit_default_bonus;
756   }
757   merit = cur_merit_base * cur_bonus;
758 
759   if (m_world->GetConfig().INHERIT_MERIT.Get() == 0) {
760     merit = cur_merit_base;
761   }
762 }
763 
764 
765 /**
766  * This function is run whenever an organism executes a successful divide.
767  **/
768 
DivideReset(const Sequence & _genome)769 void cPhenotype::DivideReset(const Sequence& _genome)
770 {
771   assert(time_used >= 0);
772   assert(initialized == true);
773 
774   // Update these values as needed...
775   int cur_merit_base = CalcSizeMerit();
776 
777   // If we are resetting the current merit, do it here
778   // and it will also be propagated to the child
779   const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
780   if (merit_default_bonus) {
781     cur_bonus = merit_default_bonus;
782   }
783   merit = cur_merit_base * cur_bonus;
784 
785   if(m_world->GetConfig().INHERIT_MERIT.Get() == 0)
786     merit = cur_merit_base;
787 
788   SetEnergy(energy_store + cur_energy_bonus);
789   m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
790   energy_testament = 0.0;
791   energy_received_buffer = 0.0;  // If donated energy not applied, it's lost here
792 
793   genome_length   = _genome.GetSize();
794   (void) copied_size;          // Unchanged
795   (void) executed_size;        // Unchanged
796   gestation_time  = time_used - gestation_start;
797   gestation_start = time_used;
798   fitness = CalcFitness( cur_merit_base, cur_bonus, gestation_time, cpu_cycles_used);
799 
800   // Lock in cur values as last values.
801   last_merit_base           = cur_merit_base;
802   last_bonus                = cur_bonus;
803   last_cpu_cycles_used      = cpu_cycles_used;
804   //TODO?  last_energy         = cur_energy_bonus;
805   last_num_errors           = cur_num_errors;
806   last_num_donates          = cur_num_donates;
807   last_task_count           = cur_task_count;
808   last_host_tasks           = cur_host_tasks;
809   last_para_tasks           = cur_para_tasks;
810   last_internal_task_count  = cur_internal_task_count;
811   last_task_quality         = cur_task_quality;
812   last_task_value           = cur_task_value;
813   last_internal_task_quality= cur_internal_task_quality;
814   last_rbins_total          = cur_rbins_total;
815   last_rbins_avail          = cur_rbins_avail;
816   last_collect_spec_counts  = cur_collect_spec_counts;
817   last_reaction_count       = cur_reaction_count;
818   last_reaction_add_reward  = cur_reaction_add_reward;
819   last_inst_count           = cur_inst_count;
820   last_sense_count          = cur_sense_count;
821   last_child_germline_propensity = cur_child_germline_propensity;
822 
823   last_mating_display_a = cur_mating_display_a; //@CHC
824   last_mating_display_b = cur_mating_display_b;
825 
826   // Reset cur values.
827   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
828   cpu_cycles_used = 0;
829   cur_energy_bonus = 0.0;
830   cur_num_errors  = 0;
831   cur_num_donates  = 0;
832   cur_task_count.SetAll(0);
833   cur_host_tasks.SetAll(0);
834 
835   cur_mating_display_a = 0; //@CHC
836   cur_mating_display_b = 0;
837 
838   // @LZ: figure out when and where to reset cur_para_tasks, depending on the divide method, and
839   //      resonable assumptions
840   if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
841     last_para_tasks = cur_para_tasks;
842     cur_para_tasks.SetAll(0);
843   }
844   cur_internal_task_count.SetAll(0);
845   eff_task_count.SetAll(0);
846   cur_task_quality.SetAll(0);
847   cur_task_value.SetAll(0);
848   cur_internal_task_quality.SetAll(0);
849   if (m_world->GetConfig().SPLIT_ON_DIVIDE.Get()) {
850     // resources available are split in half -- the offspring gets the other half
851     for (int i = 0; i < cur_rbins_avail.GetSize(); i++) {cur_rbins_avail[i] /= 2.0;}
852   }
853   else if (m_world->GetConfig().DIVIDE_METHOD.Get() != 0) {
854     cur_rbins_avail.SetAll(0);
855     cur_rbins_total.SetAll(0);  // total resources collected in lifetime
856   }
857   cur_collect_spec_counts.SetAll(0);
858   cur_reaction_count.SetAll(0);
859   first_reaction_cycles.SetAll(-1);
860   first_reaction_execs.SetAll(-1);
861   cur_stolen_reaction_count.SetAll(0);
862   cur_reaction_add_reward.SetAll(0);
863   cur_inst_count.SetAll(0);
864   cur_sense_count.SetAll(0);
865   cur_task_time.SetAll(0.0);
866   cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
867 
868   // Setup other miscellaneous values...
869   num_divides++;
870   (void) generation;
871   (void) time_used;
872   num_execs       = 0;
873   age             = 0;
874   fault_desc      = "";
875   (void) neutral_metric;
876   life_fitness = fitness;
877   exec_time_born += gestation_time;  //@MRR Treating organism as sibling
878   birth_update = m_world->GetStats().GetUpdate();
879   num_new_unique_reactions = 0;
880   last_task_id             = -1;
881   res_consumed             = 0;
882   last_task_time           = 0;
883 
884   num_thresh_gb_donations_last = num_thresh_gb_donations;
885   num_thresh_gb_donations = 0;
886   num_quanta_thresh_gb_donations_last = num_quanta_thresh_gb_donations;
887   num_quanta_thresh_gb_donations = 0;
888   num_shaded_gb_donations_last = num_shaded_gb_donations;
889   num_shaded_gb_donations = 0;
890   num_donations_locus_last = num_donations_locus;
891   num_donations_locus = 0;
892 
893   // Leave flags alone...
894   (void) is_injected;
895   is_donor_last = is_donor_cur;
896   is_donor_cur = false;
897   is_donor_rand_last = is_donor_rand;
898   is_donor_rand = false;
899   is_donor_null_last = is_donor_null;
900   is_donor_null = false;
901   is_donor_kin_last = is_donor_kin;
902   is_donor_kin = false;
903   is_donor_edit_last = is_donor_edit;
904   is_donor_edit = false;
905   is_donor_gbg_last = is_donor_gbg;
906   is_donor_gbg = false;
907   is_donor_truegb_last = is_donor_truegb;
908   is_donor_truegb = false;
909   is_donor_threshgb_last = is_donor_threshgb;
910   is_donor_threshgb = false;
911   is_donor_quanta_threshgb_last = is_donor_quanta_threshgb;
912   is_donor_quanta_threshgb = false;
913   is_donor_shadedgb_last = is_donor_shadedgb;
914   is_donor_shadedgb = false;
915   is_donor_locus_last = is_donor_locus;
916   is_donor_locus.SetAll(false);
917 
918   is_receiver_last = is_receiver;
919   is_receiver = false;
920   is_receiver_rand = false;
921   is_receiver_kin_last = is_receiver_kin;
922   is_receiver_kin = false;
923   is_receiver_edit_last = is_receiver_edit;
924   is_receiver_edit = false;
925   is_receiver_gbg = false;
926   is_receiver_truegb_last = is_receiver_truegb;
927   is_receiver_truegb = false;
928   is_receiver_threshgb_last = is_receiver_threshgb;
929   is_receiver_threshgb = false;
930   is_receiver_quanta_threshgb_last = is_receiver_quanta_threshgb;
931   is_receiver_quanta_threshgb = false;
932   is_receiver_shadedgb_last = is_receiver_shadedgb;
933   is_receiver_shadedgb = false;
934   is_receiver_gb_same_locus_last = is_receiver_gb_same_locus;
935   is_receiver_gb_same_locus = false;
936 
937   (void) is_modifier;
938   (void) is_modified;
939   (void) is_fertile;
940   (void) is_mutated;
941   (void) is_multi_thread;
942   (void) parent_true;
943   (void) parent_sex;
944   (void) parent_cross_num;
945 
946   // Reset child info...
947   (void) copy_true;
948   (void) divide_sex;
949   (void) mate_select_id;
950   (void) cross_num;
951   last_child_fertile = child_fertile;
952   child_fertile     = true;
953   (void) child_copied_size;
954 
955   // A few final changes if the parent was supposed to be be considered
956   // a second child on the divide.
957   if ((m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) ||
958       (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_BIRTH)) {
959     gestation_start = 0;
960     cpu_cycles_used = 0;
961     time_used = 0;
962     neutral_metric += m_world->GetRandom().GetRandNormal();
963   }
964 
965   if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
966     m_tolerance_immigrants.Clear();
967     m_tolerance_offspring_own.Clear();
968     m_tolerance_offspring_others.Clear();
969     m_intolerances.SetAll(make_pair(-1, -1));
970   }
971 
972   if (m_world->GetConfig().GENERATION_INC_METHOD.Get() == GENERATION_INC_BOTH) generation++;
973 
974   // Reset Task States
975   tArray<cTaskState*> task_states(0);
976   m_task_states.GetValues(task_states);
977   for (int i = 0; i < task_states.GetSize(); i++) delete task_states[i];
978   m_task_states.ClearAll();
979 }
980 
981 /**
982  * This function runs whenever a *test* CPU divides. It processes much of
983  * the information for that CPU in order to actively reflect its executed
984  * and copied size in its merit.
985  **/
986 
TestDivideReset(const Sequence & _genome)987 void cPhenotype::TestDivideReset(const Sequence& _genome)
988 {
989   assert(time_used > 0);
990   assert(initialized == true);
991 
992   // Update these values as needed...
993   int cur_merit_base = CalcSizeMerit();
994   const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
995   if (merit_default_bonus) {
996     cur_bonus = merit_default_bonus;
997   }
998   merit = cur_merit_base * cur_bonus;
999 
1000   if (m_world->GetConfig().INHERIT_MERIT.Get() == 0) {
1001     merit = cur_merit_base;
1002   }
1003 
1004   genome_length   = _genome.GetSize();
1005   (void) copied_size;                            // Unchanged
1006   (void) executed_size;                          // Unchanged
1007   gestation_time  = time_used - gestation_start;
1008   gestation_start = time_used;
1009   fitness         = CalcFitness(cur_merit_base, cur_bonus, gestation_time, cpu_cycles_used);
1010   (void) div_type; 				// Unchanged
1011 
1012   // Lock in cur values as last values.
1013   last_merit_base           = cur_merit_base;
1014   last_bonus                = cur_bonus;
1015   last_cpu_cycles_used      = cpu_cycles_used;
1016   last_num_errors           = cur_num_errors;
1017   last_num_donates          = cur_num_donates;
1018   last_task_count           = cur_task_count;
1019   last_host_tasks           = cur_host_tasks;
1020   last_para_tasks           = cur_para_tasks;
1021   last_internal_task_count  = cur_internal_task_count;
1022   last_task_quality         = cur_task_quality;
1023   last_task_value			= cur_task_value;
1024   last_internal_task_quality= cur_internal_task_quality;
1025   last_rbins_total          = cur_rbins_total;
1026   last_rbins_avail          = cur_rbins_avail;
1027   last_collect_spec_counts  = cur_collect_spec_counts;
1028   last_reaction_count       = cur_reaction_count;
1029   last_reaction_add_reward  = cur_reaction_add_reward;
1030   last_inst_count           = cur_inst_count;
1031   last_sense_count          = cur_sense_count;
1032   last_child_germline_propensity = cur_child_germline_propensity;
1033 
1034   // Reset cur values.
1035   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
1036   cpu_cycles_used = 0;
1037   cur_num_errors  = 0;
1038   cur_num_donates  = 0;
1039   cur_task_count.SetAll(0);
1040   cur_host_tasks.SetAll(0);
1041   // @LZ: figure out when and where to reset cur_para_tasks, depending on the divide method, and
1042   //      resonable assumptions
1043   if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
1044     last_para_tasks = cur_para_tasks;
1045     cur_para_tasks.SetAll(0);
1046   }
1047   cur_internal_task_count.SetAll(0);
1048   eff_task_count.SetAll(0);
1049   cur_task_quality.SetAll(0);
1050   cur_task_value.SetAll(0);
1051   cur_internal_task_quality.SetAll(0);
1052   cur_rbins_total.SetAll(0);  // total resources collected in lifetime
1053   if (m_world->GetConfig().RESOURCE_GIVEN_ON_INJECT.Get() > 0.0) {
1054     const int resource = m_world->GetConfig().COLLECT_SPECIFIC_RESOURCE.Get();
1055     cur_rbins_avail[resource] = m_world->GetConfig().RESOURCE_GIVEN_ON_INJECT.Get();
1056   }
1057   else cur_rbins_avail.SetAll(0);
1058   cur_collect_spec_counts.SetAll(0);
1059   cur_reaction_count.SetAll(0);
1060   first_reaction_cycles.SetAll(-1);
1061   first_reaction_execs.SetAll(-1);
1062   cur_stolen_reaction_count.SetAll(0);
1063   cur_reaction_add_reward.SetAll(0);
1064   cur_inst_count.SetAll(0);
1065   cur_sense_count.SetAll(0);
1066   cur_task_time.SetAll(0.0);
1067   sensed_resources.SetAll(-1.0);
1068   cur_trial_fitnesses.Resize(0);
1069   cur_trial_bonuses.Resize(0);
1070   cur_trial_times_used.Resize(0);
1071   trial_time_used = 0;
1072   trial_cpu_cycles_used = 0;
1073   m_tolerance_immigrants.Clear();
1074   m_tolerance_offspring_own.Clear();
1075   m_tolerance_offspring_others.Clear();
1076   m_intolerances.SetAll(make_pair(-1, -1));
1077   cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
1078 
1079   // Setup other miscellaneous values...
1080   num_divides++;
1081   generation++;
1082   (void) time_used;
1083   (void) num_execs;
1084   (void) age;
1085   (void) fault_desc;
1086   (void) neutral_metric;
1087   life_fitness = fitness;
1088   exec_time_born += gestation_time;  //@MRR See DivideReset
1089   birth_update  = m_world->GetStats().GetUpdate();
1090   num_new_unique_reactions = 0;
1091   last_task_id             = -1;
1092   res_consumed             = 0;
1093   last_task_time           = 0;
1094 
1095 
1096   num_thresh_gb_donations_last = num_thresh_gb_donations;
1097   num_thresh_gb_donations = 0;
1098   num_quanta_thresh_gb_donations_last = num_quanta_thresh_gb_donations;
1099   num_quanta_thresh_gb_donations = 0;
1100   num_shaded_gb_donations_last = num_shaded_gb_donations;
1101   num_shaded_gb_donations = 0;
1102   num_donations_locus_last = num_donations_locus;
1103   num_donations_locus = 0;
1104 
1105   // Leave flags alone...
1106   (void) is_injected;
1107   is_donor_last = is_donor_cur;
1108   is_donor_cur = false;
1109   is_donor_rand_last = is_donor_rand;
1110   is_donor_rand = false;
1111   is_donor_null_last = is_donor_null;
1112   is_donor_null = false;
1113   is_donor_kin_last = is_donor_kin;
1114   is_donor_kin = false;
1115   is_donor_edit_last = is_donor_edit;
1116   is_donor_edit = false;
1117   is_donor_gbg_last = is_donor_gbg;
1118   is_donor_gbg = false;
1119   is_donor_truegb_last = is_donor_truegb;
1120   is_donor_truegb = false;
1121   is_donor_threshgb_last = is_donor_threshgb;
1122   is_donor_threshgb = false;
1123   is_donor_quanta_threshgb_last = is_donor_quanta_threshgb;
1124   is_donor_quanta_threshgb = false;
1125   is_donor_shadedgb_last = is_donor_shadedgb;
1126   is_donor_shadedgb = false;
1127   is_donor_locus_last = is_donor_locus;
1128   is_donor_locus.SetAll(false);
1129 
1130   is_receiver_last = is_receiver;
1131   is_receiver = false;
1132   is_receiver_rand = false;
1133   is_receiver_kin_last = is_receiver_kin;
1134   is_receiver_kin = false;
1135   is_receiver_edit_last = is_receiver_edit;
1136   is_receiver_edit = false;
1137   is_receiver_gbg = false;
1138   is_receiver_truegb_last = is_receiver_truegb;
1139   is_receiver_truegb = false;
1140   is_receiver_threshgb_last = is_receiver_threshgb;
1141   is_receiver_threshgb = false;
1142   is_receiver_quanta_threshgb_last = is_receiver_quanta_threshgb;
1143   is_receiver_quanta_threshgb = false;
1144   is_receiver_shadedgb_last = is_receiver_shadedgb;
1145   is_receiver_shadedgb = false;
1146   is_receiver_gb_same_locus_last = is_receiver_gb_same_locus;
1147   is_receiver_gb_same_locus = false;
1148 
1149   (void) is_modifier;
1150   (void) is_modified;
1151   (void) is_fertile;
1152   (void) is_mutated;
1153   (void) is_multi_thread;
1154   (void) parent_true;
1155   (void) parent_sex;
1156   (void) parent_cross_num;
1157 
1158   // Reset child info...
1159   (void) copy_true;
1160   (void) divide_sex;
1161   (void) mate_select_id;
1162   (void) cross_num;
1163   (void) child_fertile;
1164   (void) last_child_fertile;
1165   (void) child_copied_size;
1166 }
1167 
1168 
1169 /**
1170  * This function is run when an organism is being forced to replicate, but
1171  * not at the end of its replication cycle.
1172  *
1173  * Assumptions:
1174  *   - new organism is an exact clone of the parent, with *same* last info.
1175  *   - this is the first method run on an otherwise freshly built phenotype.
1176  **/
1177 
SetupClone(const cPhenotype & clone_phenotype)1178 void cPhenotype::SetupClone(const cPhenotype& clone_phenotype)
1179 {
1180   // Copy divide values from parent, which should already be setup.
1181   merit           = clone_phenotype.merit;
1182 
1183   energy_store    = clone_phenotype.energy_store;
1184   energy_tobe_applied = 0.0;
1185   energy_testament = 0.0;
1186   energy_received_buffer = 0.0;
1187 
1188   if (m_world->GetConfig().INHERIT_EXE_RATE.Get() == 0) executionRatio = 1.0;
1189   else executionRatio = clone_phenotype.executionRatio;
1190 
1191   genome_length   = clone_phenotype.genome_length;
1192   copied_size     = clone_phenotype.copied_size;
1193   // copied_size     = clone_phenotype.child_copied_size;
1194   executed_size   = clone_phenotype.executed_size;
1195   gestation_time  = clone_phenotype.gestation_time;
1196   gestation_start = 0;
1197   fitness         = clone_phenotype.fitness;
1198   div_type        = clone_phenotype.div_type;
1199 
1200   assert(genome_length > 0);
1201   assert(copied_size > 0);
1202   assert(gestation_time >= 0); //@JEB 0 valid for some fitness methods
1203   assert(div_type > 0);
1204 
1205   // Initialize current values, as neeeded.
1206   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
1207   cpu_cycles_used = 0;
1208   cur_num_errors  = 0;
1209   cur_num_donates  = 0;
1210   cur_task_count.SetAll(0);
1211   cur_host_tasks.SetAll(0);
1212   cur_para_tasks.SetAll(0);
1213   cur_internal_task_count.SetAll(0);
1214   eff_task_count.SetAll(0);
1215   cur_rbins_total.SetAll(0);
1216   cur_rbins_avail.SetAll(0);
1217   cur_collect_spec_counts.SetAll(0);
1218   cur_reaction_count.SetAll(0);
1219   first_reaction_cycles.SetAll(-1);
1220   first_reaction_execs.SetAll(-1);
1221   cur_stolen_reaction_count.SetAll(0);
1222   cur_reaction_add_reward.SetAll(0);
1223   cur_inst_count.SetAll(0);
1224   cur_sense_count.SetAll(0);
1225   cur_task_time.SetAll(0.0);
1226   for (int j = 0; j < sensed_resources.GetSize(); j++) {
1227     sensed_resources[j] = clone_phenotype.sensed_resources[j];
1228   }
1229   cur_trial_fitnesses.Resize(0);
1230   cur_trial_bonuses.Resize(0);
1231   cur_trial_times_used.Resize(0);
1232   trial_time_used = 0;
1233   trial_cpu_cycles_used = 0;
1234   m_tolerance_immigrants.Clear();
1235   m_tolerance_offspring_own.Clear();
1236   m_tolerance_offspring_others.Clear();
1237   m_intolerances.SetAll(make_pair(-1, -1));
1238   cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
1239   mating_type = MATING_TYPE_JUVENILE; // @CHC
1240   mate_preference = MATE_PREFERENCE_RANDOM; //@CHC
1241 
1242   // Copy last values from parent
1243   last_merit_base          = clone_phenotype.last_merit_base;
1244   last_bonus               = clone_phenotype.last_bonus;
1245   last_cpu_cycles_used     = clone_phenotype.last_cpu_cycles_used;
1246   last_num_errors          = clone_phenotype.last_num_errors;
1247   last_num_donates         = clone_phenotype.last_num_donates;
1248   last_task_count          = clone_phenotype.last_task_count;
1249   last_host_tasks          = clone_phenotype.last_host_tasks;
1250   last_para_tasks          = clone_phenotype.last_para_tasks;
1251   last_internal_task_count = clone_phenotype.last_internal_task_count;
1252   last_rbins_total         = clone_phenotype.last_rbins_total;
1253   last_rbins_avail         = clone_phenotype.last_rbins_avail;
1254   last_collect_spec_counts = clone_phenotype.last_collect_spec_counts;
1255   last_reaction_count      = clone_phenotype.last_reaction_count;
1256   last_reaction_add_reward = clone_phenotype.last_reaction_add_reward;
1257   last_inst_count          = clone_phenotype.last_inst_count;
1258   last_sense_count         = clone_phenotype.last_sense_count;
1259   last_fitness             = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
1260   last_child_germline_propensity = clone_phenotype.last_child_germline_propensity;
1261 
1262   // Setup other miscellaneous values...
1263   num_divides     = 0;
1264   num_divides_failed = 0;
1265   generation      = clone_phenotype.generation;
1266   if (m_world->GetConfig().GENERATION_INC_METHOD.Get() != GENERATION_INC_BOTH) generation++;
1267   cpu_cycles_used = 0;
1268   time_used       = 0;
1269   num_execs       = 0;
1270   age             = 0;
1271   fault_desc      = "";
1272   neutral_metric  = clone_phenotype.neutral_metric + m_world->GetRandom().GetRandNormal();
1273   life_fitness    = fitness;
1274   exec_time_born  = 0;
1275   birth_update    = m_world->GetStats().GetUpdate();
1276   num_new_unique_reactions = clone_phenotype.num_new_unique_reactions;
1277   last_task_id             = clone_phenotype.last_task_id;
1278   res_consumed             = clone_phenotype.res_consumed;
1279   is_germ_cell             = clone_phenotype.is_germ_cell;
1280   last_task_time           = clone_phenotype.last_task_time;
1281 
1282 
1283   num_thresh_gb_donations_last = clone_phenotype.num_thresh_gb_donations_last;
1284   num_thresh_gb_donations  = clone_phenotype.num_thresh_gb_donations;
1285   num_quanta_thresh_gb_donations_last = clone_phenotype.num_quanta_thresh_gb_donations_last;
1286   num_quanta_thresh_gb_donations  = clone_phenotype.num_quanta_thresh_gb_donations;
1287   num_shaded_gb_donations_last = clone_phenotype.num_shaded_gb_donations_last;
1288   num_shaded_gb_donations  = clone_phenotype.num_shaded_gb_donations;
1289   num_donations_locus = clone_phenotype.num_donations_locus;
1290   num_donations_locus_last = clone_phenotype.num_donations_locus_last;
1291 
1292   // Setup flags...
1293   is_injected   = false;
1294   is_donor_last = clone_phenotype.is_donor_last;
1295   is_donor_cur  = clone_phenotype.is_donor_cur;
1296   is_receiver = false;
1297   is_donor_rand_last = clone_phenotype.is_donor_rand_last;
1298   is_donor_rand  = clone_phenotype.is_donor_rand;
1299   is_donor_null_last = clone_phenotype.is_donor_null_last;
1300   is_donor_null  = clone_phenotype.is_donor_null;
1301   is_donor_kin_last = clone_phenotype.is_donor_kin_last;
1302   is_donor_kin  = clone_phenotype.is_donor_kin;
1303   is_donor_edit_last = clone_phenotype.is_donor_edit_last;
1304   is_donor_edit  = clone_phenotype.is_donor_edit;
1305   is_donor_gbg_last = clone_phenotype.is_donor_gbg_last;
1306   is_donor_gbg  = clone_phenotype.is_donor_gbg;
1307   is_donor_truegb_last = clone_phenotype.is_donor_truegb_last;
1308   is_donor_truegb  = clone_phenotype.is_donor_truegb;
1309   is_donor_threshgb_last = clone_phenotype.is_donor_threshgb_last;
1310   is_donor_threshgb  = clone_phenotype.is_donor_threshgb;
1311   is_donor_quanta_threshgb_last = clone_phenotype.is_donor_quanta_threshgb_last;
1312   is_donor_quanta_threshgb  = clone_phenotype.is_donor_quanta_threshgb;
1313   is_donor_shadedgb_last = clone_phenotype.is_donor_shadedgb_last;
1314   is_donor_shadedgb  = clone_phenotype.is_donor_shadedgb;
1315   is_donor_locus_last = clone_phenotype.is_donor_locus_last;
1316   is_donor_locus = clone_phenotype.is_donor_locus;
1317 
1318   is_receiver = clone_phenotype.is_receiver;
1319   is_receiver_last = clone_phenotype.is_receiver_last;
1320   is_receiver_rand = clone_phenotype.is_receiver_rand;
1321   is_receiver_kin = clone_phenotype.is_receiver_kin;
1322   is_receiver_kin_last = clone_phenotype.is_receiver_kin_last;
1323   is_receiver_edit = clone_phenotype.is_receiver_edit;
1324   is_receiver_edit_last = clone_phenotype.is_receiver_edit_last;
1325   is_receiver_gbg = clone_phenotype.is_receiver_gbg;
1326   is_receiver_truegb = clone_phenotype.is_receiver_truegb;
1327   is_receiver_truegb_last = clone_phenotype.is_receiver_truegb_last;
1328   is_receiver_threshgb = clone_phenotype.is_receiver_threshgb;
1329   is_receiver_threshgb_last = clone_phenotype.is_receiver_threshgb_last;
1330   is_receiver_quanta_threshgb = clone_phenotype.is_receiver_quanta_threshgb;
1331   is_receiver_quanta_threshgb_last = clone_phenotype.is_receiver_quanta_threshgb_last;
1332   is_receiver_shadedgb = clone_phenotype.is_receiver_shadedgb;
1333   is_receiver_shadedgb_last = clone_phenotype.is_receiver_shadedgb_last;
1334   is_receiver_gb_same_locus = clone_phenotype.is_receiver_gb_same_locus;
1335 
1336   is_modifier   = false;
1337   is_modified   = false;
1338   is_fertile    = clone_phenotype.last_child_fertile;
1339   is_mutated    = false;
1340   is_multi_thread = clone_phenotype.is_multi_thread;
1341   parent_true   = clone_phenotype.copy_true;
1342   parent_sex    = clone_phenotype.divide_sex;
1343   parent_cross_num    = clone_phenotype.cross_num;
1344   to_die = false;
1345   to_delete = false;
1346   is_energy_requestor = false;
1347   is_energy_donor = false;
1348   is_energy_receiver = false;
1349   has_used_donated_energy = false;
1350   has_open_energy_request = false;
1351 
1352   // Setup child info...
1353   copy_true          = false;
1354   divide_sex         = false;
1355   mate_select_id     = 0;
1356   cross_num          = 0;
1357   last_child_fertile = is_fertile;
1358   child_fertile      = true;
1359   child_copied_size  = 0;
1360   permanent_germline_propensity = clone_phenotype.permanent_germline_propensity;
1361 
1362   initialized = true;
1363 }
1364 
1365 
1366 
1367 
TestInput(tBuffer<int> & inputs,tBuffer<int> & outputs)1368 bool cPhenotype::TestInput(tBuffer<int>& inputs, tBuffer<int>& outputs)
1369 {
1370   assert(initialized == true);
1371   // For the moment, lets not worry about inputs...
1372   return false; // Nothing happened...
1373 }
1374 
TestOutput(cAvidaContext & ctx,cTaskContext & taskctx,const tArray<double> & res_in,const tArray<double> & rbins_in,tArray<double> & res_change,tArray<cString> & insts_triggered,bool is_parasite,cContextPhenotype * context_phenotype)1375 bool cPhenotype::TestOutput(cAvidaContext& ctx, cTaskContext& taskctx,
1376                             const tArray<double>& res_in, const tArray<double>& rbins_in,
1377                             tArray<double>& res_change, tArray<cString>& insts_triggered,
1378                             bool is_parasite, cContextPhenotype* context_phenotype)
1379 {
1380   assert(initialized == true);
1381   taskctx.SetTaskStates(&m_task_states);
1382 
1383   const cEnvironment& env = m_world->GetEnvironment();
1384   const int num_resources = env.GetResourceLib().GetSize();
1385   const int num_tasks = env.GetNumTasks();
1386   const int num_reactions = env.GetReactionLib().GetSize();
1387 
1388   // For refractory period @WRE 03-20-07
1389   const int cur_update_time = m_world->GetStats().GetUpdate();
1390   const double task_refractory_period = m_world->GetConfig().TASK_REFRACTORY_PERIOD.Get();
1391   double refract_factor;
1392 
1393   if (!m_reaction_result) m_reaction_result = new cReactionResult(num_resources, num_tasks, num_reactions);
1394   cReactionResult& result = *m_reaction_result;
1395 
1396   // Run everything through the environment.
1397   bool found = env.TestOutput(ctx, result, taskctx, eff_task_count, cur_reaction_count, res_in, rbins_in,
1398                               is_parasite, context_phenotype); //NEED different eff_task_count and cur_reaction_count for deme resource
1399 
1400   // If nothing was found, stop here.
1401   if (found == false) {
1402     result.Invalidate();
1403     res_change.SetAll(0.0);
1404     return false;  // Nothing happened.
1405   }
1406 
1407   // Update the phenotype with the results...
1408   // Start with updating task and reaction counters
1409   for (int i = 0; i < num_tasks; i++) {
1410     // Calculate refractory period factor @WRE
1411     // Modify TaskQuality amount based on refractory period
1412     // Logistic equation using refractory period
1413     // in update units from configuration file.  @WRE 03-20-07, 04-17-07
1414 
1415     if (task_refractory_period == 0.0) {
1416       refract_factor = 1.0;
1417     } else {
1418       refract_factor = 1.0 - (1.0 / (1.0 + exp((cur_update_time - cur_task_time[i]) - task_refractory_period * 0.5)));
1419     }
1420 
1421     if (result.TaskDone(i) == true) {
1422       cur_task_count[i]++;
1423       eff_task_count[i]++;
1424 
1425       // Update parasite/host task tracking appropriately
1426       if (is_parasite) {
1427         cur_para_tasks[i]++;
1428       }
1429       else {
1430         cur_host_tasks[i]++;
1431       }
1432 
1433       if (context_phenotype != 0) {
1434         context_phenotype->GetTaskCounts()[i]++;
1435       }
1436       if (result.UsedEnvResource() == false) { cur_internal_task_count[i]++; }
1437 
1438       // if we want to generate an age-task histogram
1439       if (m_world->GetConfig().AGE_POLY_TRACKING.Get()) {
1440         m_world->GetStats().AgeTaskEvent(taskctx.GetOrganism()->GetID(), i, time_used);
1441       }
1442     }
1443 
1444     if (result.TaskQuality(i) > 0) {
1445       cur_task_quality[i] += result.TaskQuality(i) * refract_factor;
1446       if (result.UsedEnvResource() == false) {
1447         cur_internal_task_quality[i] += result.TaskQuality(i) * refract_factor;
1448       }
1449     }
1450 
1451     cur_task_value[i] = result.TaskValue(i);
1452     cur_task_time[i] = cur_update_time; // Find out time from context
1453   }
1454 
1455   for (int i = 0; i < num_tasks; i++) {
1456     if (result.TaskDone(i) && !last_task_count[i]) {
1457       m_world->GetStats().AddNewTaskCount(i);
1458       int prev_num_tasks = 0;
1459       int cur_num_tasks = 0;
1460       for (int j=0; j< num_tasks; j++) {
1461         if (last_task_count[j]>0) prev_num_tasks++;
1462         if (cur_task_count[j]>0) cur_num_tasks++;
1463       }
1464       m_world->GetStats().AddOtherTaskCounts(i, prev_num_tasks, cur_num_tasks);
1465     }
1466   }
1467 
1468   for (int i = 0; i < num_reactions; i++) {
1469     cur_reaction_add_reward[i] += result.GetReactionAddBonus(i);
1470     if (result.ReactionTriggered(i) && last_reaction_count[i]==0) {
1471       m_world->GetStats().AddNewReactionCount(i);
1472     }
1473     if (result.ReactionTriggered(i) == true) {
1474       if (context_phenotype != 0) {
1475         context_phenotype->GetReactionCounts()[i]++;
1476       }
1477       // If the organism has not performed this task,
1478       // then consider it to be a task switch.
1479       // If applicable, add in the penalty.
1480       switch (m_world->GetConfig().TASK_SWITCH_PENALTY_TYPE.Get()) {
1481         case 0: { // no penalty
1482           break;
1483         }
1484         case 1: { // "learning" cost
1485           int n_react = cur_reaction_count[i] -1;
1486           if (n_react < m_world->GetConfig().LEARNING_COUNT.Get()) {
1487             num_new_unique_reactions += ( m_world->GetConfig().LEARNING_COUNT.Get() - n_react);
1488           }
1489           break;
1490         }
1491         case 2: { // "retooling" cost
1492           if (last_task_id == -1) {
1493             last_task_id = i;
1494             last_task_time = time_used;
1495           }	else {
1496             // track time used if applicable
1497             int cur_time_used = time_used - last_task_time;
1498             last_task_time = time_used;
1499             m_world->GetStats().AddTaskSwitchTime(last_task_id, i, cur_time_used);
1500             if (last_task_id != i) {
1501               num_new_unique_reactions++;
1502               last_task_id = i;
1503             }
1504 
1505           }
1506           break;
1507         }
1508         case 3: { // centrifuge
1509           // task switching cost is calculated based on
1510           // the distance between the two tasks.
1511 
1512           int distance = abs(i - last_task_id);
1513           num_new_unique_reactions += distance;
1514           last_task_id = i;
1515 
1516           break;
1517         }
1518         default: {
1519           assert(false);
1520           break;
1521         }
1522       }
1523     }
1524   }
1525 
1526   // Update the merit bonus
1527   cur_bonus *= result.GetMultBonus();
1528   cur_bonus += result.GetAddBonus();
1529 
1530   // update the germline propensity
1531   cur_child_germline_propensity += result.GetAddGermline();
1532   cur_child_germline_propensity *= result.GetMultGermline();
1533 
1534   // Update deme merit (guard against running in the test CPU, where there is
1535   // no deme object.  Don't touch deme merit if there is no deme frac component.
1536   cDeme* deme = taskctx.GetOrganism()->GetDeme();
1537   if (deme) {
1538     if (result.GetActiveDeme()) {
1539       double deme_bonus = deme->GetHeritableDemeMerit().GetDouble();
1540       deme_bonus *= result.GetMultDemeBonus();
1541       deme_bonus += result.GetAddDemeBonus();
1542       deme->UpdateHeritableDemeMerit(deme_bonus);
1543     }
1544 
1545     //also count tasks/reactions
1546     for (int i = 0; i < num_tasks; i++) {
1547       if (result.TaskDone(i) == true) deme->AddCurTask(i);
1548     }
1549     for (int i = 0; i < num_reactions; i++) {
1550       if (result.ReactionTriggered(i) == true) deme->AddCurReaction(i);
1551     }
1552   }
1553 
1554   // Update the energy bonus
1555   cur_energy_bonus += result.GetAddEnergy();
1556 
1557   // Denote consumed resources...
1558   for (int i = 0; i < res_in.GetSize(); i++) {
1559     res_change[i] = result.GetProduced(i) - result.GetConsumed(i);
1560     res_consumed += result.GetConsumed(i);
1561   }
1562 
1563   // Update rbins as necessary
1564   if (result.UsedEnvResource() == false) {
1565     double rbin_diff;
1566     for (int i = 0; i < num_resources; i++) {
1567       rbin_diff = result.GetInternalConsumed(i) - result.GetInternalProduced(i); ;
1568       cur_rbins_avail[i] -= rbin_diff;
1569       if(rbin_diff != 0) { cur_rbins_total[i] += rbin_diff; }
1570     }
1571   }
1572 
1573   // Save the instructions that should be triggered...
1574   insts_triggered = result.GetInstArray();
1575 
1576   //Put in detected resources
1577   for (int j = 0; j < res_in.GetSize(); j++) {
1578     if(result.GetDetected(j) != -1.0) {
1579       sensed_resources[j] = result.GetDetected(j);
1580     }
1581   }
1582 
1583   //Kill any cells that did lethal reactions
1584   to_die = result.GetLethal();
1585 
1586   // Sterilize organisms that have performed a sterilizing task.
1587   if(result.GetSterilize()) {
1588     is_fertile = false;
1589   }
1590 
1591   result.Invalidate();
1592   return true;
1593 }
1594 
1595 
Sterilize()1596 void cPhenotype::Sterilize()
1597 {
1598   is_fertile = false;
1599 }
1600 
1601 
PrintStatus(ostream & fp) const1602 void cPhenotype::PrintStatus(ostream& fp) const
1603 {
1604   fp << "  MeritBase:"
1605   << CalcSizeMerit()
1606   << " Bonus:" << cur_bonus
1607   << " Errors:" << cur_num_errors
1608   << " Donates:" << cur_num_donates
1609   << '\n';
1610 
1611   fp << "  Task Count (Quality):";
1612   for (int i = 0; i < cur_task_count.GetSize(); i++) {
1613     fp << " " << cur_task_count[i] << " (" << cur_task_quality[i] << ")";
1614   }
1615   fp << '\n';
1616 
1617   // if using resoruce bins, print the relevant stats
1618   if (m_world->GetConfig().USE_RESOURCE_BINS.Get()) {
1619     fp << "  Used-Internal-Resources Task Count (Quality):";
1620     for (int i = 0; i < cur_internal_task_count.GetSize(); i++) {
1621       fp << " " << cur_internal_task_count[i] << " (" << cur_internal_task_quality[i] << ")";
1622     }
1623     fp << endl;
1624 
1625     fp << "  Available Internal Resource Bin Contents (Total Ever Collected):";
1626     for(int i = 0; i < cur_rbins_avail.GetSize(); i++) {
1627       fp << " " << cur_rbins_avail[i] << " (" << cur_rbins_total[i] << ")";
1628     }
1629     fp << endl;
1630   }
1631 }
1632 
CalcSizeMerit() const1633 int cPhenotype::CalcSizeMerit() const
1634 {
1635   assert(genome_length > 0);
1636   assert(copied_size > 0);
1637 
1638   int out_size;
1639 
1640   switch (m_world->GetConfig().BASE_MERIT_METHOD.Get()) {
1641     case BASE_MERIT_COPIED_SIZE:
1642       out_size = copied_size;
1643       break;
1644     case BASE_MERIT_EXE_SIZE:
1645       out_size = executed_size;
1646       break;
1647     case BASE_MERIT_FULL_SIZE:
1648       out_size = genome_length;
1649       break;
1650     case BASE_MERIT_LEAST_SIZE:
1651       out_size = genome_length;
1652       if (out_size > copied_size) out_size = copied_size;
1653       if (out_size > executed_size)    out_size = executed_size;
1654       break;
1655     case BASE_MERIT_SQRT_LEAST_SIZE:
1656       out_size = genome_length;
1657       if (out_size > copied_size) out_size = copied_size;
1658       if (out_size > executed_size)    out_size = executed_size;
1659       out_size = (int) sqrt((double) out_size);
1660       break;
1661     case BASE_MERIT_NUM_BONUS_INST:
1662       if (m_world->GetConfig().FITNESS_VALLEY.Get()){
1663         if (bonus_instruction_count >= m_world->GetConfig().FITNESS_VALLEY_START.Get() &&
1664             bonus_instruction_count <= m_world->GetConfig().FITNESS_VALLEY_STOP.Get()){
1665           out_size = 1;
1666           break;
1667         }
1668       }
1669       if (m_world->GetConfig().MERIT_BONUS_EFFECT.Get()>0) {
1670         out_size = 1 + bonus_instruction_count;
1671       }
1672       else if (m_world->GetConfig().MERIT_BONUS_EFFECT.Get()<0) {
1673         out_size = genome_length - (bonus_instruction_count -1);
1674       }
1675       else {
1676         out_size = 1; // The extra 1 point is so the orgs are not jilted by the scheduler.
1677       }
1678       break;
1679     case BASE_MERIT_GESTATION_TIME:
1680       out_size = cpu_cycles_used;
1681       break;
1682     case BASE_MERIT_CONST:
1683     default:
1684       out_size = m_world->GetConfig().BASE_CONST_MERIT.Get();
1685       break;
1686   }
1687 
1688   return out_size;
1689 }
1690 
CalcCurrentMerit() const1691 double cPhenotype::CalcCurrentMerit() const
1692 {
1693   int merit_base = CalcSizeMerit();
1694 
1695   return merit_base * cur_bonus;
1696 }
1697 
1698 
CalcFitness(double _merit_base,double _bonus,int _gestation_time,int _cpu_cycles) const1699 double cPhenotype::CalcFitness(double _merit_base, double _bonus, int _gestation_time, int _cpu_cycles) const
1700 {
1701   double out_fitness = 0;
1702   switch (m_world->GetConfig().FITNESS_METHOD.Get()) {
1703     case 0: // Normal
1704       assert(_gestation_time > 0);
1705       out_fitness = _merit_base * _bonus / _gestation_time;
1706       break;
1707 
1708     case 1: // Sigmoidal returns (should be used with an additive reward)
1709     {
1710       assert(_gestation_time > 0);
1711       out_fitness = 0;
1712       //Note: this operates on accumulated bonus and ignores the default bonus.
1713       double converted_bonus = (_bonus - m_world->GetConfig().DEFAULT_BONUS.Get()) * m_world->GetConfig().FITNESS_COEFF_2.Get() / (1 + _bonus * m_world->GetConfig().FITNESS_COEFF_2.Get() ) ;
1714       out_fitness = _merit_base * exp(converted_bonus * log(m_world->GetConfig().FITNESS_COEFF_1.Get())) / _gestation_time;
1715     }
1716       break;
1717 
1718     case 2: //Activity of one enzyme in pathway altered (with diminishing returns and a cost for each executed instruction)
1719     {
1720       out_fitness = 0;
1721       double net_bonus = _bonus +  - m_world->GetConfig().DEFAULT_BONUS.Get();
1722       out_fitness = net_bonus / (net_bonus + 1)* exp (_gestation_time * log(1 - m_world->GetConfig().FITNESS_COEFF_1.Get()));
1723     }
1724       break;
1725 
1726     default:
1727       cout << "Unknown FITNESS_METHOD!" << endl;
1728       exit(1);
1729   }
1730 
1731   return out_fitness;
1732 }
1733 
1734 /* Returns the organism's total tolerance towards immigrants by counting
1735  the total number of dec-tolerance entries within the update window that have been executed.
1736  */
CalcToleranceImmigrants()1737 int cPhenotype::CalcToleranceImmigrants()
1738 {
1739   const int cur_update = m_world->GetStats().GetUpdate();
1740   const int tolerance_max = m_world->GetConfig().MAX_TOLERANCE.Get();
1741 
1742   // Check if cached value is up-to-date, return
1743   if (m_intolerances[0].first == cur_update) return tolerance_max - m_intolerances[0].second;
1744 
1745   const int update_window = m_world->GetConfig().TOLERANCE_WINDOW.Get();
1746   // Update the tolerance list by getting rid of outdated records
1747   while (m_tolerance_immigrants.GetSize() && *m_tolerance_immigrants.GetLast() < cur_update - update_window)
1748     delete m_tolerance_immigrants.PopRear();
1749 
1750   // And prune the list down to MAX_TOLERANCE entries.
1751   while (m_tolerance_immigrants.GetSize() > tolerance_max)
1752     delete m_tolerance_immigrants.PopRear();
1753 
1754   const int tolerance = tolerance_max - m_tolerance_immigrants.GetSize();
1755 
1756   // Update cached values
1757   m_intolerances[0].first = cur_update;
1758   m_intolerances[0].second = m_tolerance_immigrants.GetSize();
1759   return tolerance;
1760 }
1761 
1762 /* Returns the organism's total tolerance towards the organism's own offspring by counting
1763  the total number of dec-tolerance entries within the update window that have been executed.
1764  */
CalcToleranceOffspringOwn()1765 int cPhenotype::CalcToleranceOffspringOwn()
1766 {
1767   const int cur_update = m_world->GetStats().GetUpdate();
1768   const int tolerance_max = m_world->GetConfig().MAX_TOLERANCE.Get();
1769 
1770   // If offspring tolerances off, skip calculations returning max
1771   if (m_world->GetConfig().TOLERANCE_VARIATIONS.Get() > 0) return tolerance_max;
1772 
1773   // Check if cached value is up-to-date, return
1774   if (m_intolerances[1].first == cur_update) return tolerance_max - m_intolerances[1].second;
1775 
1776   const int update_window = m_world->GetConfig().TOLERANCE_WINDOW.Get();
1777 
1778   // Update the tolerance list by getting rid of outdated records
1779   while (m_tolerance_offspring_own.GetSize() && *m_tolerance_offspring_own.GetLast() < cur_update - update_window)
1780     delete m_tolerance_offspring_own.PopRear();
1781 
1782   // And prune the list down to MAX_TOLERANCE entries.
1783   while (m_tolerance_offspring_own.GetSize() > tolerance_max)
1784     delete m_tolerance_offspring_own.PopRear();
1785 
1786   const int tolerance = tolerance_max - m_tolerance_offspring_own.GetSize();
1787 
1788   // Update cached values
1789   m_intolerances[1].first = cur_update;
1790   m_intolerances[1].second = m_tolerance_offspring_own.GetSize();
1791   return tolerance;
1792 }
1793 
1794 /* Returns the organism's total tolerance towards the offspring of others in the group by counting
1795  the total number of dec-tolerance entries within the update window that have been executed.
1796  */
CalcToleranceOffspringOthers()1797 int cPhenotype::CalcToleranceOffspringOthers()
1798 {
1799   const int cur_update = m_world->GetStats().GetUpdate();
1800   const int tolerance_max = m_world->GetConfig().MAX_TOLERANCE.Get();
1801 
1802   // If offspring tolerances off, skip calculations returning max
1803   if (m_world->GetConfig().TOLERANCE_VARIATIONS.Get() > 0) return tolerance_max;
1804 
1805   // Check if cached value is up-to-date, return
1806   if (m_intolerances[2].first == cur_update) return tolerance_max - m_intolerances[2].second;
1807 
1808   const int update_window = m_world->GetConfig().TOLERANCE_WINDOW.Get();
1809 
1810   // Update the tolerance list by getting rid of outdated records
1811   while (m_tolerance_offspring_others.GetSize() && *m_tolerance_offspring_others.GetLast() < cur_update - update_window)
1812     delete m_tolerance_offspring_others.PopRear();
1813 
1814   // And prune the list down to MAX_TOLERANCE entries.
1815   while (m_tolerance_offspring_others.GetSize() > tolerance_max)
1816     delete m_tolerance_offspring_others.PopRear();
1817 
1818   const int tolerance = tolerance_max - m_tolerance_offspring_others.GetSize();
1819 
1820   // Update cached values
1821   m_intolerances[2].first = cur_update;
1822   m_intolerances[2].second = m_tolerance_offspring_others.GetSize();
1823   return tolerance;
1824 }
1825 
ReduceEnergy(const double cost)1826 void cPhenotype::ReduceEnergy(const double cost) {
1827   SetEnergy(energy_store - cost);
1828 }
1829 
SetEnergy(const double value)1830 void cPhenotype::SetEnergy(const double value) {
1831   energy_store = max(0.0, min(value, m_world->GetConfig().ENERGY_CAP.Get()));
1832 }
1833 
DoubleEnergyUsage()1834 void cPhenotype::DoubleEnergyUsage() {
1835   executionRatio *= 2.0;
1836 }
1837 
HalveEnergyUsage()1838 void cPhenotype::HalveEnergyUsage() {
1839   executionRatio *= 0.5;
1840 }
1841 
DefaultEnergyUsage()1842 void cPhenotype::DefaultEnergyUsage() {
1843   executionRatio = 1.0;
1844 }
1845 
DivideFailed()1846 void cPhenotype::DivideFailed() {
1847   num_divides_failed++;
1848 }
1849 
1850 
1851 /**
1852  Credit organism with energy reward, but only update energy store if APPLY_ENERGY_METHOD = "on task completion" (1)
1853  */
RefreshEnergy()1854 void cPhenotype::RefreshEnergy() {
1855   if(cur_energy_bonus > 0) {
1856     if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 0 || // on divide
1857        m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 2) {  // on sleep
1858       energy_tobe_applied += cur_energy_bonus;
1859     } else if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 1) {
1860       SetEnergy(energy_store + cur_energy_bonus);
1861       m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
1862       energy_testament = 0.0;
1863     } else {
1864       cerr<< "Unknown APPLY_ENERGY_METHOD value " << m_world->GetConfig().APPLY_ENERGY_METHOD.Get();
1865       exit(-1);
1866     }
1867     cur_energy_bonus = 0;
1868   }
1869 }
1870 
ApplyToEnergyStore()1871 void cPhenotype::ApplyToEnergyStore() {
1872   SetEnergy(energy_store + energy_tobe_applied);
1873   m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
1874   energy_testament = 0.0;
1875   energy_tobe_applied = 0.0;
1876   energy_testament = 0.0;
1877 }
1878 
EnergyTestament(const double value)1879 void cPhenotype::EnergyTestament(const double value) {
1880   assert(value > 0.0);
1881   energy_tobe_applied += value;
1882   energy_testament += value;
1883 } //! external energy given to organism
1884 
1885 
ApplyDonatedEnergy()1886 void cPhenotype::ApplyDonatedEnergy() {
1887   double energy_cap = m_world->GetConfig().ENERGY_CAP.Get();
1888 
1889   if((energy_store + energy_received_buffer) >= energy_cap) {
1890     IncreaseEnergyApplied(energy_cap - energy_store);
1891     SetEnergy(energy_store + (energy_cap - energy_received_buffer));
1892   } else {
1893     IncreaseEnergyApplied(energy_received_buffer);
1894     SetEnergy(energy_store + energy_received_buffer);
1895   }
1896 
1897   IncreaseNumEnergyApplications();
1898   SetHasUsedDonatedEnergy();
1899 
1900   energy_received_buffer = 0.0;
1901 
1902 } //End AppplyDonatedEnergy()
1903 
1904 
ReceiveDonatedEnergy(const double donation)1905 void cPhenotype::ReceiveDonatedEnergy(const double donation) {
1906   assert(donation >= 0.0);
1907   energy_received_buffer += donation;
1908   IncreaseEnergyReceived(donation);
1909   SetIsEnergyReceiver();
1910   IncreaseNumEnergyReceptions();
1911 } //End ReceiveDonatedEnergy()
1912 
1913 
ExtractParentEnergy()1914 double cPhenotype::ExtractParentEnergy() {
1915   assert(m_world->GetConfig().ENERGY_ENABLED.Get() > 0);
1916   // energy model config variables
1917   double energy_given_at_birth = m_world->GetConfig().ENERGY_GIVEN_AT_BIRTH.Get();
1918   double frac_parent_energy_given_at_birth = m_world->GetConfig().FRAC_PARENT_ENERGY_GIVEN_TO_ORG_AT_BIRTH.Get();
1919   double frac_energy_decay_at_birth = m_world->GetConfig().FRAC_ENERGY_DECAY_AT_ORG_BIRTH.Get();
1920   double energy_cap = m_world->GetConfig().ENERGY_CAP.Get();
1921 
1922   // apply energy if APPLY_ENERGY_METHOD is set to "on divide" (0)
1923   if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 0) {
1924     RefreshEnergy();
1925     ApplyToEnergyStore();
1926   }
1927 
1928   // decay of energy in parent
1929   ReduceEnergy(GetStoredEnergy() * frac_energy_decay_at_birth);
1930 
1931   // calculate energy to be given to child
1932   double child_energy = max(0.0, min(GetStoredEnergy() * frac_parent_energy_given_at_birth + energy_given_at_birth, energy_cap));
1933   assert(GetStoredEnergy()>0.0);
1934   // adjust energy in parent
1935   ReduceEnergy(child_energy - 2*energy_given_at_birth); // 2*energy_given_at_birth: 1 in child_energy & 1 for parent
1936 
1937   //TODO: add energy_given_at_birth to Stored_energy
1938   cMerit parentMerit(ConvertEnergyToMerit(GetStoredEnergy() * GetEnergyUsageRatio()));
1939   if (parentMerit.GetDouble() > 0.0) SetMerit(parentMerit);
1940   else SetToDie();
1941 
1942   return child_energy;
1943 }
1944 
1945 // Save the current fitness and reset relevant parts of the phenotype
NewTrial()1946 void cPhenotype::NewTrial()
1947 {
1948   //Return if a complete trial has not occurred.
1949   //(This will happen if CompeteOrganisms was called before in the same update
1950   if (trial_cpu_cycles_used == 0) return;
1951 
1952   //Record the merit of this trial
1953   fitness = CalcFitness( GetCurMeritBase(), GetCurBonus() , trial_time_used, trial_cpu_cycles_used); // This is a per-trial fitness @JEB
1954   cur_trial_fitnesses.Push(fitness);
1955   cur_trial_bonuses.Push(GetCurBonus());
1956   cur_trial_times_used.Push(trial_time_used);
1957 
1958   //The rest of the function, resets the phenotype like DivideReset(), but without
1959   //incrementing the generation or child statistics.
1960 
1961   //Most importantly, this does (below):
1962   // trial_time_used = 0;
1963   // trial_cpu_cycles_used = 0;
1964   // SetCurBonus(m_world->GetConfig().DEFAULT_BONUS.Get());
1965 
1966   // Update these values as needed...
1967   int cur_merit_base = CalcSizeMerit();
1968 
1969   // If we are resetting the current merit, do it here
1970   // and it will also be propagated to the child
1971   int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
1972   if (merit_default_bonus) {
1973     cur_bonus = merit_default_bonus;
1974   }
1975   merit = cur_merit_base * cur_bonus;
1976 
1977   // update energy store
1978   energy_store += cur_energy_bonus;
1979   energy_store = m_world->GetConfig().ENERGY_GIVEN_AT_BIRTH.Get(); // We reset to what they had at birth
1980   cur_energy_bonus = 0;
1981   // to be perfectly accurate, this should be from a last_energy value??
1982 
1983 
1984   // genome_length   = _genome.GetSize();  //No child! @JEB
1985   (void) copied_size;          // Unchanged
1986   (void) executed_size;        // Unchanged
1987   gestation_time  = time_used - gestation_start;  //Keep gestation referring to actual replication time! @JEB
1988   gestation_start = time_used;                    //Keep gestation referring to actual replication time! @JEB
1989   // fitness         = merit.GetDouble() / gestation_time; //Use fitness measure that is per-trial @JEB
1990 
1991   // Lock in cur values as last values.
1992   last_merit_base           = cur_merit_base;
1993   last_bonus                = cur_bonus;
1994   last_cpu_cycles_used      = cpu_cycles_used;
1995   //TODO?  last_energy         = cur_energy_bonus;
1996   last_num_errors           = cur_num_errors;
1997   last_num_donates          = cur_num_donates;
1998   last_task_count           = cur_task_count;
1999   last_host_tasks           = cur_host_tasks;
2000   last_para_tasks           = cur_para_tasks;
2001   last_internal_task_count  = cur_internal_task_count;
2002   last_task_quality         = cur_task_quality;
2003   last_internal_task_quality= cur_internal_task_quality;
2004   last_task_value			      = cur_task_value;
2005   last_rbins_total          = cur_rbins_total;
2006   last_rbins_avail          = cur_rbins_avail;
2007   last_collect_spec_counts  = cur_collect_spec_counts;
2008   last_reaction_count       = cur_reaction_count;
2009   last_reaction_add_reward  = cur_reaction_add_reward;
2010   last_inst_count           = cur_inst_count;
2011   last_sense_count          = cur_sense_count;
2012 
2013   // Reset cur values.
2014   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
2015   cpu_cycles_used = 0;
2016   cur_energy_bonus = 0.0;
2017   cur_num_errors  = 0;
2018   cur_num_donates  = 0;
2019   cur_task_count.SetAll(0);
2020   cur_host_tasks.SetAll(0);
2021   cur_para_tasks.SetAll(0);
2022   cur_internal_task_count.SetAll(0);
2023   eff_task_count.SetAll(0);
2024   cur_task_quality.SetAll(0);
2025   cur_internal_task_quality.SetAll(0);
2026   cur_task_value.SetAll(0);
2027   cur_rbins_total.SetAll(0);
2028   cur_rbins_avail.SetAll(0);
2029   cur_collect_spec_counts.SetAll(0);
2030   cur_reaction_count.SetAll(0);
2031   first_reaction_cycles.SetAll(-1);
2032   first_reaction_execs.SetAll(-1);
2033   cur_stolen_reaction_count.SetAll(0);
2034   cur_reaction_add_reward.SetAll(0);
2035   cur_inst_count.SetAll(0);
2036   cur_sense_count.SetAll(0);
2037   //cur_trial_fitnesses.Resize(0); Don't throw out the trial fitnesses! @JEB
2038   trial_time_used = 0;
2039   trial_cpu_cycles_used = 0;
2040   m_tolerance_immigrants.Clear();
2041   m_tolerance_offspring_own.Clear();
2042   m_tolerance_offspring_others.Clear();
2043   m_intolerances.SetAll(make_pair(-1, -1));
2044 
2045   // Setup other miscellaneous values...
2046   num_divides++;
2047   (void) generation;
2048   (void) time_used;
2049   num_execs       = 0;
2050   age             = 0;
2051   fault_desc      = "";
2052   (void) neutral_metric;
2053   life_fitness = fitness;
2054 
2055 
2056   num_thresh_gb_donations_last = num_thresh_gb_donations;
2057   num_thresh_gb_donations = 0;
2058   num_quanta_thresh_gb_donations_last = num_quanta_thresh_gb_donations;
2059   num_quanta_thresh_gb_donations = 0;
2060   num_shaded_gb_donations_last = num_shaded_gb_donations;
2061   num_shaded_gb_donations = 0;
2062   num_donations_locus_last = num_donations_locus;
2063   num_donations_locus = 0;
2064 
2065   // Leave flags alone...
2066   (void) is_injected;
2067   is_donor_last = is_donor_cur;
2068   is_donor_cur = false;
2069   is_donor_rand_last = is_donor_rand;
2070   is_donor_rand = false;
2071   is_donor_null_last = is_donor_null;
2072   is_donor_null = false;
2073   is_donor_kin_last = is_donor_kin;
2074   is_donor_kin = false;
2075   is_donor_edit_last = is_donor_edit;
2076   is_donor_edit = false;
2077   is_donor_gbg_last = is_donor_gbg;
2078   is_donor_gbg = false;
2079   is_donor_truegb_last = is_donor_truegb;
2080   is_donor_truegb = false;
2081   is_donor_threshgb_last = is_donor_threshgb;
2082   is_donor_threshgb = false;
2083   is_donor_quanta_threshgb_last = is_donor_quanta_threshgb;
2084   is_donor_quanta_threshgb = false;
2085   is_donor_shadedgb_last = is_donor_shadedgb;
2086   is_donor_shadedgb = false;
2087   is_donor_locus_last = is_donor_locus;
2088   is_donor_locus.SetAll(false);
2089 
2090   is_receiver_last = is_receiver;
2091   is_receiver = false;
2092   is_receiver_rand = false;
2093   is_receiver_kin_last = is_receiver_kin;
2094   is_receiver_kin = false;
2095   is_receiver_edit_last = is_receiver_edit;
2096   is_receiver_edit = false;
2097   is_receiver_gbg = false;
2098   is_receiver_truegb_last = is_receiver_truegb;
2099   is_receiver_truegb = false;
2100   is_receiver_threshgb_last = is_receiver_threshgb;
2101   is_receiver_threshgb = false;
2102   is_receiver_quanta_threshgb_last = is_receiver_quanta_threshgb;
2103   is_receiver_quanta_threshgb = false;
2104   is_receiver_shadedgb_last = is_receiver_shadedgb;
2105   is_receiver_shadedgb = false;
2106   is_receiver_gb_same_locus_last = is_receiver_gb_same_locus;
2107   is_receiver_gb_same_locus = false;
2108 
2109   is_energy_requestor = false;
2110   is_energy_donor = false;
2111   is_energy_receiver = false;
2112   (void) is_modifier;
2113   (void) is_modified;
2114   (void) is_fertile;
2115   (void) is_mutated;
2116   (void) is_multi_thread;
2117   (void) parent_true;
2118   (void) parent_sex;
2119   (void) parent_cross_num;
2120 }
2121 
2122 /**
2123  * This function is run to reset an organism whose task counts (etc) have already been moved from cur to last
2124  * by another call (like NewTrial). It is a subset of DivideReset @JEB
2125  **/
2126 
TrialDivideReset(const Sequence & _genome)2127 void cPhenotype::TrialDivideReset(const Sequence& _genome)
2128 {
2129   int cur_merit_base = CalcSizeMerit();
2130 
2131   // If we are resetting the current merit, do it here
2132   // and it will also be propagated to the child
2133   const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
2134   if (merit_default_bonus) {
2135     cur_bonus = merit_default_bonus;
2136   }
2137   merit = cur_merit_base * cur_bonus;
2138 
2139   SetEnergy(energy_store + cur_energy_bonus);
2140   m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
2141   energy_testament = 0.0;
2142 
2143   genome_length   = _genome.GetSize();
2144   gestation_start = time_used;
2145   cur_trial_fitnesses.Resize(0);
2146   cur_trial_bonuses.Resize(0);
2147   cur_trial_times_used.Resize(0);
2148 
2149   // Reset child info...
2150   (void) copy_true;
2151   (void) divide_sex;
2152   (void) mate_select_id;
2153   (void) cross_num;
2154   last_child_fertile = child_fertile;
2155   child_fertile     = true;
2156   (void) child_copied_size;
2157 
2158   // A few final changes if the parent was supposed to be be considered
2159   // a second child on the divide.
2160   if ((m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) || (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_BIRTH)) {
2161     gestation_start = 0;
2162     cpu_cycles_used = 0;
2163     time_used = 0;
2164     num_execs = 0;
2165     neutral_metric += m_world->GetRandom().GetRandNormal();
2166   }
2167 
2168   if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
2169     m_tolerance_immigrants.Clear();
2170     m_tolerance_offspring_own.Clear();
2171     m_tolerance_offspring_others.Clear();
2172     m_intolerances.SetAll(make_pair(-1,-1));
2173   }
2174 
2175   if (m_world->GetConfig().GENERATION_INC_METHOD.Get() == GENERATION_INC_BOTH) generation++;
2176 }
2177 
2178 // Arbitrary (but consistant) ordering.
2179 // Return -1 if lhs is "less", +1 is it is "greater", and 0 otherwise.
Compare(const cPhenotype * lhs,const cPhenotype * rhs)2180 int cPhenotype::Compare(const cPhenotype* lhs, const cPhenotype* rhs) {
2181   // Compare first based on merit...
2182   if ( lhs->GetMerit() < rhs->GetMerit() ) return -1;
2183   else if ( lhs->GetMerit() > rhs->GetMerit() ) return 1;
2184 
2185   // If merits are equal, compare gestation time...
2186   if ( lhs->GetGestationTime() < rhs->GetGestationTime() ) return -1;
2187   else if ( lhs->GetGestationTime() > rhs->GetGestationTime() ) return 1;
2188 
2189   // If gestation times are also equal, compare each task
2190   tArray<int> lhsTasks = lhs->GetLastTaskCount();
2191   tArray<int> rhsTasks = rhs->GetLastTaskCount();
2192   for (int k = 0; k < lhsTasks.GetSize(); k++) {
2193     if (lhsTasks[k] < rhsTasks[k]) return -1;
2194     else if (lhsTasks[k] > rhsTasks[k]) return 1;
2195   }
2196 
2197   // Assume they are identical.
2198   return 0;
2199 }
2200 
operator ()(const cPhenotype * lhs,const cPhenotype * rhs) const2201 bool cPhenotype::PhenotypeCompare::operator()(const cPhenotype* lhs, const cPhenotype* rhs) const {
2202   return cPhenotype::Compare(lhs, rhs) < 0;
2203 }
2204 
2205 
2206 
2207 // Return an integer classifying the organism's energy level as -1=error,0=low,1=med,2=high
GetDiscreteEnergyLevel() const2208 int cPhenotype::GetDiscreteEnergyLevel() const {
2209   double max_energy = m_world->GetConfig().ENERGY_CAP.Get();
2210   double high_pct = m_world->GetConfig().ENERGY_THRESH_HIGH.Get();
2211   double low_pct = m_world->GetConfig().ENERGY_THRESH_LOW.Get();
2212 
2213   assert(max_energy >= 0);
2214   assert(high_pct <= 1);
2215   assert(high_pct >= 0);
2216   assert(low_pct <= 1);
2217   assert(low_pct >= 0);
2218   assert(low_pct <= high_pct);
2219 
2220   if (energy_store < (low_pct * max_energy)) {
2221     return ENERGY_LEVEL_LOW;
2222   } else if ( (energy_store >= (low_pct * max_energy)) && (energy_store <= (high_pct * max_energy)) ) {
2223     return ENERGY_LEVEL_MEDIUM;
2224   } else if (energy_store > (high_pct * max_energy)) {
2225     return ENERGY_LEVEL_HIGH;
2226   } else {
2227     return -1;
2228   }
2229 
2230 } //End GetDiscreteEnergyLevel()
2231 
2232 
ConvertEnergyToMerit(double energy) const2233 double cPhenotype::ConvertEnergyToMerit(double energy) const
2234 {
2235   assert(m_world->GetConfig().ENERGY_ENABLED.Get() == 1);
2236 
2237 	double FIX_METABOLIC_RATE = m_world->GetConfig().FIX_METABOLIC_RATE.Get();
2238 	if (FIX_METABOLIC_RATE > 0.0) return 100 * FIX_METABOLIC_RATE;
2239 
2240   return 100 * energy / m_world->GetConfig().NUM_CYCLES_EXC_BEFORE_0_ENERGY.Get();
2241 }
2242 
2243 
2244 
GetResourcesConsumed()2245 double cPhenotype::GetResourcesConsumed()
2246 {
2247 	double r = res_consumed;
2248 	res_consumed =0;
2249 	return r;
2250 }
2251 
2252 //Deep copy parasite task count
SetLastParasiteTaskCount(tArray<int> oldParaPhenotype)2253 void cPhenotype::SetLastParasiteTaskCount(tArray<int> oldParaPhenotype)
2254 {
2255   assert(initialized == true);
2256 
2257   for(int i=0;i<oldParaPhenotype.GetSize();i++)
2258   {
2259     last_para_tasks[i] = oldParaPhenotype[i];
2260   }
2261 }
2262 
2263 /* Return the cumulative reaction count if we aren't resetting on divide. */
GetCumulativeReactionCount()2264 tArray<int> cPhenotype::GetCumulativeReactionCount()
2265 {
2266   if (m_world->GetConfig().DIVIDE_METHOD.Get() == 0) {
2267     tArray<int> cum_react;
2268     for (int i=0; i<cur_reaction_count.GetSize(); ++i)
2269     {
2270       cum_react.Push(cur_reaction_count[i] + last_reaction_count[i]);
2271     }
2272 //    return (cur_reaction_count + last_reaction_count);
2273     return cum_react;
2274   } else {
2275     return cur_reaction_count;
2276   }
2277 }
2278