[Avida-cvs] [avida-svn] r974 - development/source/cpu

barrick at myxo.css.msu.edu barrick at myxo.css.msu.edu
Sat Sep 23 10:46:03 PDT 2006


Author: barrick
Date: 2006-09-23 13:46:02 -0400 (Sat, 23 Sep 2006)
New Revision: 974

Modified:
   development/source/cpu/cHardwareCPU.cc
Log:
updated sense instruction

Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2006-09-22 19:18:16 UTC (rev 973)
+++ development/source/cpu/cHardwareCPU.cc	2006-09-23 17:46:02 UTC (rev 974)
@@ -345,9 +345,7 @@
     cInstEntryCPU("kazi",	&cHardwareCPU::Inst_Kazi),
     cInstEntryCPU("kazi5",	&cHardwareCPU::Inst_Kazi5),
     cInstEntryCPU("die",	&cHardwareCPU::Inst_Die),
-    
-    
-    
+	    
     // Placebo instructions
     // nop-x (included with nops)
     cInstEntryCPU("skip",      &cHardwareCPU::Inst_Skip)
@@ -2729,20 +2727,80 @@
 
 bool cHardwareCPU::Inst_Sense(cAvidaContext& ctx)
 {
-  const tArray<double>& res_count = organism->GetOrgInterface().GetResources();
-  const int reg_used = FindModifiedRegister(REG_BX);
-  
-  // If there are no resources to measure, this instruction fails.
+  // Returns the log2 amount of a resource or resources 
+  // specified by modifying NOPs into register BX
+
+  const tArray<double> & res_count = organism->GetOrgInterface().GetResources();
+
+  // Arbitrarily set to BX since the conditionals use this directly.
+  int reg_to_set = cHardwareCPU::REG_BX;
+
+  // There are no resources, return
   if (res_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;
+ 
+  if ((last_num_resources != res_count.GetSize()))
+  {
+      int max_label_length = (int) ceil(log(res_count.GetSize())/log(cHardwareCPU::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
   
-  // Always get the first resource, and convert it to and int.
-  GetRegister(reg_used) = (int) res_count[0];
+  // Attempt to read a label with this maximum length
+  cHardwareCPU::ReadLabel(max_label_length);
   
-  // @CAO Since resources are sometimes less than one, perhaps we should
-  // multiply it by some constant?  Or perhaps taking the log would be more
-  // useful so they can easily scan across orders of magnitude?
+  // Find the length of the label that we actually obtained (max is max_reg_needed)
+  int real_label_length = GetLabel().GetSize();
   
-  return true;
+  // 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(cHardwareCPU::NUM_NOPS-1);
+  }
+  
+  int start_index = start_label.AsInt(cHardwareCPU::NUM_NOPS);
+  int   end_index =   end_label.AsInt(cHardwareCPU::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;
+  for (int i = start_index; i <= end_index; i++)
+  {
+    // if it's a valid resource and not zero
+    // (alternately you could assign min_int for zero resources, but
+    // that would cause wierdness when adding sense values together)
+    if ((i < res_count.GetSize()) && (res_count[i] > 0)) resource_result += (int)(log(res_count[i])/0.69314718056);
+    // 0.69314718056 is log (2)
+  }
+    
+  //Dump this value into an arbitrary register: BX
+  GetRegister(reg_to_set) = resource_result;
+  
+  return true; 
+
+  // Note that we are converting <double> resources to <int> register values
 }
 
 void cHardwareCPU::DoDonate(cOrganism* to_org)
@@ -3355,7 +3413,6 @@
 return true; 
 }
 
-
 //// Placebo insts ////
 bool cHardwareCPU::Inst_Skip(cAvidaContext& ctx)
 {




More information about the Avida-cvs mailing list