[Avida-SVN] r2785 - branches/movement/source/cpu

welsberr at myxo.css.msu.edu welsberr at myxo.css.msu.edu
Sun Sep 14 17:09:42 PDT 2008


Author: welsberr
Date: 2008-09-14 20:09:41 -0400 (Sun, 14 Sep 2008)
New Revision: 2785

Modified:
   branches/movement/source/cpu/cHardwareCPU.cc
   branches/movement/source/cpu/cHardwareCPU.h
Log:
Added sense-diff-facing instruction

Modified: branches/movement/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/movement/source/cpu/cHardwareCPU.cc	2008-09-14 23:26:47 UTC (rev 2784)
+++ branches/movement/source/cpu/cHardwareCPU.cc	2008-09-15 00:09:41 UTC (rev 2785)
@@ -208,6 +208,7 @@
     tInstLibEntry<tMethod>("sense", &cHardwareCPU::Inst_SenseLog2, nInstFlag::STALL),           // If you add more sense instructions
     tInstLibEntry<tMethod>("sense-unit", &cHardwareCPU::Inst_SenseUnit, nInstFlag::STALL),      // and want to keep stats, also add
     tInstLibEntry<tMethod>("sense-m100", &cHardwareCPU::Inst_SenseMult100, nInstFlag::STALL),   // the names to cStats::cStats() @JEB
+	tInstLibEntry<tMethod>("sense-diff-facing", &cHardwareCPU::Inst_SenseDiffFacing, nInstFlag::STALL),
     tInstLibEntry<tMethod>("if-resources", &cHardwareCPU::Inst_IfResources, nInstFlag::STALL),
     // Data collection
     tInstLibEntry<tMethod>("collect-cell-data", &cHardwareCPU::Inst_CollectCellData, nInstFlag::STALL),
@@ -3290,7 +3291,149 @@
   // Note that we are converting <double> resources to <int> register values
 }
 
+bool cHardwareCPU::Inst_SenseDiffFacing(cAvidaContext& ctx)
+{
+  return DoSenseDiffFacing(ctx, 1, 1000);
+}
+ 
+bool cHardwareCPU::DoSenseDiffFacing(cAvidaContext& ctx, int conversion_method, double base)
+{
+  // Returns the amount of a resource or resources
+  // specified by modifying NOPs into register BX
+  const tArray<double> res_count = organism->GetOrgInterface().GetResources() +
+    organism->GetOrgInterface().GetDemeResources(organism->GetOrgInterface().GetDemeID());
 
+  int facedcellID;
+  // Get population
+  cPopulation& pop = m_world->GetPopulation();
+
+  // @WRE: This sort of thing wasn't needed for the regular organism-linked sense instructions
+  if (0 > organism->GetCellID()) return false;
+  facedcellID = pop.GetCell(organism->GetCellID()).GetCellFaced().GetID();
+  if (0 > facedcellID) return false;
+  const tArray<double> & facedres_count = pop.GetResourceCount().GetCellResources(facedcellID);
+
+  // Arbitrarily set to BX since the conditional instructions use this directly.
+  int reg_to_set = REG_BX;
+  int reg_comp = REG_CX;
+
+  // There are no resources, return
+  if ((res_count.GetSize() == 0) || (facedres_count.GetSize() == 0)) return false;
+
+  // Only recalculate logs if these values have changed
+  static int last_num_resources = 0;
+  static int max_label_length = 0;
+  int num_nops = GetInstSet().GetNumNops();
+
+  if ((last_num_resources != res_count.GetSize()))
+  {
+      max_label_length = (int) ceil(log((double)res_count.GetSize())/log((double)num_nops));
+      last_num_resources = res_count.GetSize();
+  }
+
+  // Convert modifying NOPs to the index of the resource.
+  // If there are fewer than the number of NOPs required
+  // to uniquely specify a resource, then add together
+  // a subset of resources (motivation: regulation can evolve
+  // to be more specific if there is an advantage)
+
+  // Find the maximum number of NOPs needed to specify this number of resources
+  // Note: It's a bit wasteful to recalculate this every time and organisms will
+  // definitely be confused if the number of resources changes during a run
+  // because their mapping to resources will be disrupted
+
+  // Attempt to read a label with this maximum length
+  ReadLabel(max_label_length);
+
+  // Find the length of the label that we actually obtained (max is max_reg_needed)
+  int real_label_length = GetLabel().GetSize();
+
+  // Start and end labels to define the start and end indices of
+  // resources that we need to add together
+  cCodeLabel start_label = cCodeLabel(GetLabel());
+  cCodeLabel   end_label = cCodeLabel(GetLabel());
+
+  for (int i = 0; i < max_label_length - real_label_length; i++)
+  {
+    start_label.AddNop(0);
+    end_label.AddNop(num_nops-1);
+  }
+
+  int start_index = start_label.AsInt(num_nops);
+  int   end_index =   end_label.AsInt(num_nops);
+
+  // If the label refers to ONLY resources that
+  // do not exist, then the operation fails
+  if (start_index >= res_count.GetSize()) return false;
+
+  // Otherwise sum all valid resources that it might refer to
+  // (this will only be ONE if the label was of the maximum length).
+  int resource_result = 0;
+  double dresource_result = 0;
+  for (int i = start_index; i <= end_index; i++)
+  {
+    // if it's a valid resource
+    if (i < res_count.GetSize())
+    {
+      if (conversion_method == 0) // Log
+      {
+        // for log, add together and then take log
+	dresource_result += ( (double) facedres_count[i] - (double) res_count[i]);
+      }
+      else if (conversion_method == 1) // Addition of multiplied resource amount
+      {
+        int add_amount = ( (int) ((facedres_count[i] - res_count[i]) * base));
+        // Do some range checking to make sure we don't overflow
+	resource_result = (INT_MAX - resource_result <= add_amount) ? INT_MAX : resource_result + add_amount;
+      }
+    }
+  }
+
+  // Take the log after adding resource amounts together! This way a zero can be assigned to INT_MIN
+  if (conversion_method == 0) // Log2
+  {
+    // You really shouldn't be using the log method if you can get to zero resources
+    if(dresource_result == 0.0)
+    {
+      resource_result = INT_MIN;
+    }
+    else
+    {
+      resource_result = (int)(log(dresource_result)/log(base));
+    }
+  }
+
+  //Dump this value into an arbitrary register: BX
+  GetRegister(reg_to_set) = resource_result;
+  // Clear the complement register so conditionals will work
+  GetRegister(reg_comp) = 0;
+
+  // @WRE: Not sure why this code doesn't work
+  /*
+  //We have to convert this to a different index that includes all degenerate labels possible: shortest to longest
+  int sensed_index = 0;
+  int on = 1;
+  for (int i = 0; i < real_label_length; i++)
+  {
+    sensed_index += on;
+    on *= num_nops;
+  }
+  sensed_index+= GetLabel().AsInt(num_nops);
+  organism->GetPhenotype().IncSenseCount(sensed_index);
+  */
+
+  // Possible reward for sensing
+  const int reg_used = FindModifiedRegister(REG_BX);
+  const int value = GetRegister(reg_used);
+  // GetRegister(reg_used) = 0;
+  organism->DoOutput(ctx, value);
+
+  return true;
+
+  // Note that we are converting <double> resources to <int> register values
+} // DoSenseDiffFacing
+
+
 /*! Sense the level of resources in this organism's cell, and if all of the 
 resources present are above the min level for that resource, execute the following
 intruction.  Otherwise, skip the following instruction.

Modified: branches/movement/source/cpu/cHardwareCPU.h
===================================================================
--- branches/movement/source/cpu/cHardwareCPU.h	2008-09-14 23:26:47 UTC (rev 2784)
+++ branches/movement/source/cpu/cHardwareCPU.h	2008-09-15 00:09:41 UTC (rev 2785)
@@ -464,6 +464,9 @@
   bool Inst_SenseUnit(cAvidaContext& ctx);
   bool Inst_SenseMult100(cAvidaContext& ctx);
   bool DoSense(cAvidaContext& ctx, int conversion_method, double base);
+  // @WRE: Single local-knowledge sense instruction. 14-Sep-2008
+  bool Inst_SenseDiffFacing(cAvidaContext& ctx);
+  bool DoSenseDiffFacing(cAvidaContext& ctx, int conversion_method, double base);
   //! Execute the following instruction if all resources are above their min level.
   bool Inst_IfResources(cAvidaContext& ctx);
   bool Inst_CollectCellData(cAvidaContext& ctx);




More information about the Avida-cvs mailing list