[Avida-SVN] r2520 - in development/source: . actions cpu main
barrick at myxo.css.msu.edu
barrick at myxo.css.msu.edu
Sun Apr 6 18:49:58 PDT 2008
Author: barrick
Date: 2008-04-06 21:49:58 -0400 (Sun, 06 Apr 2008)
New Revision: 2520
Modified:
development/source/actions/PrintActions.cc
development/source/cpu/cHardwareCPU.cc
development/source/cpu/cHardwareCPU.h
development/source/defs.h
development/source/main/cAvidaConfig.h
development/source/main/cDeme.cc
development/source/main/cDeme.h
development/source/main/cEnvironment.cc
development/source/main/cOrganism.cc
development/source/main/cOrganism.h
development/source/main/cPhenotype.cc
development/source/main/cPhenotype.h
development/source/main/cPopulation.cc
development/source/main/cPopulation.h
development/source/main/cReactionProcess.h
development/source/main/cReactionResult.cc
development/source/main/cReactionResult.h
development/source/main/cStats.cc
development/source/main/cStats.h
Log:
* Demes can elect certain orgs to function as germlines by completing "germline=1" reactions. Various methods for how this is handled. Still in flux.
* New statistics to track how many generations pass between deme founders. More variations on deme task stat files.
* Epigenetic inheritance modes - current register and stack information can be passed to child and/or mother. (Purpose: allow differentiation within deme seeded by single organism). Only implemented in cHardwareCPU.
Modified: development/source/actions/PrintActions.cc
===================================================================
--- development/source/actions/PrintActions.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/actions/PrintActions.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -99,6 +99,9 @@
STATS_OUT_FILE(PrintDemeTasks, deme_tasks.dat );
STATS_OUT_FILE(PrintDemeTasksExe, deme_tasks_exe.dat );
STATS_OUT_FILE(PrintDemeReactions, deme_reactions.dat );
+STATS_OUT_FILE(PrintDemeOrgTasks, deme_org_tasks.dat );
+STATS_OUT_FILE(PrintDemeOrgTasksExe, deme_org_tasks_exe.dat );
+STATS_OUT_FILE(PrintDemeOrgReactions, deme_org_reactions.dat );
STATS_OUT_FILE(PrintGermlineData, germline.dat );
// @WRE: Added output event for collected visit counts
STATS_OUT_FILE(PrintCellVisitsData, visits.dat );
@@ -2687,6 +2690,9 @@
action_lib->Register<cActionPrintDemeTasks>("PrintDemeTasksData");
action_lib->Register<cActionPrintDemeTasksExe>("PrintDemeTasksExeData");
action_lib->Register<cActionPrintDemeReactions>("PrintDemeReactionData");
+ action_lib->Register<cActionPrintDemeOrgTasks>("PrintDemeOrgTasksData");
+ action_lib->Register<cActionPrintDemeOrgTasksExe>("PrintDemeOrgTasksExeData");
+ action_lib->Register<cActionPrintDemeOrgReactions>("PrintDemeOrgReactionData");
//Coalescence Clade Actions
action_lib->Register<cActionPrintCCladeCounts>("PrintCCladeCounts");
Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/cpu/cHardwareCPU.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -425,6 +425,7 @@
/**/
m_spec_die = false;
+ m_epigenetic_state = false;
m_thread_slicing_parallel = (m_world->GetConfig().THREAD_SLICING_METHOD.Get() == 1);
m_no_cpu_cycle_time = m_world->GetConfig().NO_CPU_CYCLE_TIME.Get();
@@ -448,6 +449,7 @@
, m_mal_active(hardware_cpu.m_mal_active)
, m_advance_ip(hardware_cpu.m_advance_ip)
, m_executedmatchstrings(hardware_cpu.m_executedmatchstrings)
+, m_epigenetic_state(hardware_cpu.m_epigenetic_state)
{
#if INSTRUCTION_COSTS
m_inst_cost = hardware_cpu.m_inst_cost;
@@ -474,6 +476,14 @@
m_thread_id_chart = 1; // Mark only the first thread as taken...
m_cur_thread = 0;
+ // But then reset thread to have any epigenetic information we have saved
+ if (m_epigenetic_state) {
+ for (int i=0; i<NUM_REGISTERS; i++) {
+ m_threads[0].reg[i] = m_epigenetic_saved_reg[i];
+ }
+ m_threads[0].stack = m_epigenetic_saved_stack;
+ }
+
m_mal_active = false;
m_executedmatchstrings = false;
@@ -1353,6 +1363,12 @@
// Do more work if the parent lives through the birth of the offspring
if (parent_alive) {
+
+ if ( (m_world->GetConfig().EPIGENETIC_METHOD.Get() == EPIGENETIC_METHOD_PARENT)
+ || (m_world->GetConfig().EPIGENETIC_METHOD.Get() == EPIGENETIC_METHOD_BOTH) ) {
+ InheritState(*this);
+ }
+
if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) Reset();
}
@@ -1631,14 +1647,20 @@
return true;
}
-void cHardwareCPU::Divide_InheritState(cHardwareBase& in_hardware)
+// Sets the current state of the hardware and also saves this state so
+// that future Reset() calls will reset to that epigenetic state
+void cHardwareCPU::InheritState(cHardwareBase& in_hardware)
{
+ m_epigenetic_state = true;
+
cHardwareCPU& in_h = (cHardwareCPU&)in_hardware;
const cLocalThread& thread = in_h.GetThread(in_h.GetCurThread());
- m_threads[m_cur_thread].stack = thread.stack;
for (int i=0; i<NUM_REGISTERS; i++) {
- m_threads[m_cur_thread].reg[i] = thread.reg[i];
+ m_epigenetic_saved_reg[i] = thread.reg[i];
+ m_threads[m_cur_thread].reg[i] = m_epigenetic_saved_reg[i];
}
+ m_epigenetic_saved_stack = thread.stack;
+ m_threads[m_cur_thread].stack = m_epigenetic_saved_stack;
}
Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/cpu/cHardwareCPU.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -169,6 +169,12 @@
tArray<cPromoter> m_promoters;
// Promoter Model -->
+ // <-- Epigenetic State
+ bool m_epigenetic_state;
+ int m_epigenetic_saved_reg[NUM_REGISTERS];
+ cCPUStack m_epigenetic_saved_stack;
+ // Epigenetic State -->
+
bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
// -------- Stack Manipulation... --------
@@ -221,7 +227,7 @@
bool Divide_Main2RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
void Divide_DoTransposons(cAvidaContext& ctx);
- void Divide_InheritState(cHardwareBase& in_hardware);
+ void InheritState(cHardwareBase& in_hardware);
void InjectCode(const cGenome& injection, const int line_num);
Modified: development/source/defs.h
===================================================================
--- development/source/defs.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/defs.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -136,10 +136,16 @@
DIVIDE_METHOD_OFFSPRING = 0,
DIVIDE_METHOD_SPLIT,
DIVIDE_METHOD_BIRTH,
- DIVIDE_METHOD_KEEP_STATE,
- DIVIDE_METHOD_KEEP_STATE_EPIGENETIC
};
+enum eEPIGENETIC_METHOD
+{
+ EPIGENETIC_METHOD_NONE = 0,
+ EPIGENETIC_METHOD_OFFSPRING,
+ EPIGENETIC_METHOD_PARENT,
+ EPIGENETIC_METHOD_BOTH
+};
+
enum eINJECT_METHOD
{
INJECT_METHOD_OFFSPRING = 0,
Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cAvidaConfig.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -317,6 +317,8 @@
CONFIG_ADD_VAR(DEMES_NUM_X, int, 0, "Simulated number of demes in X dimension. Only used for migration. ");
CONFIG_ADD_VAR(DEMES_SEED_METHOD, int, 0, "Deme seeding method.\n0=maintain old consistency\n1=new method using genotypes");
CONFIG_ADD_VAR(DEMES_DIVIDE_METHOD, int, 0, "Deme divide method. Only works with DEMES_SEED_METHOD 1\n0=replace and target demes\n1= replace target deme, reset source deme to founders\n2=replace target deme, leave source deme unchanged");
+ CONFIG_ADD_VAR(DEMES_DEFAULT_GERMLINE_PROPENSITY, double, 0.0, "Default germline propensity of organisms in deme.\nFor use with DEMES_DIVIDE_METHOD 2.");
+ CONFIG_ADD_VAR(DEMES_FOUNDER_GERMLINE_PROPENSITY, double, -1.0, "Default germline propensity of founder organisms in deme.\nFor use with DEMES_DIVIDE_METHOD 2.\n <0 = OFF");
CONFIG_ADD_GROUP(REPRODUCTION_GROUP, "Birth and Death");
CONFIG_ADD_VAR(BIRTH_METHOD, int, 0, "Which organism should be replaced on birth?\n0 = Random organism in neighborhood\n1 = Oldest in neighborhood\n2 = Largest Age/Merit in neighborhood\n3 = None (use only empty cells in neighborhood)\n4 = Random from population (Mass Action)\n5 = Oldest in entire population\n6 = Random within deme\n7 = Organism faced by parent\n8 = Next grid cell (id+1)\n9 = Largest energy used in entire population\n10 = Largest energy used in neighborhood");
@@ -327,6 +329,7 @@
CONFIG_ADD_VAR(AGE_DEVIATION, int, 0, "Creates a distribution around AGE_LIMIT");
CONFIG_ADD_VAR(ALLOC_METHOD, int, 0, "(Orignal CPU Only)\n0 = Allocated space is set to default instruction.\n1 = Set to section of dead genome (Necrophilia)\n2 = Allocated space is set to random instruction.");
CONFIG_ADD_VAR(DIVIDE_METHOD, int, 1, "0 = Divide leaves state of mother untouched.\n1 = Divide resets state of mother\n (after the divide, we have 2 children)\n2 = Divide resets state of current thread only\n (does not touch possible parasite threads)\n3 = Divide resets mother stats, but not state.\n4 = 3 + child inherits mother registers and stack values.");
+ CONFIG_ADD_VAR(EPIGENETIC_METHOD, int, 0, "Inheritance of state information other than genome\n0 = none\n1 = offspring inherits registers and stacks of first thread\n1 = parent maintains registers and stacks of first thread\n\n1 = offspring and parent keep state information");
CONFIG_ADD_VAR(INJECT_METHOD, int, 0, "0 = Leaves the parasite thread state untouched.\n1 = Resets the calling thread state on inject");
CONFIG_ADD_VAR(GENERATION_INC_METHOD, int, 1, "0 = Only the generation of the child is\n increased on divide.\n1 = Both the generation of the mother and child are\n increased on divide (good with DIVIDE_METHOD 1).");
CONFIG_ADD_VAR(RESET_INPUTS_ON_DIVIDE, int, 0, "Reset environment inputs of parent upon successful divide.");
Modified: development/source/main/cDeme.cc
===================================================================
--- development/source/main/cDeme.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cDeme.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -45,15 +45,29 @@
const int num_tasks = m_world->GetEnvironment().GetNumTasks();
const int num_reactions = m_world->GetNumReactions();
- cur_task_count.Resize(num_tasks);
- cur_task_count.SetAll(0);
+
+ cur_task_exe_count.Resize(num_tasks);
+ cur_task_exe_count.SetAll(0);
cur_reaction_count.ResizeClear(num_reactions);
cur_reaction_count.SetAll(0);
- last_task_count.ResizeClear(num_tasks);
- last_task_count.SetAll(0);
+ last_task_exe_count.ResizeClear(num_tasks);
+ last_task_exe_count.SetAll(0);
last_reaction_count.ResizeClear(num_reactions);
last_reaction_count.SetAll(0);
+ cur_org_task_count.Resize(num_tasks);
+ cur_org_task_count.SetAll(0);
+ cur_org_task_exe_count.Resize(num_tasks);
+ cur_org_task_exe_count.SetAll(0);
+ cur_org_reaction_count.ResizeClear(num_reactions);
+ cur_org_reaction_count.SetAll(0);
+ last_org_task_count.ResizeClear(num_tasks);
+ last_org_task_count.SetAll(0);
+ last_org_task_exe_count.ResizeClear(num_tasks);
+ last_org_task_exe_count.SetAll(0);
+ last_org_reaction_count.ResizeClear(num_reactions);
+ last_org_reaction_count.SetAll(0);
+
// If width is negative, set it to the full number of cells.
width = in_width;
if (width < 1) width = cell_ids.GetSize();
@@ -143,7 +157,7 @@
birth_count = 0;
cur_normalized_time_used = 0;
- cur_task_count.SetAll(0);
+ cur_task_exe_count.SetAll(0);
cur_reaction_count.SetAll(0);
if(resetResources) deme_resource_count.ReinitializeResources();
@@ -152,18 +166,44 @@
void cDeme::DivideReset(cDeme& parent_deme, bool resetResources, double deme_energy)
{
+ // inherit last value from the parent
+ generations_per_lifetime = parent_deme.GetGenerationsPerLifetime();
+
+ // update our average founder generation
+ cDoubleSum gen;
+ for (int i=0; i< m_founder_phenotypes.GetSize(); i++) {
+ gen.Add( m_founder_phenotypes[i].GetGeneration() );
+ }
+ avg_founder_generation = gen.Average();
+
//Save statistics according to parent before reset.
generation = parent_deme.GetGeneration() + 1;
gestation_time = parent_deme.GetTimeUsed();
last_normalized_time_used = parent_deme.GetNormalizedTimeUsed();
- last_task_count = cur_task_count;
+ last_task_exe_count = cur_task_exe_count;
last_reaction_count = cur_reaction_count;
+ last_org_task_count = cur_org_task_count;
+ last_org_task_exe_count = cur_org_task_exe_count;
+ last_org_reaction_count = cur_org_reaction_count;
+
Reset(resetResources, deme_energy);
}
+// Given the input deme founders and original ones,
+// calculate how many generations this deme went through to divide.
+void cDeme::UpdateGenerationsPerLifetime(tArray<cPhenotype>& new_founder_phenotypes)
+{
+ cDoubleSum gen;
+ for (int i=0; i< new_founder_phenotypes.GetSize(); i++) {
+ gen.Add( new_founder_phenotypes[i].GetGeneration() );
+ }
+ double new_avg_founder_generation = gen.Average();
+ generations_per_lifetime = new_avg_founder_generation - avg_founder_generation;
+}
+
/*! Check every cell in this deme for a living organism. If found, kill it. */
void cDeme::KillAll()
{
@@ -175,7 +215,46 @@
}
}
+void cDeme::UpdateStats()
+{
+ //save stats about what tasks our orgs were doing
+ //usually called before KillAll
+
+ for(int j = 0; j < cur_org_task_count.GetSize(); j++) {
+ int count = 0;
+ for(int k=0; k<GetSize(); k++) {
+ int cellid = GetCellID(k);
+ if(m_world->GetPopulation().GetCell(cellid).IsOccupied()) {
+ count += (m_world->GetPopulation().GetCell(cellid).GetOrganism()->GetPhenotype().GetLastTaskCount()[j] > 0);
+ }
+ cur_org_task_count[j] = count;
+ }
+ }
+
+ for(int j = 0; j < cur_org_task_exe_count.GetSize(); j++) {
+ int count = 0;
+ for(int k=0; k<GetSize(); k++) {
+ int cellid = GetCellID(k);
+ if(m_world->GetPopulation().GetCell(cellid).IsOccupied()) {
+ count += m_world->GetPopulation().GetCell(cellid).GetOrganism()->GetPhenotype().GetLastTaskCount()[j];
+ }
+ cur_org_task_exe_count[j] = count;
+ }
+ }
+ for(int j = 0; j < cur_org_reaction_count.GetSize(); j++) {
+ int count = 0;
+ for(int k=0; k<GetSize(); k++) {
+ int cellid = GetCellID(k);
+ if(m_world->GetPopulation().GetCell(cellid).IsOccupied()) {
+ count += m_world->GetPopulation().GetCell(cellid).GetOrganism()->GetPhenotype().GetLastReactionCount()[j];
+ }
+ cur_org_reaction_count[j] = count;
+ }
+ }
+}
+
+
/*! Replacing this deme's germline has the effect of changing the deme's lineage.
There's still some work to do here; the lineage labels of the Genomes in the germline
are all messed up.
@@ -289,12 +368,17 @@
// --- Founder list management --- //
-void cDeme::AddFounder(cGenotype& _in_genotype) {
+void cDeme::AddFounder(cGenotype& _in_genotype, cPhenotype * _in_phenotype) {
+
// save genotype id
m_founder_genotype_ids.Push( _in_genotype.GetID() );
+ cPhenotype phenotype;
+ if (_in_phenotype) phenotype = *_in_phenotype;
+ m_founder_phenotypes.Push( phenotype );
// defer adjusting this genotype until we are done with it
_in_genotype.IncDeferAdjust();
+
}
void cDeme::ClearFounders() {
@@ -308,6 +392,7 @@
// empty our list
m_founder_genotype_ids.ResizeClear(0);
+ m_founder_phenotypes.ResizeClear(0);
}
void cDeme::ReplaceGermline(cGenotype& _in_genotype) {
Modified: development/source/main/cDeme.h
===================================================================
--- development/source/main/cDeme.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cDeme.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -26,6 +26,7 @@
#include "cDemeCellEvent.h"
#include "cGermline.h"
+#include "cPhenotype.h"
#include "cMerit.h"
#include "tArray.h"
#include "cResourceCount.h"
@@ -35,6 +36,7 @@
class cWorld;
class cPopulationCell;
class cGenotype;
+class cOrganism;
/*! Demes are groups of cells in the population that are somehow bound together
as a unit. The deme object is used from within cPopulation to manage these
@@ -59,11 +61,21 @@
double cur_normalized_time_used; // normalized by merit and number of orgs
double last_normalized_time_used;
- tArray<int> cur_task_count;
+ tArray<int> cur_task_exe_count;
tArray<int> cur_reaction_count;
- tArray<int> last_task_count;
+ tArray<int> last_task_exe_count;
tArray<int> last_reaction_count;
+ tArray<int> cur_org_task_count;
+ tArray<int> cur_org_task_exe_count;
+ tArray<int> cur_org_reaction_count;
+ tArray<int> last_org_task_count;
+ tArray<int> last_org_task_exe_count;
+ tArray<int> last_org_reaction_count;
+
+ double avg_founder_generation; //Average generation of current founders
+ double generations_per_lifetime; //Generations between current founders and founders of parent
+
// End of phenotypic traits
cGermline _germline; //!< The germline for this deme, if used.
@@ -78,6 +90,7 @@
int m_germline_genotype_id; // Genotype id of germline (if in use)
tArray<int> m_founder_genotype_ids; // List of genotype ids used to found deme.
// Keep a lease on these genotypes for the deme's lifetime.
+ tArray<cPhenotype> m_founder_phenotypes; // List of phenotypes of founder organsisms
cMerit _current_merit; //!< Deme merit applied to all organisms living in this deme.
cMerit _next_merit; //!< Deme merit that will be inherited upon deme replication.
@@ -85,6 +98,7 @@
public:
cDeme() : _id(0), width(0), birth_count(0), org_count(0), _age(0), generation(0), total_org_energy(0.0),
time_used(0), gestation_time(0), cur_normalized_time_used(0.0), last_normalized_time_used(0.0),
+ avg_founder_generation(0.0), generations_per_lifetime(0.0),
deme_resource_count(0), m_germline_genotype_id(0) { ; }
~cDeme() { ; }
@@ -106,6 +120,8 @@
//! Kills all organisms currently in this deme.
void KillAll();
+ void UpdateStats();
+
int GetBirthCount() const { return birth_count; }
void IncBirthCount() { birth_count++; }
@@ -136,12 +152,16 @@
const cMerit& GetHeritableDemeMerit() const { return _next_merit; }
- void AddCurTask(int task_num) { cur_task_count[task_num]++; }
+ void AddCurTask(int task_num) { cur_task_exe_count[task_num]++; }
void AddCurReaction (int reaction_num) { cur_reaction_count[reaction_num]++; }
- const tArray<int>& GetLastTaskCount() const { return last_task_count; }
+ const tArray<int>& GetLastTaskExeCount() const { return last_task_exe_count; }
const tArray<int>& GetLastReactionCount() const { return last_reaction_count; }
+ const tArray<int>& GetLastOrgTaskCount() const { return last_org_task_count; }
+ const tArray<int>& GetLastOrgTaskExeCount() const { return last_org_task_exe_count; }
+ const tArray<int>& GetLastOrgReactionCount() const { return last_org_reaction_count; }
+
bool HasDemeMerit() const { return _current_merit.GetDouble() != 1.0; }
// -= Update support =-
@@ -175,9 +195,13 @@
// --- Founder list management --- //
void ClearFounders();
- void AddFounder(cGenotype& _in_genotype);
- tArray<int>& GetFounders() { return m_founder_genotype_ids; }
-
+ void AddFounder(cGenotype& _in_genotype, cPhenotype * _in_phenotype = NULL);
+ tArray<int>& GetFounderGenotypeIDs() { return m_founder_genotype_ids; }
+ tArray<cPhenotype>& GetFounderPhenotypes() { return m_founder_phenotypes; }
+ double GetAvgFounderGeneration() { return avg_founder_generation; }
+ void UpdateGenerationsPerLifetime(tArray<cPhenotype>& new_founder_phenotypes);
+ double GetGenerationsPerLifetime() { return generations_per_lifetime; }
+
// --- Germline management --- //
void ReplaceGermline(cGenotype& _in_genotype);
int GetGermlineGenotypeID() { return m_germline_genotype_id; }
Modified: development/source/main/cEnvironment.cc
===================================================================
--- development/source/main/cEnvironment.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cEnvironment.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -212,6 +212,11 @@
return false;
new_process->SetDemeFraction(var_value.AsDouble());
}
+ else if (var_name == "germline") {
+ if (!AssertInputBool(var_value, "germline", var_type))
+ return false;
+ new_process->SetIsGermline(var_value.AsInt());
+ }
else if (var_name == "detect") {
cResource* test_resource = resource_lib.GetResource(var_value);
if (!AssertInputValid(test_resource, "product", var_type, var_value)) {
@@ -1027,57 +1032,87 @@
// Mark the reaction as having been performed if we get here.
result.MarkReaction(reaction_id);
- // How much of this bonus belongs to the deme, and how much belongs to the organism?
- double deme_bonus = cur_process->GetDemeFraction() * consumed * cur_process->GetValue();
- double bonus = (1.0 - cur_process->GetDemeFraction()) * consumed * cur_process->GetValue();
-
- // Take care of the organism's bonus:
- switch (cur_process->GetType()) {
- case nReaction::PROCTYPE_ADD:
- result.AddBonus(bonus, reaction_id);
- result.AddDemeBonus(deme_bonus);
- break;
- case nReaction::PROCTYPE_MULT:
- result.MultBonus(bonus);
- result.MultDemeBonus(deme_bonus);
- break;
- case nReaction::PROCTYPE_POW:
- result.MultBonus(pow(2.0, bonus));
- result.MultDemeBonus(pow(2.0, deme_bonus));
- break;
- case nReaction::PROCTYPE_LIN:
- result.AddBonus(bonus * task_count, reaction_id);
- assert(deme_bonus == 0.0);
- break;
- case nReaction::PROCTYPE_ENERGY:
- result.AddEnergy(bonus);
- assert(deme_bonus == 0.0);
- break;
- case nReaction::PROCTYPE_ENZYME: //@JEB
- {
- const int res_id = in_resource->GetID();
- assert(cur_process->GetMaxFraction() != 0);
- assert(resource_count[res_id] != 0);
- double reward = cur_process->GetValue() * resource_count[res_id] / (resource_count[res_id] + cur_process->GetMaxFraction());
- result.AddBonus( reward , reaction_id);
- break;
+ double bonus = consumed * cur_process->GetValue();
+
+ if (!cur_process->GetIsGermline())
+ {
+ // normal bonus
+ double deme_bonus = 0;
+
+ // How much of this bonus belongs to the deme, and how much belongs to the organism?
+ if (cur_process->GetDemeFraction()) {
+ deme_bonus = cur_process->GetDemeFraction() * bonus;
+ bonus = (1-cur_process->GetDemeFraction()) * bonus;
}
- case nReaction::PROCTYPE_EXP: //@JEB
- {
- // Cumulative rewards are Value * integral (exp (-MaxFraction * TaskCount))
- // Evaluate to get stepwise amount to add per task executed.
- assert(task_count >= 1);
- const double decay = cur_process->GetMaxFraction();
- const double value = cur_process->GetValue();
- result.AddBonus( value * (1.0 / decay) * ( exp((task_count-1) * decay) - exp(task_count * decay)), reaction_id );
- break;
+
+ // Take care of the organism's bonus:
+ switch (cur_process->GetType()) {
+ case nReaction::PROCTYPE_ADD:
+ result.AddBonus(bonus, reaction_id);
+ result.AddDemeBonus(deme_bonus);
+ break;
+ case nReaction::PROCTYPE_MULT:
+ result.MultBonus(bonus);
+ // @JEB: since deme_bonus is ZERO by default this will cause
+ // a problem if we unintentionally multiply the deme's bonus
+ // when we do not make a deme reaction, i.e. deme=0!
+ // Other cases ADD zero, so they don't necessarily need this check.
+ if (cur_process->GetDemeFraction()) result.MultDemeBonus(deme_bonus);
+ break;
+ case nReaction::PROCTYPE_POW:
+ result.MultBonus(pow(2.0, bonus));
+ result.MultDemeBonus(pow(2.0, deme_bonus));
+ break;
+ case nReaction::PROCTYPE_LIN:
+ result.AddBonus(bonus * task_count, reaction_id);
+ break;
+ case nReaction::PROCTYPE_ENERGY:
+ result.AddEnergy(bonus);
+ assert(deme_bonus == 0.0);
+ break;
+ case nReaction::PROCTYPE_ENZYME: //@JEB -- experimental
+ {
+ const int res_id = in_resource->GetID();
+ assert(cur_process->GetMaxFraction() != 0);
+ assert(resource_count[res_id] != 0);
+ double reward = cur_process->GetValue() * resource_count[res_id] / (resource_count[res_id] + cur_process->GetMaxFraction());
+ result.AddBonus( reward , reaction_id);
+ break;
+ }
+ case nReaction::PROCTYPE_EXP: //@JEB -- experimental
+ {
+ // Cumulative rewards are Value * integral (exp (-MaxFraction * TaskCount))
+ // Evaluate to get stepwise amount to add per task executed.
+ assert(task_count >= 1);
+ const double decay = cur_process->GetMaxFraction();
+ const double value = cur_process->GetValue();
+ result.AddBonus( value * (1.0 / decay) * ( exp((task_count-1) * decay) - exp(task_count * decay)), reaction_id );
+ break;
+ }
+
+ default:
+ assert(false); // Should not get here!
+ break;
}
-
- default:
- assert(false); // Should not get here!
- break;
- };
-
+ } else { // if (cur_process->GetIsGermline())
+ // @JEB -- this process changes germline propensities, not bonus
+ switch (cur_process->GetType()) {
+ case nReaction::PROCTYPE_ADD:
+ result.AddGermline(bonus);
+ break;
+ case nReaction::PROCTYPE_MULT:
+ result.MultGermline(bonus);
+ break;
+ case nReaction::PROCTYPE_POW:
+ result.MultGermline(pow(2.0, bonus));
+ break;
+
+ default:
+ assert(false); // Should not get here!
+ break;
+ }
+ }
+
// Determine detection events
cResource* detected = cur_process->GetDetect();
if (detected != NULL) {
Modified: development/source/main/cOrganism.cc
===================================================================
--- development/source/main/cOrganism.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cOrganism.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -266,8 +266,6 @@
//update deme resources
m_interface->UpdateDemeResources(deme_res_change);
- //if(m_world->GetConfig().CLEAR_ON_OUTPUT.Get()) input_buffer.Clear(); @JEB Not fully implemented
-
for (int i = 0; i < insts_triggered.GetSize(); i++) {
const int cur_inst = insts_triggered[i];
m_hardware->ProcessBonusInst(ctx, cInstruction(cur_inst));
Modified: development/source/main/cOrganism.h
===================================================================
--- development/source/main/cOrganism.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cOrganism.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -150,6 +150,7 @@
cGenotype* GetGenotype() const { return m_genotype; }
const cPhenotype& GetPhenotype() const { return m_phenotype; }
cPhenotype& GetPhenotype() { return m_phenotype; }
+ void SetPhenotype(cPhenotype& _in_phenotype) { m_phenotype = _in_phenotype; }
const cGenome& GetGenome() const { return m_initial_genome; }
Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cPhenotype.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -115,7 +115,8 @@
cur_sense_count = in_phen.cur_sense_count;
sensed_resources = in_phen.sensed_resources;
cur_task_time = in_phen.cur_task_time;
-
+ cur_child_germline_propensity = in_phen.cur_child_germline_propensity;
+
// Dynamically allocated m_task_states requires special handling
tList<cTaskState*> hash_values;
tList<void*> hash_keys;
@@ -142,7 +143,8 @@
last_inst_count = in_phen.last_inst_count;
last_sense_count = in_phen.last_sense_count;
last_fitness = in_phen.last_fitness;
-
+ last_child_germline_propensity = in_phen.last_child_germline_propensity;
+
// 4. Records from this organisms life...
num_divides = in_phen.num_divides;
generation = in_phen.generation;
@@ -211,6 +213,9 @@
child_fertile = in_phen.child_fertile;
last_child_fertile = in_phen.last_child_fertile;
child_copied_size = in_phen.child_copied_size;
+
+ // 7. Permanent information...
+ permanent_germline_propensity = in_phen.permanent_germline_propensity;
return *this;
}
@@ -295,7 +300,8 @@
cur_trial_times_used.Resize(0);
trial_time_used = 0;
trial_cpu_cycles_used = 0;
-
+ cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
+
// Copy last values from parent
last_merit_base = parent_phenotype.last_merit_base;
last_bonus = parent_phenotype.last_bonus;
@@ -304,12 +310,13 @@
last_num_donates = parent_phenotype.last_num_donates;
last_task_count = parent_phenotype.last_task_count;
last_task_quality = parent_phenotype.last_task_quality;
- last_task_value = parent_phenotype.last_task_value;
+ last_task_value = parent_phenotype.last_task_value;
last_reaction_count = parent_phenotype.last_reaction_count;
last_reaction_add_reward = parent_phenotype.last_reaction_add_reward;
last_inst_count = parent_phenotype.last_inst_count;
last_sense_count = parent_phenotype.last_sense_count;
last_fitness = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
+ last_child_germline_propensity = parent_phenotype.last_child_germline_propensity; // chance of child being a germline cell; @JEB
// Setup other miscellaneous values...
num_divides = 0;
@@ -381,6 +388,9 @@
child_fertile = true;
child_copied_size = 0;
+ // permanently set germline propensity of org (since DivideReset is called first, it is now in the "last" slot...)
+ permanent_germline_propensity = parent_phenotype.last_child_germline_propensity;
+
initialized = true;
}
@@ -429,7 +439,8 @@
cur_trial_times_used.Resize(0);
trial_time_used = 0;
trial_cpu_cycles_used = 0;
-
+ cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
+
// Copy last values from parent
last_merit_base = genome_length;
last_bonus = 1;
@@ -443,6 +454,7 @@
last_reaction_add_reward.SetAll(0);
last_inst_count.SetAll(0);
last_sense_count.SetAll(0);
+ last_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
// Setup other miscellaneous values...
num_divides = 0;
@@ -513,6 +525,8 @@
last_child_fertile = true;
child_copied_size = 0;
+ permanent_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
+
initialized = true;
}
@@ -561,6 +575,7 @@
last_reaction_add_reward = cur_reaction_add_reward;
last_inst_count = cur_inst_count;
last_sense_count = cur_sense_count;
+ last_child_germline_propensity = cur_child_germline_propensity;
// Reset cur values.
cur_bonus = m_world->GetConfig().DEFAULT_BONUS.Get();
@@ -577,6 +592,7 @@
cur_inst_count.SetAll(0);
cur_sense_count.SetAll(0);
cur_task_time.SetAll(0.0);
+ cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
// Setup other miscellaneous values...
num_divides++;
@@ -646,9 +662,7 @@
// A few final changes if the parent was supposed to be be considered
// a second child on the divide.
- if ( (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT)
- || (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_KEEP_STATE)
- || (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_KEEP_STATE_EPIGENETIC) ) {
+ if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
gestation_start = 0;
cpu_cycles_used = 0;
time_used = 0;
@@ -704,7 +718,8 @@
last_reaction_add_reward = cur_reaction_add_reward;
last_inst_count = cur_inst_count;
last_sense_count = cur_sense_count;
-
+ last_child_germline_propensity = cur_child_germline_propensity;
+
// Reset cur values.
cur_bonus = m_world->GetConfig().DEFAULT_BONUS.Get();
cpu_cycles_used = 0;
@@ -725,6 +740,7 @@
cur_trial_times_used.Resize(0);
trial_time_used = 0;
trial_cpu_cycles_used = 0;
+ cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
// Setup other miscellaneous values...
num_divides++;
@@ -846,6 +862,7 @@
cur_trial_times_used.Resize(0);
trial_time_used = 0;
trial_cpu_cycles_used = 0;
+ cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
// Copy last values from parent
last_merit_base = clone_phenotype.last_merit_base;
@@ -859,6 +876,7 @@
last_inst_count = clone_phenotype.last_inst_count;
last_sense_count = clone_phenotype.last_sense_count;
last_fitness = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
+ last_child_germline_propensity = clone_phenotype.last_child_germline_propensity;
// Setup other miscellaneous values...
num_divides = 0;
@@ -930,6 +948,7 @@
last_child_fertile = is_fertile;
child_fertile = true;
child_copied_size = 0;
+ permanent_germline_propensity = clone_phenotype.permanent_germline_propensity;
initialized = true;
}
@@ -1003,14 +1022,21 @@
cur_bonus *= result.GetMultBonus();
cur_bonus += result.GetAddBonus();
+ // update the germline propensity
+ cur_child_germline_propensity += result.GetAddGermline();
+ cur_child_germline_propensity *= result.GetMultGermline();
+
// Update deme merit (guard against running in the test CPU, where there is
// no deme object. Don't touch deme merit if there is no deme frac component.
cDeme* deme = taskctx.GetOrganism()->GetOrgInterface().GetDeme();
- if(deme && result.GetActiveDeme()) {
- double deme_bonus = deme->GetHeritableDemeMerit().GetDouble();
- deme_bonus *= result.GetMultDemeBonus();
- deme_bonus += result.GetAddDemeBonus();
- deme->UpdateHeritableDemeMerit(deme_bonus);
+ if(deme) {
+
+ if (result.GetActiveDeme()) {
+ double deme_bonus = deme->GetHeritableDemeMerit().GetDouble();
+ deme_bonus *= result.GetMultDemeBonus();
+ deme_bonus += result.GetAddDemeBonus();
+ deme->UpdateHeritableDemeMerit(deme_bonus);
+ }
//also count tasks/reactions
for (int i = 0; i < num_tasks; i++) {
@@ -1514,7 +1540,7 @@
cur_reaction_add_reward.SetAll(0);
cur_inst_count.SetAll(0);
cur_sense_count.SetAll(0);
- //cur_trial_fitnesses.Resize(0); Don't throw out the tiral fitnesses! @JEB
+ //cur_trial_fitnesses.Resize(0); Don't throw out the trial fitnesses! @JEB
trial_time_used = 0;
trial_cpu_cycles_used = 0;
@@ -1574,7 +1600,6 @@
(void) parent_true;
(void) parent_sex;
(void) parent_cross_num;
-
}
/**
@@ -1614,9 +1639,7 @@
// A few final changes if the parent was supposed to be be considered
// a second child on the divide.
- if ( (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT)
- || (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_KEEP_STATE)
- || (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_KEEP_STATE_EPIGENETIC) ) {
+ if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
gestation_start = 0;
cpu_cycles_used = 0;
time_used = 0;
Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cPhenotype.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -123,10 +123,11 @@
tHashTable<void*, cTaskState*> m_task_states;
tArray<double> cur_trial_fitnesses; // Fitnesses of various trials.; @JEB
tArray<double> cur_trial_bonuses; // Bonuses of various trials.; @JEB
- tArray<int> cur_trial_times_used; // Time used in of various trials.; @JEB
+ tArray<int> cur_trial_times_used; // Time used in of various trials.; @JEB
int trial_time_used; // like time_used, but reset every trial; @JEB
int trial_cpu_cycles_used; // like cpu_cycles_used, but reset every trial; @JEB
-
+ double last_child_germline_propensity; // chance of child being a germline cell; @JEB
+
// 3. These mark the status of "in progess" variables at the last divide.
double last_merit_base; // Either constant or based on genome length.
double last_bonus;
@@ -142,6 +143,7 @@
tArray<int> last_sense_count; // Total times resource combinations have been sensed; @JEB
double last_fitness; // Used to determine sterilization.
int last_cpu_cycles_used;
+ double cur_child_germline_propensity; // chance of child being a germline cell; @JEB
// 4. Records from this organisms life...
int num_divides; // Total successful divides organism has produced.
@@ -212,15 +214,14 @@
bool last_child_fertile; // Was the child being born to be fertile?
int child_copied_size; // Instruction copied into child.
-
- cPhenotype(); // @not_implemented
+ // 7. Information that is set once (when organism was born)
+ double permanent_germline_propensity;
-protected:
+public:
+ cPhenotype() { ; } // @not_implemented
+ cPhenotype(cWorld* world);
cPhenotype(const cPhenotype&);
cPhenotype& operator=(const cPhenotype&);
-
-public:
- cPhenotype(cWorld* world);
~cPhenotype();
bool OK();
@@ -320,6 +321,7 @@
const tArray<int>& GetLastInstCount() const { assert(initialized == true); return last_inst_count; }
const tArray<int>& GetLastSenseCount() const { assert(initialized == true); return last_sense_count; }
double GetLastFitness() const { assert(initialized == true); return last_fitness; }
+ double GetPermanentGermlinePropensity() const { assert(initialized == true); return permanent_germline_propensity; }
int GetNumDivides() const { assert(initialized == true); return num_divides;}
int GetGeneration() const { assert(initialized == true); return generation; }
@@ -392,6 +394,8 @@
void SetGestationTime(int in_time) { gestation_time = in_time; }
void SetTimeUsed(int in_time) { time_used = in_time; }
void SetTrialTimeUsed(int in_time) { trial_time_used = in_time; }
+ void SetGeneration(int in_generation) { generation = in_generation; }
+ void SetPermanentGermlinePropensity(double _in) { permanent_germline_propensity = _in; }
void SetFault(const cString& in_fault) { fault_desc = in_fault; }
void SetNeutralMetric(double _in){ neutral_metric = _in; }
void SetLifeFitness(double _in){ life_fitness = _in; }
@@ -438,6 +442,7 @@
void IncErrors() { assert(initialized == true); cur_num_errors++; }
void IncDonates() { assert(initialized == true); cur_num_donates++; }
void IncSenseCount(const int i) { assert(initialized == true); cur_sense_count[i]++; }
+
bool& IsInjected() { assert(initialized == true); return is_injected; }
bool& IsModifier() { assert(initialized == true); return is_modifier; }
bool& IsModified() { assert(initialized == true); return is_modified; }
Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cPopulation.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -398,7 +398,8 @@
ActivateOrganism(ctx, child_array[i], GetCell(target_cells[i]));
//@JEB - we may want to pass along some state information from parent to child
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_KEEP_STATE_EPIGENETIC) {
+ if ( (m_world->GetConfig().EPIGENETIC_METHOD.Get() == EPIGENETIC_METHOD_OFFSPRING)
+ || (m_world->GetConfig().EPIGENETIC_METHOD.Get() == EPIGENETIC_METHOD_BOTH) ) {
child_array[i]->GetHardware().InheritState(parent_organism.GetHardware());
}
@@ -521,6 +522,7 @@
// Keep track of statistics for organism counts...
num_organisms++;
+
if (deme_array.GetSize() > 0) {
deme_array[target_cell.GetDemeID()].IncOrgCount();
}
@@ -687,6 +689,7 @@
// Update count statistics...
num_organisms--;
+
if (deme_array.GetSize() > 0) {
deme_array[in_cell.GetDemeID()].DecOrgCount();
}
@@ -1328,6 +1331,7 @@
}
// Reset both demes, in case they have any cleanup work to do.
+ // Must reset target first for stats to be correctly updated!
if(m_world->GetConfig().ENERGY_ENABLED.Get()) {
// Transfer energy from source to target if we're using the energy model.
target_deme.DivideReset(source_deme, target_deme_resource_reset, offspring_deme_energy);
@@ -1438,9 +1442,12 @@
assert(xfer.size()>0);
// Clear the demes.
+ source_deme.UpdateStats();
source_deme.KillAll();
+
+ target_deme.UpdateStats();
target_deme.KillAll();
-
+
// And now populate the source and target.
int j=0;
for(std::vector<std::pair<cGenome,int> >::iterator i=xfer.begin(); i!=xfer.end(); ++i, ++j) {
@@ -1458,9 +1465,23 @@
// Updated seed deme method that maintains genotype inheritance.
tArray<cOrganism*> founders; // List of organisms we're going to transfer.
+
+ /*
+ // Debug Code
+ cGenotype * original_source_founder_genotype = NULL;
+ if (1) {
+ tArray<int>& source_founders = source_deme.GetFounderGenotypeIDs();
+ if (source_founders.GetSize() > 0) {
+ original_source_founder_genotype = m_world->GetClassificationManager().FindGenotype(source_founders[0]);
+ cout << "Source:" << endl << original_source_founder_genotype->GetGenome().AsString() << endl;
+ }
+ tArray<int>& target_founders = target_deme.GetFounderGenotypeIDs();
+ if (target_founders.GetSize() > 0) {
+ cGenotype * target_founder_genotype = m_world->GetClassificationManager().FindGenotype(target_founders[0]);
+ cout << "Target:" << endl << target_founder_genotype->GetGenome().AsString() << endl;
+ }
+ }
- /*
- // Debug
tArray<int>& source_founders = source_deme.GetFounders();
cerr << "Original source genotype ids:" << endl;
for(int i=0; i<source_founders.GetSize(); i++) {
@@ -1474,6 +1495,22 @@
cerr << target_founders[i] << " ";
}
cerr << endl;
+
+ // Debug Code
+ //// Count the number of orgs in each deme.
+ int count = 0;
+ for(int i=0; i<target_deme.GetSize(); ++i) {
+ int cell_id = target_deme.GetCellID(i);
+ if(cell_array[cell_id].IsOccupied()) count++;
+ }
+ cout << "Initial orgs in target deme: " << count << endl;
+
+ count = 0;
+ for(int i=0; i<source_deme.GetSize(); ++i) {
+ int cell_id = source_deme.GetCellID(i);
+ if(cell_array[cell_id].IsOccupied()) count++;
+ }
+ cout << "Initial orgs in source deme: " << count << endl;
*/
switch(m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get()) {
@@ -1496,16 +1533,132 @@
}
break;
}
+ case 2:
+ case 3:
+ { // Selection based on germline propensities.
+ // 2: sum the germline propensities of all organisms
+ // and pick TWO based on each organism getting a
+ // weighted probability of being germline
+ // 3: treat germline propensities as zero or nonzero for picking
+
+ if (source_deme.GetOrgCount() < 2) {
+ m_world->GetDriver().RaiseFatalException(1, "Germline DEMES_ORGANISM_SELECTION method didn't find at least two organisms in deme.");
+ }
+
+ if (m_world->GetConfig().DEMES_DIVIDE_METHOD.Get() != 0) {
+ m_world->GetDriver().RaiseFatalException(1, "Germline DEMES_ORGANISM_SELECTION methods 2 and 3 can only be used with DEMES_DIVIDE_METHOD 0.");
+ }
+
+ tArray<cOrganism*> prospective_founders;
+
+ cDoubleSum gp_sum;
+ double min = -1;
+ for (int i=0; i < source_deme.GetSize(); i++) {
+ if ( GetCell(source_deme.GetCellID(i)).IsOccupied() ) {
+ double gp = GetCell(source_deme.GetCellID(i)).GetOrganism()->GetPhenotype().GetPermanentGermlinePropensity();
+ if (gp > 0.0) {
+ gp_sum.Add( gp );
+ prospective_founders.Push( GetCell(source_deme.GetCellID(i)).GetOrganism() );
+ }
+ //cout << gp << " ";
+ if ( (min == -1) || (gp < min) ) min = gp;
+ }
+ }
+
+ //cout << "Germline Propensity Sum: " << gp_sum.Sum() << endl;
+ //cout << "Num prospective founders: " << prospective_founders.GetSize() << endl;
+
+ if (prospective_founders.GetSize() < 2) {
+ // there were not enough orgs with nonzero germlines
+ // pick additional orgs at random without replacement
+
+ founders = prospective_founders;
+
+ while(founders.GetSize() < 2) {
+ int cellid = source_deme.GetCellID(random.GetUInt(source_deme.GetSize()));
+ if( cell_array[cellid].IsOccupied() ) {
+ cOrganism * org = cell_array[cellid].GetOrganism();
+ bool found = false;
+ for(int i=0; i< founders.GetSize(); i++) {
+ if (founders[i] == org) found = true;
+ }
+ if (!found) founders.Push(cell_array[cellid].GetOrganism());
+ }
+ }
+ } else {
+
+ // pick two orgs based on germline propensities from prospective founders
+
+ while(founders.GetSize() < 2) {
+
+ double choice = (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 2)
+ ? random.GetDouble( gp_sum.Sum() ) : random.GetDouble( gp_sum.Count() );
+
+
+ //cout << "Count: " << gp_sum.Count() << endl;
+
+ // find the next organism to choose
+ cOrganism * org = NULL;
+ int on = 0;
+ while( (choice > 0) && (on < prospective_founders.GetSize()) ) {
+ org = prospective_founders[on];
+
+ // did we already have this org?
+ bool found = false;
+ for(int i=0; i< founders.GetSize(); i++) {
+ if (founders[i] == org) found = true;
+ }
+
+ // if it wasn't already chosen, then we count down...
+ if (!found) {
+ choice -= (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 2)
+ ? org->GetPhenotype().GetPermanentGermlinePropensity()
+ : (org->GetPhenotype().GetPermanentGermlinePropensity() > 0);
+ }
+ on++;
+ }
+
+ gp_sum.Subtract(org->GetPhenotype().GetPermanentGermlinePropensity());
+ assert(org);
+ founders.Push(org);
+ }
+ }
+ /*
+ // Debug Code
+ cout << endl;
+ cout << "sum " << gp_sum.Sum() << endl;
+ cout << "min " << min << endl;
+ cout << "choice " << choice << endl;
+ */
+
+ //cout << "Chose germline propensity " << chosen_org->GetPhenotype().GetLastGermlinePropensity() << endl;
+ break;
+ }
default: {
cout << "Undefined value (" << m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get()
<< ") for DEMES_ORGANISM_SELECTION." << endl;
exit(1);
}
}
-
+
+ // deconstruct founders into two lists...
+ tArray<cOrganism*> source_founders = founders; // List of organisms we're going to transfer.
+ tArray<cOrganism*> target_founders = founders; // List of organisms we're going to transfer.
+
+ if ( (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 2)
+ || (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 3) )
+ {
+ source_founders.ResizeClear(0);
+ target_founders.ResizeClear(0);
+
+ source_founders.Push(founders[0]);
+ target_founders.Push(founders[1]);
+ }
+
// We'd better have at *least* one genome.
- assert(founders.GetSize()>0);
-
+ assert(source_founders.GetSize()>0);
+ assert(target_founders.GetSize()>0);
+
// We clear the deme, but trick cPopulation::KillOrganism
// to NOT delete the organisms, by pretending
// the orgs are running. This way we can still create
@@ -1513,6 +1666,7 @@
// We also need to defer adjusting the genotype
// or it will be prematurely deleted before we are done!
+ // cDoubleSum gen;
tArray<cOrganism*> old_source_organisms;
for(int i=0; i<source_deme.GetSize(); ++i) {
int cell_id = source_deme.GetCellID(i);
@@ -1522,8 +1676,14 @@
old_source_organisms.Push(org);
org->SetRunning(true);
org->GetGenotype()->IncDeferAdjust();
+
+ // cout << org->GetPhenotype().GetGeneration()-source_deme.GetAvgFounderGeneration() << " ";
+ // gen.Add(org->GetPhenotype().GetGeneration()-source_deme.GetAvgFounderGeneration());
}
}
+ //cout << endl;
+ //cout << "Average: " << gen.Average() << endl;
+
tArray<cOrganism*> old_target_organisms;
for(int i=0; i<target_deme.GetSize(); ++i) {
@@ -1539,17 +1699,20 @@
// Clear the demes.
target_deme.ClearFounders();
+ target_deme.UpdateStats();
target_deme.KillAll();
-
+
+ //cout << founders.GetSize() << " founders." << endl;
+
// Now populate the target (and optionally the source) using InjectGenotype.
// In the future InjectClone could be used, but this would require the
// deme keeping complete copies of the founder organisms when
// we wanted to re-seed from the original founders.
- for(int i=0; i<founders.GetSize(); i++) {
+ for(int i=0; i<target_founders.GetSize(); i++) {
int cellid = DemeSelectInjectionCell(target_deme, i);
- InjectGenotype(cellid, founders[i]->GetGenotype());
- DemePostInjection(target_deme, cell_array[cellid]);
- target_deme.AddFounder(*founders[i]->GetGenotype());
+ InjectDemeFounder(cellid, *target_founders[i]->GetGenotype(), &target_founders[i]->GetPhenotype());
+ target_deme.AddFounder(*target_founders[i]->GetGenotype(), &target_founders[i]->GetPhenotype());
+ DemePostInjection(target_deme, cell_array[cellid]);
}
// We either repeat this procedure in the source deme,
@@ -1557,32 +1720,41 @@
// or do nothing to the source deme...
// source deme is replaced in the same way as the target
- if (m_world->GetConfig().DEMES_DIVIDE_METHOD.Get() == 0) {
+ if (m_world->GetConfig().DEMES_DIVIDE_METHOD.Get() == 0) {
+
source_deme.ClearFounders();
+ source_deme.UpdateStats();
source_deme.KillAll();
- for(int i=0; i<founders.GetSize(); i++) {
- int cellid = DemeSelectInjectionCell(source_deme, i);
- InjectGenotype(cellid, founders[i]->GetGenotype());
+ for(int i=0; i<source_founders.GetSize(); i++) {
+ int cellid = DemeSelectInjectionCell(source_deme, i);
+ InjectDemeFounder(cellid, *source_founders[i]->GetGenotype(), &source_founders[i]->GetPhenotype());
+ source_deme.AddFounder(*source_founders[i]->GetGenotype(), &source_founders[i]->GetPhenotype());
DemePostInjection(source_deme, cell_array[cellid]);
- source_deme.AddFounder(*founders[i]->GetGenotype());
}
}
// source deme is "reset" by re-injecting founder genotypes
else if (m_world->GetConfig().DEMES_DIVIDE_METHOD.Get() == 1) {
-
+ // Do not update the last founder generation, since the founders have not changed.
+
+ source_deme.UpdateStats();
source_deme.KillAll();
// do not clear or change founder list
// use it to recreate ancestral state of genotypes
- tArray<int>& source_founders = source_deme.GetFounders();
+ tArray<int>& source_founders = source_deme.GetFounderGenotypeIDs();
+ tArray<cPhenotype>& source_founder_phenotypes = source_deme.GetFounderPhenotypes();
for(int i=0; i<source_founders.GetSize(); i++) {
+
int cellid = DemeSelectInjectionCell(source_deme, i);
+ //cout << "founder: " << source_founders[i] << endl;
cGenotype * genotype = m_world->GetClassificationManager().FindGenotype(source_founders[i]);
- assert(genotype);
- InjectGenotype(cellid, genotype);
- DemePostInjection(source_deme, cell_array[cellid]);
+ InjectDemeFounder(cellid, *genotype, &source_founder_phenotypes[i]);
+ DemePostInjection(source_deme, cell_array[cellid]);
}
+
+ //cout << target_deme.GetOrgCount() << " target orgs." << endl;
+ //cout << source_deme.GetOrgCount() << " source orgs." << endl;
}
// source deme is left untouched
else if (m_world->GetConfig().DEMES_DIVIDE_METHOD.Get() == 2) {
@@ -1591,7 +1763,45 @@
m_world->GetDriver().RaiseFatalException(1, "Unknown DEMES_DIVIDE_METHOD");
}
+ // Update *source* generations per lifetime by the founders we used to seed the *target*.
+ // and *source*, so that we average over them.
+ tArray<cPhenotype> new_phenotypes;
+ new_phenotypes = new_phenotypes + target_deme.GetFounderPhenotypes();
+ new_phenotypes = new_phenotypes + source_deme.GetFounderPhenotypes();
+ source_deme.UpdateGenerationsPerLifetime(new_phenotypes);
+
+
/*
+ // Debug Code
+ //// Count the number of orgs in each deme.
+ count = 0;
+ for(int i=0; i<target_deme.GetSize(); ++i) {
+ int cell_id = target_deme.GetCellID(i);
+ if(cell_array[cell_id].IsOccupied()) count++;
+ }
+ cout << "Final orgs in target deme: " << count << endl;
+
+ count = 0;
+ for(int i=0; i<source_deme.GetSize(); ++i) {
+ int cell_id = source_deme.GetCellID(i);
+ if(cell_array[cell_id].IsOccupied()) count++;
+ }
+ cout << "Final orgs in source deme: " << count << endl;
+
+ if (1) {
+ tArray<int>& source_founders = source_deme.GetFounderGenotypeIDs();
+ cGenotype * source_founder_genotype = m_world->GetClassificationManager().FindGenotype(source_founders[0]);
+ tArray<int>& target_founders = target_deme.GetFounderGenotypeIDs();
+ cGenotype * target_founder_genotype = m_world->GetClassificationManager().FindGenotype(target_founders[0]);
+ if (original_source_founder_genotype->GetGenome().AsString() != source_founder_genotype->GetGenome().AsString())
+ {
+ cout << "Original source founder does not equal final source founder!!!!" << endl;
+ }
+
+ cout << "Source:" << endl << source_founder_genotype->GetGenome().AsString() << endl;
+ cout << "Target:" << endl << target_founder_genotype->GetGenome().AsString() << endl;
+ }
+
// Debug
tArray<int>& new_source_founders = source_deme.GetFounders();
cerr << "New source genotype ids:" << endl;
@@ -1670,7 +1880,47 @@
}
}
+void cPopulation::InjectDemeFounder(int _cell_id, cGenotype& _genotype, cPhenotype* _phenotype)
+{
+ // phenotype can be NULL
+
+ InjectGenotype(_cell_id, &_genotype);
+
+ // At this point, the cell had better be occupied...
+ assert(GetCell(_cell_id).IsOccupied());
+ cOrganism * organism = GetCell(_cell_id).GetOrganism();
+
+ //Now we need to set up the phenotype of this organism...
+ if (_phenotype) {
+ //If we want founders to have their proper phenotypes
+ // then we might do something like this... (untested)
+ //organism->SetPhenotype(*_phenotype);
+ // Re-initialize the time-slice for this new organism.
+ //AdjustSchedule(_cell_id, organism->GetPhenotype().GetMerit());
+
+ // For now, just copy the generation...
+ organism->GetPhenotype().SetGeneration( _phenotype->GetGeneration() );
+
+ // and germline propensity.
+ organism->GetPhenotype().SetPermanentGermlinePropensity( _phenotype->GetPermanentGermlinePropensity() );
+
+ if (m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() > 0.0) {
+ organism->GetPhenotype().SetPermanentGermlinePropensity( m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() );
+ }
+ }
+
+ /* It requires mcuh more than this to correctly implement, do later if needed @JEB
+ //Optionally, set the first organism's merit to a constant value
+ //actually, we need to add so the first organism is seeded this way too...
+ if (m_world->GetConfig().DEMES_DEFAULT_MERIT.Get()) {
+ organism->GetPhenotype().SetMerit( cMerit(m_world->GetConfig().DEMES_DEFAULT_MERIT.Get()) );
+ AdjustSchedule(GetCell(_cell_id), organism->GetPhenotype().GetMerit());
+ }
+ */
+}
+
+
/*! Helper method that determines the cell into which an organism will be placed.
Respects all of the different placement options that are relevant for deme replication.
@@ -2387,11 +2637,7 @@
if(deme_array[i].IsEmpty()) continue;
- tArray<int>& deme_founders = deme_array[i].GetFounders();
-
- // this case really shouldn't happen, but starting
- // orgs don't count as founders currently...
- if (deme_founders.GetSize() == 0) continue;
+ tArray<int>& deme_founders = deme_array[i].GetFounderGenotypeIDs();
fp << i << " " << deme_founders.GetSize();
for(int j=0; j<deme_founders.GetSize(); j++) {
@@ -2971,10 +3217,12 @@
stats.SumDemeGestationTime().Clear();
stats.SumDemeNormalizedTimeUsed().Clear();
stats.SumDemeMerit().Clear();
-
+
+ stats.SumDemeGenerationsPerLifetime().Clear();
+
for(int i = 0; i < GetNumDemes(); i++) {
cDeme& deme = GetDeme(i);
- if(!deme.IsEmpty()) // ignore empty demes
+ if(deme.IsEmpty()) // ignore empty demes
{
continue;
}
@@ -2986,6 +3234,8 @@
stats.SumDemeGestationTime().Add(deme.GetGestationTime());
stats.SumDemeNormalizedTimeUsed().Add(deme.GetLastNormalizedTimeUsed());
stats.SumDemeMerit().Add(deme.GetDemeMerit().GetDouble());
+
+ stats.SumDemeGenerationsPerLifetime().Add(deme.GetGenerationsPerLifetime());
}
}
@@ -3622,20 +3872,43 @@
LineageSetupOrganism(GetCell(cell_id).GetOrganism(), 0, lineage_label);
- // If we're using germlines, then we have to be a little careful here.
- // This should probably not be within Inject() since we mainly want it to
- // apply to the START_CREATURE? -- @JEB
- if(m_world->GetConfig().DEMES_USE_GERMLINE.Get() == 1) {
- cDeme& deme = deme_array[GetCell(cell_id).GetDemeID()];
- if(deme.GetGermline().Size()==0) {
- deme.GetGermline().Add(GetCell(cell_id).GetOrganism()->GetGenome());
- }
- }
- else if(m_world->GetConfig().DEMES_USE_GERMLINE.Get() == 2) {
- //find the genotype we just created from the genome, and save it
- cDeme& deme = deme_array[GetCell(cell_id).GetDemeID()];
- cGenotype * genotype = m_world->GetClassificationManager().FindGenotype(genome, lineage_label);
- deme.ReplaceGermline(*genotype);
+ if (GetNumDemes() > 1) {
+ cDeme& deme = deme_array[GetCell(cell_id).GetDemeID()];
+
+ // If we're using germlines, then we have to be a little careful here.
+ // This should probably not be within Inject() since we mainly want it to
+ // apply to the START_CREATURE? -- @JEB
+
+ //@JEB This section is very messy to maintain consistency with other deme ways.
+
+ if(m_world->GetConfig().DEMES_SEED_METHOD.Get() == 0) {
+ if(m_world->GetConfig().DEMES_USE_GERMLINE.Get() == 1) {
+ if(deme.GetGermline().Size()==0) {
+ deme.GetGermline().Add(GetCell(cell_id).GetOrganism()->GetGenome());
+ }
+ }
+ }
+ else if(m_world->GetConfig().DEMES_SEED_METHOD.Get() == 1) {
+ if(m_world->GetConfig().DEMES_USE_GERMLINE.Get() == 2) {
+ //find the genotype we just created from the genome, and save it
+ cGenotype * genotype = GetCell(cell_id).GetOrganism()->GetGenotype();
+ deme.ReplaceGermline(*genotype);
+ }
+ else { // not germlines, save org as founder
+ cGenotype * genotype = GetCell(cell_id).GetOrganism()->GetGenotype();
+ deme.AddFounder(*genotype, &phenotype);
+ }
+
+ GetCell(cell_id).GetOrganism()->GetPhenotype().SetPermanentGermlinePropensity
+ (m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get());
+
+
+ if (m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() > 0.0) {
+ GetCell(cell_id).GetOrganism()->GetPhenotype().SetPermanentGermlinePropensity
+ ( m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() );
+ }
+
+ }
}
}
@@ -3929,6 +4202,7 @@
void cPopulation::PrintPhenotypeData(const cString& filename)
{
set<int> ids;
+ set<cString> complete;
for (int i = 0; i < cell_array.GetSize(); i++) {
// Only look at cells with organisms in them.
@@ -3937,16 +4211,20 @@
const cPhenotype& phenotype = cell_array[i].GetOrganism()->GetPhenotype();
int id = 0;
+ cString key;
for (int j = 0; j < phenotype.GetLastTaskCount().GetSize(); j++) {
if (phenotype.GetLastTaskCount()[j] > 0) id += (1 << j);
+ key += cStringUtil::Stringf("%i-", phenotype.GetLastTaskCount()[j]);
}
ids.insert(id);
+ complete.insert(key);
}
cDataFile& df = m_world->GetDataFile(filename);
df.WriteTimeStamp();
df.Write(m_world->GetStats().GetUpdate(), "Update");
- df.Write(static_cast<int>(ids.size()), "Unique Phenotypes");
+ df.Write(static_cast<int>(ids.size()), "Unique Phenotypes (by task done)");
+ df.Write(static_cast<int>(complete.size()), "Unique Phenotypes (by task count)");
df.Endl();
}
Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cPopulation.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -204,6 +204,9 @@
//! Helper method that seeds a target deme from the organisms in the source deme.
void SeedDeme(cDeme& source_deme, cDeme& target_deme);
+
+ //! Helper method that adds a founder organism to a deme, and sets up its phenotype
+ void InjectDemeFounder(int _cell_id, cGenotype& _genotype, cPhenotype* _phenotype = NULL);
//! Helper method that determines the cell into which an organism will be placed during deme replication.
int DemeSelectInjectionCell(cDeme& deme, int sequence=0);
Modified: development/source/main/cReactionProcess.h
===================================================================
--- development/source/main/cReactionProcess.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cReactionProcess.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -55,6 +55,7 @@
bool lethal; // Lethality of reaction
bool sterilize; //!< Whether performance of this reaction sterilizes the organism.
double deme_fraction; //!< Fraction of process reward that is applied to the organism's deme.
+ bool is_germline; // Apply reward to germline propensity instead of bonus?
cString match_string; // Bit string to match if this is a match string reaction
int inst_id; // Instruction to be triggered if reaction successful.
bool depletable; // Does completing consume resource?
@@ -83,6 +84,7 @@
, lethal(0)
, sterilize(false)
, deme_fraction(0.0)
+ , is_germline(false)
, inst_id(-1)
, depletable(true)
, detect(NULL)
@@ -105,6 +107,7 @@
bool GetLethal() const { return lethal; }
bool GetSterilize() const { return sterilize; }
double GetDemeFraction() const { return deme_fraction; }
+ bool GetIsGermline() const { return is_germline; }
cResource* GetDetect() const { return detect; }
double GetDetectionThreshold() const { return detection_threshold; }
double GetDetectionError() const { return detection_error; }
@@ -123,6 +126,7 @@
void SetLethal(int _in) { lethal = _in; }
void SetSterile(int _in) { sterilize = _in; }
void SetDemeFraction(double _in) { assert(_in>=0.0); assert(_in<=1.0); deme_fraction = _in; }
+ void SetIsGermline(bool _in) { is_germline = _in; }
void SetDetect(cResource* _in) { detect = _in; }
void SetDetectionThreshold(double _in) { detection_threshold = _in; }
void SetDetectionError(double _in) { detection_error = _in; }
Modified: development/source/main/cReactionResult.cc
===================================================================
--- development/source/main/cReactionResult.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cReactionResult.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -40,6 +40,8 @@
, energy_add(0.0)
, bonus_add(0.0)
, bonus_mult(1.0)
+ , germline_add(0.0)
+ , germline_mult(1.0)
, insts_triggered(0)
, lethal(false)
, sterilize(false)
@@ -152,6 +154,19 @@
deme_mult_bonus *= value;
}
+void cReactionResult::AddGermline(double value)
+{
+ ActivateReaction();
+ germline_add += value;
+}
+
+void cReactionResult::MultGermline(double value)
+{
+ ActivateReaction();
+ germline_mult *= value;
+}
+
+
void cReactionResult::AddInst(int id)
{
insts_triggered.Push(id);
Modified: development/source/main/cReactionResult.h
===================================================================
--- development/source/main/cReactionResult.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cReactionResult.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -43,6 +43,8 @@
double energy_add;
double bonus_add;
double bonus_mult;
+ double germline_add;
+ double germline_mult;
tArray<int> insts_triggered;
bool lethal;
bool sterilize;
@@ -78,7 +80,9 @@
void MultBonus(double value);
void AddDemeBonus(double value);
void MultDemeBonus(double value);
-
+ void AddGermline(double value);
+ void MultGermline(double value);
+
void AddInst(int id);
double GetConsumed(int id);
@@ -97,6 +101,9 @@
tArray<int>& GetInstArray() { return insts_triggered; }
double GetAddDemeBonus() { return deme_add_bonus; }
double GetMultDemeBonus() { return deme_mult_bonus; }
+ double GetAddGermline() { return germline_add; }
+ double GetMultGermline() { return germline_mult; }
+
};
Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cStats.cc 2008-04-07 01:49:58 UTC (rev 2520)
@@ -584,6 +584,7 @@
df.Write(sum_deme_merit.Average(), "Merit");
df.Write(sum_deme_gestation_time.Average(), "Gestation Time");
df.Write(sum_deme_normalized_time_used.Average(), "Time Used (normalized by org fitness)");
+ df.Write(sum_deme_generations_per_lifetime.Average(), "Generations between current and last founders");
df.Endl();
}
@@ -1342,7 +1343,7 @@
for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
cDeme& deme = m_world->GetPopulation().GetDeme(i);
for(int j = 0; j < num_tasks; j++) {
- df.Write( (deme.GetLastTaskCount()[j] > 0), cStringUtil::Stringf("%i.", i) + task_names[j] );
+ df.Write( (deme.GetLastTaskExeCount()[j] > 0), cStringUtil::Stringf("%i.", i) + task_names[j] );
}
}
df.Endl();
@@ -1362,7 +1363,7 @@
for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
cDeme& deme = m_world->GetPopulation().GetDeme(i);
for(int j = 0; j < num_tasks; j++) {
- df.Write( deme.GetLastTaskCount()[j], cStringUtil::Stringf("%i.", i) + task_names[j] );
+ df.Write( deme.GetLastTaskExeCount()[j], cStringUtil::Stringf("%i.", i) + task_names[j] );
}
}
df.Endl();
@@ -1387,3 +1388,64 @@
df.Endl();
}
+void cStats::PrintDemeOrgTasks(const cString& filename){
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteComment("Avida deme org tasks data");
+ df.WriteTimeStamp();
+ df.WriteComment("First column gives the current update, next columns give the number");
+ df.WriteComment("of organisms that have the particular task as a component of their merit");
+ df.WriteComment("in a particular deme when the deme last divided.");
+
+ const int num_tasks = m_world->GetEnvironment().GetNumTasks();
+
+ df.Write(m_update, "Update");
+ for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+ cDeme& deme = m_world->GetPopulation().GetDeme(i);
+ for(int j = 0; j < num_tasks; j++) {
+ df.Write( deme.GetLastOrgTaskCount()[j], cStringUtil::Stringf("%i.", i) + task_names[j] );
+ }
+ }
+ df.Endl();
+}
+
+void cStats::PrintDemeOrgTasksExe(const cString& filename){
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteComment("Avida deme org tasks exe data");
+ df.WriteTimeStamp();
+ df.WriteComment("First column gives the current update, next columns give the number");
+ df.WriteComment("of times a task has contributed to the merit of all organisms");
+ df.WriteComment("in a particular deme when the deme last divided.");
+
+ const int num_tasks = m_world->GetEnvironment().GetNumTasks();
+
+ df.Write(m_update, "Update");
+ for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+ cDeme& deme = m_world->GetPopulation().GetDeme(i);
+ for(int j = 0; j < num_tasks; j++) {
+ df.Write( deme.GetLastOrgTaskExeCount()[j], cStringUtil::Stringf("%i.", i) + task_names[j] );
+ }
+ }
+
+ df.Endl();
+}
+
+void cStats::PrintDemeOrgReactions(const cString& filename){
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteComment("Avida deme org reactions data");
+ df.WriteTimeStamp();
+ df.WriteComment("First column gives the current update, all further columns give the number");
+ df.WriteComment("of currently living organisms each reaction has affected");
+ df.WriteComment("in a particular deme when the deme last divided.");
+
+ const int num_reactions = m_world->GetEnvironment().GetReactionLib().GetSize();
+
+ df.Write(m_update, "Update");
+ for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+ cDeme& deme = m_world->GetPopulation().GetDeme(i);
+ for(int j = 0; j < num_reactions; j++) {
+ df.Write( deme.GetLastOrgReactionCount()[j], cStringUtil::Stringf("%i.", i) + m_world->GetEnvironment().GetReactionLib().GetReaction(j)->GetName() );
+ }
+ }
+ df.Endl();
+}
+
Modified: development/source/main/cStats.h
===================================================================
--- development/source/main/cStats.h 2008-04-04 19:18:26 UTC (rev 2519)
+++ development/source/main/cStats.h 2008-04-07 01:49:58 UTC (rev 2520)
@@ -274,6 +274,7 @@
cIntSum sum_deme_gestation_time;
cDoubleSum sum_deme_normalized_time_used;
cDoubleSum sum_deme_merit;
+ cDoubleSum sum_deme_generations_per_lifetime;
// Speculative Execution Stats
int m_spec_total;
@@ -418,7 +419,8 @@
cIntSum& SumDemeGestationTime() { return sum_deme_gestation_time; }
cDoubleSum& SumDemeNormalizedTimeUsed() { return sum_deme_normalized_time_used; }
cDoubleSum& SumDemeMerit() { return sum_deme_merit; }
-
+ cDoubleSum& SumDemeGenerationsPerLifetime() { return sum_deme_generations_per_lifetime; }
+
#if INSTRUCTION_COUNT
void ZeroInst();
#endif
@@ -458,8 +460,8 @@
const cIntSum& SumDemeGestationTime() const { return sum_deme_generation; }
const cDoubleSum& SumDemeNormalizedTimeUsed() const { return sum_deme_normalized_time_used; }
const cDoubleSum& SumDemeMerit() const { return sum_deme_merit; }
+ const cDoubleSum& SumDemeGenerationsPerLifetime() const { return sum_deme_generations_per_lifetime; }
-
void IncResamplings() { ++num_resamplings; } // @AWC 06/29/06
void IncFailedResamplings() { ++num_failedResamplings; } // @AWC 06/29/06
@@ -722,8 +724,10 @@
void PrintDemeTasks(const cString& filename);
void PrintDemeTasksExe(const cString& filename);
void PrintDemeReactions(const cString& filename);
-
-
+ void PrintDemeOrgTasks(const cString& filename);
+ void PrintDemeOrgTasksExe(const cString& filename);
+ void PrintDemeOrgReactions(const cString& filename);
+
protected:
int m_deme_num_repls; //!< Number of deme replications since last PrintDemeReplicationData.
cDoubleSum m_deme_gestation_time; //!< Gestation time for demes - mean age at deme replication.
More information about the Avida-cvs
mailing list