[Avida-SVN] r1777 - in development: source/cpu source/main tests/_testrunner

welsberr at myxo.css.msu.edu welsberr at myxo.css.msu.edu
Tue Jul 10 10:55:04 PDT 2007


Author: welsberr
Date: 2007-07-10 13:55:03 -0400 (Tue, 10 Jul 2007)
New Revision: 1777

Modified:
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/main/cAvidaConfig.h
   development/source/main/cBirthChamber.cc
   development/source/main/cEnvironment.cc
   development/source/main/cEnvironment.h
   development/source/main/cPhenotype.cc
   development/source/main/cPhenotype.h
   development/source/main/cPopulation.cc
   development/source/main/cPopulation.h
   development/tests/_testrunner/testrunner.cfg
Log:
Changes to implement "tumble" and "move" instructions for Avidians, and add a 
refractory period on completion of tasks that reduces the merit acquired on
completion of a task if it was already done recently.


Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/cpu/cHardwareCPU.cc	2007-07-10 17:55:03 UTC (rev 1777)
@@ -221,6 +221,9 @@
     
     tInstLibEntry<tMethod>("set-cmut", &cHardwareCPU::Inst_SetCopyMut),
     tInstLibEntry<tMethod>("mod-cmut", &cHardwareCPU::Inst_ModCopyMut),
+    // @WRE additions for movement
+    tInstLibEntry<tMethod>("tumble", &cHardwareCPU::Inst_Tumble),
+    tInstLibEntry<tMethod>("move", &cHardwareCPU::Inst_Move),
 
     // Energy instruction
     tInstLibEntry<tMethod>("recover", &cHardwareCPU::Inst_ZeroEnergyUsed),
@@ -3699,6 +3702,55 @@
   return true;
 }
 
+// @WRE addition for movement
+// Tumble sets the organism and cell to a new random facing
+// 
+bool cHardwareCPU::Inst_Tumble(cAvidaContext& ctx)
+{
+  // Code taken from Inst_Inject
+  //cout << "Tumble: start" << endl;
+  const int num_neighbors = organism->GetNeighborhoodSize();
+  //cout << "Tumble: size = " << num_neighbors << endl;
+  organism->Rotate(ctx.GetRandom().GetUInt(num_neighbors));
+  return true;
+}
+
+// @WRE addition for movement
+// Move uses the cPopulation::SwapCells method to move an organism to a different cell
+// and the cPopulation::MoveOrganisms helper function to clean up after a move
+// The cell selected as a destination is the one faced
+bool cHardwareCPU::Inst_Move(cAvidaContext& ctx)
+{
+  // Declarations
+  int fromcellID, destcellID; //, actualNeighborhoodSize, fromFacing, destFacing, currentFacing;
+
+  // Get population
+  cPopulation& pop = m_world->GetPopulation();
+
+  // Get stepsize. Currently, all moves are one cell regardless of stepsize.
+  // This could be changed in the future.
+  const int stepsize = m_world->GetConfig().BIOMIMETIC_MOVEMENT_STEP.Get();
+  
+  // Code
+  if (0 < stepsize) {
+    // Current cell
+    fromcellID = organism->GetCellID();
+    // With sanity check
+    if (-1  == fromcellID) return false;
+    // Destination cell
+    destcellID = pop.GetCell(fromcellID).GetCellFaced().GetID();
+    // Actually perform the move using SwapCells
+    //cout << "SwapCells: " << fromcellID << " to " << destcellID << endl;
+    pop.SwapCells(pop.GetCell(fromcellID),pop.GetCell(destcellID));
+    // Swap inputs and facings between cells using helper function
+    pop.MoveOrganisms(ctx, pop.GetCell(fromcellID), pop.GetCell(destcellID));
+
+    return true;
+  } else {
+    return false;
+  }
+}
+
 // Energy use
 
 bool cHardwareCPU::Inst_ZeroEnergyUsed(cAvidaContext& ctx)

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/cpu/cHardwareCPU.h	2007-07-10 17:55:03 UTC (rev 1777)
@@ -453,6 +453,9 @@
   bool Inst_RotateLabel(cAvidaContext& ctx);
   bool Inst_SetCopyMut(cAvidaContext& ctx);
   bool Inst_ModCopyMut(cAvidaContext& ctx);
+  // @WRE additions for movement
+  bool Inst_Tumble(cAvidaContext& ctx);
+  bool Inst_Move(cAvidaContext& ctx);
 
   // Energy use
   

Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cAvidaConfig.h	2007-07-10 17:55:03 UTC (rev 1777)
@@ -352,12 +352,12 @@
   CONFIG_ADD_VAR(APPLY_ENERGY_METHOD, int, 0, "When should rewarded energy be applied to current energy?\n0 = on divide\n1 = on completion of task\n2 = on sleep");  
   CONFIG_ADD_VAR(ENERGY_VERBOSE, bool, 0, "Print energy and merit values. 0/1 (off/on)");
   CONFIG_ADD_VAR(LOG_SLEEP_TIMES, bool, 0, "Log sleep start and end times. 0/1 (off/on)\nWARNING: may use lots of memory.");
-//  CONFIG_ADD_VAR(FIX_METABOLIC_RATE, bool, 0, "When activated the metabolic rate of all orgiansims are equal. 0/1 (off/on)"); // TODO - check for correctness
+  //  CONFIG_ADD_VAR(FIX_METABOLIC_RATE, bool, 0, "When activated the metabolic rate of all orgiansims are equal. 0/1 (off/on)"); // TODO - check for correctness
 
   CONFIG_ADD_GROUP(SECOND_PASS_GROUP, "Tracking metrics known after the running experiment previously");
   CONFIG_ADD_VAR(TRACK_CCLADES, int, 0, "Enable tracking of coalescence clades");
   CONFIG_ADD_VAR(TRACK_CCLADES_IDS, cString, "coalescence.ids", "File storing coalescence IDs");
-  
+
   CONFIG_ADD_GROUP(GX_GROUP, "Gene Expression CPU Settings");
   CONFIG_ADD_VAR(MAX_PROGRAMIDS, int, 16, "Maximum number of programids an organism can create.");
   CONFIG_ADD_VAR(MAX_PROGRAMID_AGE, int, 2000, "Max number of CPU cycles a programid executes before it is removed.");
@@ -365,7 +365,7 @@
   CONFIG_ADD_VAR(IMPLICIT_BG_PROMOTER_RATE, double, 0.0, "Relative rate of non-promoter sites creating programids.");
   CONFIG_ADD_VAR(IMPLICIT_TURNOVER_RATE, double, 0.0, "Number of programids recycled per CPU cycle. 0 = OFF");
   CONFIG_ADD_VAR(IMPLICIT_MAX_PROGRAMID_LENGTH, int, 0, "Creation of an executable programid terminates after this many instructions. 0 = disabled");
-//  CONFIG_ADD_VAR(CLEAR_ON_OUTPUT, int, 0, "Reset input buffer every time output called?"); @JEB Not fully implemented
+  //  CONFIG_ADD_VAR(CLEAR_ON_OUTPUT, int, 0, "Reset input buffer every time output called?"); @JEB Not fully implemented
 
   CONFIG_ADD_GROUP(PROMOTER_GROUP, "Promoters");
   CONFIG_ADD_VAR(PROMOTERS_ENABLED, int, 0, "Use the promoter/terminator execution scheme.\nCertain instructions must also be included.");
@@ -388,6 +388,12 @@
   CONFIG_ADD_VAR(COLOR_MUT_NEG,    cString, "FFFF00", "Color to flag stat that has changed since parent.");
   CONFIG_ADD_VAR(COLOR_MUT_LETHAL, cString, "FF0000", "Color to flag stat that has changed since parent.");
 
+  // @WRE: Additions for approaching various features of biological organisms
+  CONFIG_ADD_GROUP(BIOMIMETIC_GROUP, "Biomimetic Features Settings");
+  CONFIG_ADD_VAR(BIOMIMETIC_REFRACTORY_PERIOD, double, 0.0, "Number of updates affected by refractory period");
+  CONFIG_ADD_VAR(BIOMIMETIC_MOVEMENT_STEP, int, 0, "Number of cells to move Avidian on move instruction");
+  CONFIG_ADD_VAR(BIOMIMETIC_K, int, 0, "Carrying capacity in number of organisms");
+  
 #endif
   
   void Load(const cString& filename, const bool& crash_if_not_found);

Modified: development/source/main/cBirthChamber.cc
===================================================================
--- development/source/main/cBirthChamber.cc	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cBirthChamber.cc	2007-07-10 17:55:03 UTC (rev 1777)
@@ -39,8 +39,14 @@
 
 cBirthChamber::cBirthChamber(cWorld* world) : m_world(world)
 {
-  const int num_orgs = m_world->GetConfig().WORLD_X.Get() * m_world->GetConfig().WORLD_Y.Get();
   const int num_demes = m_world->GetConfig().NUM_DEMES.Get(); 
+  int num_orgs;
+
+  num_orgs = m_world->GetConfig().BIOMIMETIC_K.Get();
+  if (0 >= num_orgs) {
+    num_orgs = m_world->GetConfig().WORLD_X.Get() * m_world->GetConfig().WORLD_Y.Get();
+  }
+
   local_wait_entry.Resize(num_orgs);
   deme_wait_entry.Resize(num_demes);
 }

Modified: development/source/main/cEnvironment.cc
===================================================================
--- development/source/main/cEnvironment.cc	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cEnvironment.cc	2007-07-10 17:55:03 UTC (rev 1777)
@@ -787,6 +787,17 @@
 }
 
 
+void cEnvironment::SwapInputs(cAvidaContext& ctx, tArray<int>& src_input_array, tArray<int>& dest_input_array) const
+{
+  tArray<int>& tmp_input_array = dest_input_array;
+
+  // Just swap the pointers around.  
+  dest_input_array = src_input_array;
+  src_input_array = tmp_input_array;
+  
+}
+
+
 bool cEnvironment::TestInput(cReactionResult& result, const tBuffer<int>& inputs,
                              const tBuffer<int>& outputs, const tArray<double>& resource_count) const
 {

Modified: development/source/main/cEnvironment.h
===================================================================
--- development/source/main/cEnvironment.h	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cEnvironment.h	2007-07-10 17:55:03 UTC (rev 1777)
@@ -119,7 +119,9 @@
 
   // Interaction with the organisms
   void SetupInputs(cAvidaContext& ctx, tArray<int>& input_array, bool random = true) const;
+  void SwapInputs(cAvidaContext& ctx, tArray<int>& src_input_array, tArray<int>& dest_input_array) const;
 
+
   bool TestInput(cReactionResult& result, const tBuffer<int>& inputs,
                  const tBuffer<int>& outputs, const tArray<double>& resource_count) const;
 

Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cPhenotype.cc	2007-07-10 17:55:03 UTC (rev 1777)
@@ -49,6 +49,7 @@
   , cur_reaction_add_reward(m_world->GetEnvironment().GetReactionLib().GetSize())
   , cur_inst_count(world->GetHardwareManager().GetInstSet().GetSize())
   , cur_sense_count(m_world->GetStats().GetSenseSize())
+  , cur_task_time(m_world->GetEnvironment().GetNumTasks())   // Added for tracking time; WRE 03-18-07
   , sensed_resources(m_world->GetEnvironment().GetResourceLib().GetSize())
   , promoter_last_inst_terminated(false) 
   , last_task_count(m_world->GetEnvironment().GetNumTasks())
@@ -142,6 +143,7 @@
   cur_reaction_add_reward.SetAll(0);
   cur_inst_count.SetAll(0);
   cur_sense_count.SetAll(0);  
+  cur_task_time.SetAll(0.0);  // Added for time tracking; WRE 03-18-07
   for (int j = 0; j < sensed_resources.GetSize(); j++)
 	      sensed_resources[j] =  parent_phenotype.sensed_resources[j];
   SetupPromoterWeights(_genome, true);
@@ -271,6 +273,7 @@
   cur_inst_count.SetAll(0);
   sensed_resources.SetAll(0);
   cur_sense_count.SetAll(0);
+  cur_task_time.SetAll(0.0);
   SetupPromoterWeights(_genome, true);
   
   // Copy last values from parent
@@ -418,6 +421,7 @@
   cur_reaction_add_reward.SetAll(0);
   cur_inst_count.SetAll(0);
   cur_sense_count.SetAll(0);
+  cur_task_time.SetAll(0.0);
 
   // Setup other miscellaneous values...
   num_divides++;
@@ -553,6 +557,7 @@
   cur_reaction_add_reward.SetAll(0);
   cur_inst_count.SetAll(0);
   cur_sense_count.SetAll(0); 
+  cur_task_time.SetAll(0.0);
   sensed_resources.SetAll(-1.0);
   SetupPromoterWeights(_genome, true);
   
@@ -666,6 +671,7 @@
   cur_reaction_add_reward.SetAll(0);
   cur_inst_count.SetAll(0);
   cur_sense_count.SetAll(0);  
+  cur_task_time.SetAll(0.0);
   for (int j = 0; j < sensed_resources.GetSize(); j++)
 	      sensed_resources[j] =  clone_phenotype.sensed_resources[j];
   //SetupPromoterWeights(_genome); Do we reset here?
@@ -778,6 +784,11 @@
   const int num_tasks = env.GetNumTasks();
   const int num_reactions = env.GetReactionLib().GetSize();
 
+  // For refractory period @WRE 03-20-07
+  const int cur_update_time = m_world->GetStats().GetUpdate();
+  const double biomimetic_refractory_period = m_world->GetConfig().BIOMIMETIC_REFRACTORY_PERIOD.Get();
+  double refract_factor;
+
   cReactionResult result(num_resources, num_tasks, num_reactions);
 			
   // Run everything through the environment.
@@ -792,14 +803,25 @@
   // Update the phenotype with the results...
   // Start with updating task and reaction counters
   for (int i = 0; i < num_tasks; i++) {
+    // Calculate refractory period factor @WRE
+    // Modify TaskQuality amount based on refractory period
+    // Logistic equation using refractory period
+    // in update units from configuration file.  @WRE 03-20-07, 04-17-07
+    if (0.0 == biomimetic_refractory_period) {
+      refract_factor = 1.0;
+    } else {
+      refract_factor = 1.0 - (1.0 / (1.0 + exp((cur_update_time - cur_task_time[i])-biomimetic_refractory_period*0.5)));
+    }
     if (result.TaskDone(i) == true) 
     {
       cur_task_count[i]++;
       eff_task_count[i]++;
     }
-    if (result.TaskQuality(i) > 0) cur_task_quality[i]+= result.TaskQuality(i);
-	cur_task_value[i] = result.TaskValue(i);
+    if (result.TaskQuality(i) > 0) cur_task_quality[i]+= result.TaskQuality(i) * refract_factor;
+    cur_task_value[i] = result.TaskValue(i);
+    cur_task_time[i] = cur_update_time; // Find out time from context
   }
+
   for (int i = 0; i < num_reactions; i++) {
     if (result.ReactionTriggered(i) == true) cur_reaction_count[i]++;
     cur_reaction_add_reward[i] += result.GetReactionAddBonus(i);

Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cPhenotype.h	2007-07-10 17:55:03 UTC (rev 1777)
@@ -119,6 +119,7 @@
   tArray<int> cur_inst_count;                 // Instruction exection counter
   tArray<int> cur_sense_count;                // Total times resource combinations have been sensed; @JEB 
   tArray<double> sensed_resources;            // Resources which the organism has sensed; @JEB 
+  tArray<double> cur_task_time;    // Time at which each task was last performed; WRE 03-18-07
   tArray<cCodeLabel> active_transposons;      // Transposons that are active; @JEB
   tArray<double> base_promoter_weights;       // Baseline chance of starting execution from each position; @JEB 
   tArray<double> cur_promoter_weights;        // Current of starting execution from each position, adjusted for regulation; @JEB 

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cPopulation.cc	2007-07-10 17:55:03 UTC (rev 1777)
@@ -473,6 +473,95 @@
   
 }
 
+// @WRE 2007/07/05 Helper function to take care of side effects of Avidian 
+// movement that cannot be directly handled in cHardwareCPU.cc
+void cPopulation::MoveOrganisms(cAvidaContext& ctx, cPopulationCell& src_cell, cPopulationCell& dest_cell)
+{
+  // Declarations
+  int actualNeighborhoodSize, fromFacing, destFacing, newFacing, success;
+#ifdef DEBBUG
+  int sID, dID, xx1, yy1, xx2, yy2;
+#endif
+
+  // Swap inputs between cells to fix bus error when Avidian moves into an unoccupied cell
+  environment.SwapInputs(ctx, src_cell.input_array, dest_cell.input_array);
+  
+  // Find neighborhood size for facing 
+  if (NULL != dest_cell.GetOrganism()) {
+    actualNeighborhoodSize = dest_cell.GetOrganism()->GetNeighborhoodSize();
+  } else {
+    if (NULL != src_cell.GetOrganism()) {
+      actualNeighborhoodSize = src_cell.GetOrganism()->GetNeighborhoodSize();
+    } else {
+      // Punt
+      actualNeighborhoodSize = 8;
+    }
+  }
+ 
+  // Swap cell facings between cells, so that if movement is directed, it continues to be associated with
+  // the same organism
+  // Determine absolute facing for each cell
+  fromFacing = src_cell.GetFacing();
+  destFacing = dest_cell.GetFacing();
+
+  // Set facing in source cell
+  success = 0;
+  newFacing = destFacing;
+  for(int i = 0; i < actualNeighborhoodSize; i++) {
+    if (src_cell.GetFacing() != newFacing) {
+      src_cell.ConnectionList().CircNext();
+      //cout << "MO: src_cell facing not yet at " << newFacing << endl;
+    } else {
+      //cout << "MO: src_cell facing successfully set to " << newFacing << endl;
+      success = 1;
+      break;
+    }
+  }
+#ifdef DEBUG
+  if (!success) {
+    sID = src_cell.GetID();
+    dID = dest_cell.GetID();
+    src_cell.GetPosition(xx1,yy1);
+    dest_cell.GetPosition(xx2,yy2);
+    //Conditional for examining only neighbor move without swap in facing
+    //if (1 == abs(xx2-xx1)+abs(yy2-yy1)) {
+    cout << "MO: src: " << sID << "@ (" << xx1 << "," << yy1 << ") dest: " << dID << "@ (" << xx2 << "," << yy2 << "), FAILED to set src_cell facing to " << newFacing << endl;
+    for (int j=0; j < actualNeighborhoodSize; j++) {
+      src_cell.ConnectionList().CircNext();
+      src_cell.GetCellFaced().GetPosition(xx2,yy2);
+      cout << "connlist for " << sID << ": facing " << src_cell.GetFacing() << " -> (" << xx2 << "," << yy2 << ")" << endl;
+    }
+    //}
+  }
+#endif 
+
+  // Set facing in destinatiion cell
+  success = 0;
+  newFacing = fromFacing;
+  for(int i = 0; i < actualNeighborhoodSize; i++) {
+    if (dest_cell.GetFacing() != newFacing) {
+      dest_cell.ConnectionList().CircNext();
+      // cout << "MO: dest_cell facing not yet at " << newFacing << endl;
+    } else {
+      // cout << "MO: dest_cell facing successfully set to " << newFacing << endl;
+      success = 1;
+      break;
+    }
+  }
+#ifdef DEBUG
+  if (!success) {
+    sID = src_cell.GetID();
+    dID = dest_cell.GetID();
+    src_cell.GetPosition(xx1,yy1);
+    dest_cell.GetPosition(xx2,yy2);
+    if (1 == abs(xx2-xx1)+abs(yy2-yy1)) {
+      cout << "MO: src: " << sID << "@ (" << xx1 << "," << yy1 << ") dest: " << dID << "@ (" << xx2 << "," << yy2 << "), FAILED to set dest_cell facing to " << newFacing << endl;
+    }
+  }
+#endif
+  
+}
+
 void cPopulation::KillOrganism(cPopulationCell& in_cell)
 {
   // do we actually have something to kill?
@@ -659,24 +748,34 @@
 
 void cPopulation::SwapCells(cPopulationCell & cell1, cPopulationCell & cell2)
 {
+  // Sanity checks: Don't process if the cells are the same and 
+  // don't bother trying to move when given a cell that isn't there
+  //cout << "SwapCells: testing if cell1 and cell2 are non-null" << endl;
+  //if (!(NULL != cell1) || !(NULL != cell2)) return;
+  if ((&cell1 == NULL) || (&cell2 == NULL)) return;
+  //cout << "SwapCells: testing if cell1 and cell2 are different" << endl;  
+  if (cell1.GetID() == cell2.GetID()) return;
+  // Clear current contents of cells
+  //cout << "SwapCells: clearing cell contents" << endl;
   cOrganism * org1 = cell1.RemoveOrganism();
   cOrganism * org2 = cell2.RemoveOrganism();
+  //cout << "SwapCells: organism 2 is non-null, fix up source cell" << endl;
   if (org2 != NULL) {
     cell1.InsertOrganism(*org2);
     schedule->Adjust(cell1.GetID(), org2->GetPhenotype().GetMerit());
   } else {
     schedule->Adjust(cell1.GetID(), cMerit(0));
   }
-
+  //cout << "SwapCells: organism 1 is non-null, fix up dest cell" << endl;
   if (org1 != NULL) {
     cell2.InsertOrganism(*org1);
     schedule->Adjust(cell2.GetID(), org1->GetPhenotype().GetMerit());
   } else {
     schedule->Adjust(cell2.GetID(), cMerit(0));
   }
+  //cout << "SwapCells: Done." << endl;
 }
 
-
 // CompeteDemes  probabilistically copies demes into the next generation
 // based on their fitness. How deme fitness is estimated is specified by 
 // competition_type input argument as:
@@ -1638,6 +1737,12 @@
 
 void cPopulation::UpdateOrganismStats()
 {
+  // Carrying capacity @WRE 04-20-07
+  // Check for positive non-zero carrying capacity and apply it
+  if (0 < m_world->GetConfig().BIOMIMETIC_K.Get()) {
+    SerialTransfer(m_world->GetConfig().BIOMIMETIC_K.Get(),true);
+  }
+
   // Loop through all the cells getting stats and doing calculations
   // which must be done on a creature by creature basis.
   

Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cPopulation.h	2007-07-10 17:55:03 UTC (rev 1777)
@@ -162,6 +162,10 @@
   
   // Deactivate an organism in the population (required for deactivations)
   void KillOrganism(cPopulationCell& in_cell);
+  
+  // @WRE 2007/07/05 Helper function to take care of side effects of Avidian 
+  // movement that cannot be directly handled in cHardwareCPU.cc
+  void MoveOrganisms(cAvidaContext& ctx, cPopulationCell& src_cell, cPopulationCell& dest_cell);
 
   // Specialized functionality
   void Kaboom(cPopulationCell& in_cell, int distance=0);

Modified: development/tests/_testrunner/testrunner.cfg
===================================================================
--- development/tests/_testrunner/testrunner.cfg	2007-07-10 17:27:15 UTC (rev 1776)
+++ development/tests/_testrunner/testrunner.cfg	2007-07-10 17:55:03 UTC (rev 1777)
@@ -1,5 +1,5 @@
 [testrunner]
-builddir = cbuild
+builddir = .
 mode = local
 svn = svn
 svnversion = svnversion




More information about the Avida-cvs mailing list