[Avida-SVN] r1450 - in development: source/cpu source/main support/config

barrick at myxo.css.msu.edu barrick at myxo.css.msu.edu
Mon Apr 2 10:32:12 PDT 2007


Author: barrick
Date: 2007-04-02 13:32:12 -0400 (Mon, 02 Apr 2007)
New Revision: 1450

Modified:
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/cpu/cTestCPU.cc
   development/source/cpu/cTestCPUInterface.cc
   development/source/main/cAvidaConfig.h
   development/source/main/cOrganism.cc
   development/source/main/cPhenotype.cc
   development/source/main/cPhenotype.h
   development/source/main/cPopulation.cc
   development/support/config/avida.cfg
Log:
Promoter Model.

Enabling promoter mode causes the CPU to initiate probabalistically at "promoter" instructions and fall off at "terminate" instructions. There are also instructions for modifying the activation/repression level of nearby promoters based on matching upstream NOP labels.

For now promoter information is stored in CPhenotype. As we create the GX cpu model, it will probably need to become part of a new cCPUMemory derivative.



Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/cpu/cHardwareCPU.cc	2007-04-02 17:32:12 UTC (rev 1450)
@@ -221,6 +221,7 @@
     
     // Head-based instructions
     tInstLibEntry<tMethod>("h-alloc", &cHardwareCPU::Inst_MaxAlloc, nInstFlag::DEFAULT, "Allocate maximum allowed space"),
+    tInstLibEntry<tMethod>("h-alloc-mw", &cHardwareCPU::Inst_MaxAllocMoveWriteHead),
     tInstLibEntry<tMethod>("h-divide", &cHardwareCPU::Inst_HeadDivide, nInstFlag::DEFAULT, "Divide code between read and write heads."),
     tInstLibEntry<tMethod>("h-divide1RS", &cHardwareCPU::Inst_HeadDivide1RS, 0, "Divide code between read and write heads, at most one mutation on divide, resample if reverted."),
     tInstLibEntry<tMethod>("h-divide2RS", &cHardwareCPU::Inst_HeadDivide2RS, 0, "Divide code between read and write heads, at most two mutations on divide, resample if reverted."),
@@ -321,9 +322,19 @@
     tInstLibEntry<tMethod>("kazi",	&cHardwareCPU::Inst_Kazi),
     tInstLibEntry<tMethod>("kazi5", &cHardwareCPU::Inst_Kazi5),
     tInstLibEntry<tMethod>("die", &cHardwareCPU::Inst_Die),
-	    
+
+    // Promoter Model
+    tInstLibEntry<tMethod>("up-reg-*", &cHardwareCPU::Inst_UpRegulatePromoter),
+    tInstLibEntry<tMethod>("down-reg-*", &cHardwareCPU::Inst_DownRegulatePromoter),
+    tInstLibEntry<tMethod>("up-reg", &cHardwareCPU::Inst_UpRegulatePromoterNop),
+    tInstLibEntry<tMethod>("down-reg", &cHardwareCPU::Inst_DownRegulatePromoterNop),
+    tInstLibEntry<tMethod>("terminate", &cHardwareCPU::Inst_Terminate),
+    tInstLibEntry<tMethod>("promoter", &cHardwareCPU::Inst_Promoter),
+    tInstLibEntry<tMethod>("decay-reg", &cHardwareCPU::Inst_DecayRegulation),
+    
     // Placebo instructions
-    tInstLibEntry<tMethod>("skip", &cHardwareCPU::Inst_Skip)
+    tInstLibEntry<tMethod>("skip", &cHardwareCPU::Inst_Skip),
+
   };
   
   const int n_size = sizeof(s_n_array)/sizeof(cNOPEntryCPU);
@@ -437,6 +448,13 @@
   organism->SetRunning(true);
   
   cPhenotype & phenotype = organism->GetPhenotype();
+  
+  //First instruction - check whether we should be starting at a promoter.
+  if (phenotype.GetTimeUsed() == 0)
+  {
+    if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) Inst_Terminate(m_world->GetDefaultContext());
+  }
+  
   phenotype.IncTimeUsed();
   phenotype.IncCPUCyclesUsed();
 
@@ -450,6 +468,15 @@
   for (int i = 0; i < num_inst_exec; i++) {
     // Setup the hardware for the next instruction to be executed.
     ThreadNext();
+    
+    // In the promoter model, there may be a chance of termination
+    // that causes execution to start at a new instruction
+    const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY.Get();
+    if (processivity < 1)
+    {
+      if ( ctx.GetRandom().P(1-processivity) ) Inst_Terminate(ctx);
+    }
+    
     m_advance_ip = true;
     IP().Adjust();
     
@@ -532,8 +559,8 @@
   return true;
 }
 
-// This method will handle the actuall execution of an instruction
-// within single process, once that function has been finalized.
+// This method will handle the actual execution of an instruction
+// within a single process, once that function has been finalized.
 bool cHardwareCPU::SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst) 
 {
   // Copy Instruction locally to handle stochastic effects
@@ -544,7 +571,7 @@
   if (organism->TestExeErr()) actual_inst = m_inst_set->GetRandomInst(ctx);
 #endif /* EXECUTION_ERRORS */
   
-  // Get a pointer to the corrisponding method...
+  // Get a pointer to the corresponding method...
   int inst_idx = m_inst_set->GetLibFunctionIndex(actual_inst);
   
   // Mark the instruction as executed
@@ -552,7 +579,7 @@
 	
   
 #if INSTRUCTION_COUNT
-  // instruction execution count incremeneted
+  // instruction execution count incremented
   organism->GetPhenotype().IncCurInstCount(actual_inst.GetOp());
 #endif
 	
@@ -560,7 +587,7 @@
   const bool exec_success = (this->*(m_functions[inst_idx]))(ctx);
 	
 #if INSTRUCTION_COUNT
-  // decremenet if the instruction was not executed successfully
+  // decrement if the instruction was not executed successfully
   if (exec_success == false) {
     organism->GetPhenotype().DecCurInstCount(actual_inst.GetOp());
   }
@@ -1094,7 +1121,7 @@
 bool cHardwareCPU::Allocate_Random(cAvidaContext& ctx, const int old_size, const int new_size)
 {
   GetMemory().Resize(new_size);
-  
+
   for (int i = old_size; i < new_size; i++) {
     GetMemory()[i] = m_inst_set->GetRandomInst(ctx);
   }
@@ -1164,7 +1191,7 @@
   }
   
   m_mal_active = true;
-  
+
   return true;
 }
 
@@ -2376,6 +2403,20 @@
   } else return false;
 }
 
+// Alloc and move write head if we're successful
+bool cHardwareCPU::Inst_MaxAllocMoveWriteHead(cAvidaContext& ctx)   // Allocate maximal more
+{
+  const int dst = REG_AX;
+  const int cur_size = GetMemory().GetSize();
+  const int alloc_size = Min((int) (m_world->GetConfig().CHILD_SIZE_RANGE.Get() * cur_size),
+                             MAX_CREATURE_SIZE - cur_size);
+  if (Allocate_Main(ctx, alloc_size)) {
+    GetRegister(dst) = cur_size;
+    GetHead(nHardware::HEAD_WRITE).Set(cur_size);
+    return true;
+  } else return false;
+}
+
 bool cHardwareCPU::Inst_Transposon(cAvidaContext& ctx)
 {
   ReadLabel();
@@ -2669,8 +2710,7 @@
 }
 
 
-// @JEB - this instruction does more than two "gets" together
-// it also (1) resets the inputs and (2) resets an organisms task counts
+// @JEB - this instruction does more than two "gets" together, it also resets the inputs
 bool cHardwareCPU::Inst_TaskGet2(cAvidaContext& ctx)
 {
   // Randomize the inputs so they can't save numbers
@@ -2690,7 +2730,7 @@
   organism->DoInput(value2);
   
   // Clear the task number
-  organism->GetPhenotype().ClearEffTaskCount();
+  //organism->GetPhenotype().ClearEffTaskCount();
   
   return true;
 }
@@ -3255,7 +3295,7 @@
 {
   const int head_used = FindModifiedHead(nHardware::HEAD_IP);
   GetHead(head_used).Jump(GetRegister(REG_CX) );
-  // JEB - probably shouldn't advance inst ptr after jumping here?
+  // @JEB - probably shouldn't advance IP after jumping here?
   // Any negative number jumps to the beginning of the genome (pos 0)
   // and then we immediately advance past that first instruction.
   return true;
@@ -3553,6 +3593,220 @@
 return true; 
 }
 
+//// Promoter Model ////
+
+// Starting at the current position reads a promoter pattern
+bool cHardwareCPU::GetPromoterPattern(tArray<int>& promoter)
+{
+  // For now a constant that defines behavior
+  const int max_size = 6;
+  int count = 0;
+  
+  cHeadCPU& inst_ptr = IP();
+    
+  while ( (inst_ptr.GetNextInst().GetOp() != m_inst_set->GetNumNops() - 1) &&
+         (count < max_size) ) {
+    count++;
+    inst_ptr++;
+    promoter.Push(inst_ptr.GetInst().GetOp());
+    // If this is the first line of the template, mark it executed.
+    //if (GetLabel().GetSize() <=	m_world->GetConfig().MAX_LABEL_EXE_SIZE.Get()) {
+    //  inst_ptr->SetFlagExecuted();
+    //}
+  }
+
+}
+
+
+// Adjust the weight at promoter positions that match the downstream pattern
+// allowing wildcards and matching of instructions
+bool cHardwareCPU::RegulatePromoter(cAvidaContext& ctx, bool up)
+{
+  static cInstruction promoter_inst = GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
+
+  // Save the initial site so we don't match our own pattern
+  cHeadCPU inst_ptr(IP());
+
+  tArray<int> promoter;
+  GetPromoterPattern(promoter);
+  if (promoter.GetSize() == 0) return true;
+
+  // nop-A is a wildcard of length 1
+  // nop-B is a wildcard of length 1
+  // nop-C (the final nop) terminates the matching pattern, and is not included
+  
+  cHeadCPU search_head(IP());  
+  while (search_head.GetPosition() != inst_ptr.GetPosition()) 
+  {
+    cHeadCPU match_head(search_head);
+    int matched_pos = 0;
+    while (matched_pos < promoter.GetSize())
+    {
+      // Unless the promoter pattern has a nop, we must match the instruction exactly
+      if ( (promoter[matched_pos] > m_inst_set->GetNumNops())
+        && (promoter[matched_pos] != match_head.GetInst().GetOp()) )
+      {
+        break;
+      }
+      matched_pos++;
+      match_head++;
+    }
+    
+    // Successfully matched, change this promoter position weight
+    if (matched_pos == promoter.GetSize())
+    {
+      cHeadCPU change_head(search_head);
+      for (int j=0; j < 5; j++)
+      {
+        change_head++;
+        if (change_head.GetInst() == promoter_inst) {
+          organism->GetPhenotype().RegulatePromoter(change_head.GetPosition(), up);
+        }
+      }
+    }
+    search_head++;
+  }
+  
+  // Debugging code
+  /*
+  tArray<double> w = organism->GetPhenotype().GetPromoterWeights();
+  cerr << "Promoter Weights..." << endl;
+  for (int i = 0; i < w.GetSize(); i++) {
+    cerr << i << " " << w[i] << endl;
+  }
+  */
+}
+
+// Adjust the weight at promoter positions that match the downstream nop pattern
+bool cHardwareCPU::RegulatePromoterNop(cAvidaContext& ctx, bool up)
+{
+  static cInstruction promoter_inst = GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
+
+  // Look for the label directly (no complement)
+  // Save the position before the label, so we don't count it as a regulatory site
+  int start_pos = IP().GetPosition(); 
+  ReadLabel();
+  
+  // Don't allow zero-length label matches. These are too powerful.
+  if (GetLabel().GetSize() == 0) return true;
+ 
+  cHeadCPU search_head(IP());
+  do {
+    search_head++;
+    cHeadCPU match_head(search_head);
+
+    // See whether a matching label is here
+    int i;
+    for (i=0; i < GetLabel().GetSize(); i++)
+    {
+      match_head++;
+      if ( !m_inst_set->IsNop(match_head.GetInst() ) 
+        || (GetLabel()[i] != m_inst_set->GetNopMod( match_head.GetInst())) ) break;
+    }
+  
+    // Matching label found
+    if (i == GetLabel().GetSize())
+    {
+      cHeadCPU change_head(match_head);
+      for (int j=0; j < 5; j++)
+      {
+        change_head++;
+        if (change_head.GetInst() == promoter_inst) {
+         
+          
+          if (change_head.GetPosition() < organism->GetPhenotype().GetCurPromoterWeights().GetSize())
+          {
+            organism->GetPhenotype().RegulatePromoter(change_head.GetPosition(), up);
+          }
+          /*
+          else
+          {
+            // I can't seem to get resizing promoter arrays on allocate to work
+            // promoter weights still get unsynched from the genome size somewhere.
+            cout << change_head.GetPosition() << endl;
+            cout << organism->GetPhenotype().GetCurPromoterWeights().GetSize() << endl;
+            cout << GetMemory().GetSize() << endl;
+            cout << GetMemory().AsString() << endl;
+          }
+          */
+        }
+      }
+    }
+  } while ( start_pos != search_head.GetPosition() );
+  
+  // Debugging code
+  /*
+  tArray<double> w = organism->GetPhenotype().GetPromoterWeights();
+  cerr << "Promoter Weights..." << endl;
+  for (int i = 0; i < w.GetSize(); i++) {
+    cerr << i << " " << w[i] << endl;
+  }
+  */
+}
+
+
+// Move execution to a new promoter
+bool cHardwareCPU::Inst_Terminate(cAvidaContext& ctx)
+{
+  // Reset the CPU, clearing everything except R/W head positions.
+  const int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
+  const int read_head_pos = GetHead(nHardware::HEAD_READ).GetPosition();
+  m_threads[m_cur_thread].Reset(this, m_threads[m_cur_thread].GetID());
+  GetHead(nHardware::HEAD_WRITE).Set(write_head_pos);
+  GetHead(nHardware::HEAD_READ).Set(read_head_pos);
+
+  // We want to execute the promoter that we land on.
+  m_advance_ip = false;
+  
+  //organism->ClearInput();
+  
+  // Get the promoter weight list
+  double total_weight = 0;
+  tArray<double> w = organism->GetPhenotype().GetCurPromoterWeights();
+  for (int i = 0; i < w.GetSize(); i++) {
+    total_weight += w[i];
+  }
+ 
+   
+  // If there is no weight (for example if there are no promoters)
+  // then randomly choose a starting position
+  if (total_weight==0)
+  {
+    // Or we could kill the organism...
+    //organism->Die();
+    //return true;
+    
+    int i = m_world->GetRandom().GetInt(w.GetSize());
+    IP().Set(i);
+    return true;
+  }
+  
+  // Add together all of the promoter weights
+  double promoter_choice = (double) m_world->GetRandom().GetDouble(total_weight);
+  double test_total = 0;
+  for (int i = 0; i < w.GetSize(); i++) {
+    test_total += w[i];
+    if (promoter_choice < test_total) {
+      IP().Set(i);
+      break;
+    }
+  }  
+  return true;
+}
+
+bool cHardwareCPU::Inst_Promoter(cAvidaContext& ctx)
+{
+  // Promoters don't do anything themselves
+  return true;
+}
+
+
+bool cHardwareCPU::Inst_DecayRegulation(cAvidaContext& ctx)
+{
+  organism->GetPhenotype().DecayAllPromoterRegulation();
+  return true;
+}
+
 //// Placebo insts ////
 bool cHardwareCPU::Inst_Skip(cAvidaContext& ctx)
 {

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/cpu/cHardwareCPU.h	2007-04-02 17:32:12 UTC (rev 1450)
@@ -392,6 +392,7 @@
   bool Inst_CAlloc(cAvidaContext& ctx);
   bool Inst_CDivide(cAvidaContext& ctx);
   bool Inst_MaxAlloc(cAvidaContext& ctx);
+  bool Inst_MaxAllocMoveWriteHead(cAvidaContext& ctx);
   bool Inst_Inject(cAvidaContext& ctx);
   bool Inst_InjectRand(cAvidaContext& ctx);
   bool Inst_InjectThread(cAvidaContext& ctx);
@@ -510,6 +511,20 @@
   bool Inst_HeadDivide0_01(cAvidaContext& ctx);
   bool Inst_HeadDivide0_001(cAvidaContext& ctx);
 
+  //// Promoter Model ////
+  bool GetPromoterPattern(tArray<int>& promoter);
+  bool RegulatePromoter(cAvidaContext& ctx, bool up);
+  bool Inst_UpRegulatePromoter(cAvidaContext& ctx) { RegulatePromoter(ctx, true); }
+  bool Inst_DownRegulatePromoter(cAvidaContext& ctx) { RegulatePromoter(ctx, false); }
+  bool RegulatePromoterNop(cAvidaContext& ctx, bool up);
+  bool Inst_UpRegulatePromoterNop(cAvidaContext& ctx) { RegulatePromoterNop(ctx, true); }
+  bool Inst_DownRegulatePromoterNop(cAvidaContext& ctx) { RegulatePromoterNop(ctx, false); }  
+  bool Inst_UpRegulatePromoterNopDecay(cAvidaContext& ctx);
+  bool Inst_DownRegulatePromoterNopDecay(cAvidaContext& ctx);
+  bool Inst_Terminate(cAvidaContext& ctx);
+  bool Inst_Promoter(cAvidaContext& ctx);
+  bool Inst_DecayRegulation(cAvidaContext& ctx);
+  
   //// Placebo ////
   bool Inst_Skip(cAvidaContext& ctx);
 };

Modified: development/source/cpu/cTestCPU.cc
===================================================================
--- development/source/cpu/cTestCPU.cc	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/cpu/cTestCPU.cc	2007-04-02 17:32:12 UTC (rev 1450)
@@ -342,7 +342,7 @@
   test_info.org_array[cur_depth] = new cOrganism(m_world, ctx, genome);
   cOrganism & organism = *( test_info.org_array[cur_depth] );
   organism.SetOrgInterface(new cTestCPUInterface(this));
-  organism.GetPhenotype().SetupInject(genome.GetSize());
+  organism.GetPhenotype().SetupInject(genome);
 
   // Run the current organism.
   ProcessGestation(ctx, test_info, cur_depth);

Modified: development/source/cpu/cTestCPUInterface.cc
===================================================================
--- development/source/cpu/cTestCPUInterface.cc	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/cpu/cTestCPUInterface.cc	2007-04-02 17:32:12 UTC (rev 1450)
@@ -31,7 +31,7 @@
 
 bool cTestCPUInterface::Divide(cAvidaContext& ctx, cOrganism* parent, cGenome& child_genome)
 {
-  parent->GetPhenotype().TestDivideReset(parent->GetGenome().GetSize());
+  parent->GetPhenotype().TestDivideReset(parent->GetGenome());
   // @CAO in the future, we probably want to pass this child the test_cpu!
   return true;
 }

Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/main/cAvidaConfig.h	2007-04-02 17:32:12 UTC (rev 1450)
@@ -208,7 +208,7 @@
   CONFIG_ADD_VAR(START_CREATURE, cString, "default-classic.org", "Organism to seed the soup");
   
   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");
+  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");
   CONFIG_ADD_VAR(PREFER_EMPTY, int, 1, "Give empty cells preference in offsping placement?");
   CONFIG_ADD_VAR(ALLOW_PARENT, int, 1, "Allow births to replace the parent organism?");
   CONFIG_ADD_VAR(DEATH_METHOD, int, 2, "0 = Never die of old age.\n1 = Die when inst executed = AGE_LIMIT (+deviation)\n2 = Die when inst executed = length*AGE_LIMIT (+dev)");
@@ -284,6 +284,13 @@
   CONFIG_ADD_VAR(MAX_DONATE_EDIT_DIST, int, -1, "Limit on edit distance for donate; -1=no max");
   CONFIG_ADD_VAR(MAX_DONATES, int, 1000000, "Limit on number of donates organisms are allowed.");
   
+  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.");
+  CONFIG_ADD_VAR(PROMOTER_PROCESSIVITY, double, 1.0, "Chance of not terminating before executing each instruction.");
+  CONFIG_ADD_VAR(PROMOTER_BG_STRENGTH, double, 0, "Probability of positions that are not promoter\ninstructions initiating execution (promoters are 1).");
+  CONFIG_ADD_VAR(REGULATION_STRENGTH, double, 1, "Strength added or subtracted to a promoter by regulation.");
+  CONFIG_ADD_VAR(REGULATION_DECAY_FRAC, double, 0.1, "Fraction of regulation that decays away. \n(Max regulation = REGULATION_STRENGTH / REGULATION_DECAY_FRAC)");
+
   CONFIG_ADD_GROUP(GENEOLOGY_GROUP, "Geneology");
   CONFIG_ADD_VAR(TRACK_MAIN_LINEAGE, int, 1, "Keep all ancestors of the active population?\n0=no, 1=yes, 2=yes,w/sexual population");
   CONFIG_ADD_VAR(THRESHOLD, int, 3, "Number of organisms in a genotype needed for it\n  to be considered viable.");

Modified: development/source/main/cOrganism.cc
===================================================================
--- development/source/main/cOrganism.cc	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/main/cOrganism.cc	2007-04-02 17:32:12 UTC (rev 1450)
@@ -455,7 +455,6 @@
   for (int i = 0; i < m_output_buf.GetNumStored(); i++) fp << " 0x" << setw(8) << m_output_buf[i];
   fp << endl;
   
-  
   fp << setfill(' ') << setbase(10);
     
   fp << "---------------------------" << endl;

Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/main/cPhenotype.cc	2007-04-02 17:32:12 UTC (rev 1450)
@@ -104,13 +104,15 @@
  **/
 
 void cPhenotype::SetupOffspring(const cPhenotype & parent_phenotype,
-				int _length)
+				const cGenome & _genome)
 {
   // Copy divide values from parent, which should already be setup.
   merit           = parent_phenotype.merit;
-  genome_length   = _length;
+  genome_length   = _genome.GetSize();
   copied_size     = parent_phenotype.child_copied_size;
   executed_size   = parent_phenotype.executed_size;
+  assert (executed_size > 0);
+  
   gestation_time  = parent_phenotype.gestation_time;
   gestation_start = 0;
   fitness         = parent_phenotype.fitness;
@@ -135,7 +137,8 @@
   cur_sense_count.SetAll(0);  
   for (int j = 0; j < sensed_resources.GetSize(); j++)
 	      sensed_resources[j] =  parent_phenotype.sensed_resources[j];
-
+  SetupPromoterWeights(_genome, true);
+  
   // Copy last values from parent
   last_merit_base           = parent_phenotype.last_merit_base;
   last_bonus                = parent_phenotype.last_bonus;
@@ -199,13 +202,13 @@
  *     - This is the first method run on an otherwise freshly built phenotype.
  **/
 
-void cPhenotype::SetupInject(int _length)
+void cPhenotype::SetupInject(const cGenome & _genome)
 {
   // Setup reasonable initial values injected organism...
-  merit           = _length;
-  genome_length   = _length;
-  copied_size     = _length;
-  executed_size   = _length;
+  genome_length   = _genome.GetSize();
+  merit           = genome_length;
+  copied_size     = genome_length;
+  executed_size   = genome_length;
   gestation_time  = 0;
   gestation_start = 0;
   fitness         = 0;
@@ -223,9 +226,10 @@
   cur_inst_count.SetAll(0);
   sensed_resources.SetAll(0);
   cur_sense_count.SetAll(0);
-
+  SetupPromoterWeights(_genome, true);
+  
   // Copy last values from parent
-  last_merit_base = _length;
+  last_merit_base = genome_length;
   last_bonus      = 1;
   last_num_errors = 0;
   last_num_donates = 0;
@@ -279,7 +283,7 @@
  * This function is run whenever an organism executes a successful divide.
  **/
 
-void cPhenotype::DivideReset(int _length)
+void cPhenotype::DivideReset(const cGenome & _genome)
 {
   assert(time_used > 0);
   assert(initialized == true);
@@ -297,7 +301,7 @@
     merit = cur_merit_base * cur_bonus;
   }
   
-  genome_length   = _length;
+  genome_length   = _genome.GetSize();
   (void) copied_size;          // Unchanged
   (void) executed_size;        // Unchanged
   gestation_time  = time_used - gestation_start;
@@ -368,6 +372,7 @@
     cpu_cycles_used = 0;
     time_used = 0;
     neutral_metric += m_world->GetRandom().GetRandNormal();
+    SetupPromoterWeights(_genome, true);
   }
 
   if (m_world->GetConfig().GENERATION_INC_METHOD.Get() == GENERATION_INC_BOTH) generation++;
@@ -386,7 +391,7 @@
  * and copied size in its merit.
  **/
 
-void cPhenotype::TestDivideReset(int _length)
+void cPhenotype::TestDivideReset(const cGenome & _genome)
 {
   assert(time_used > 0);
   assert(initialized == true);
@@ -395,7 +400,7 @@
   int cur_merit_base = CalcSizeMerit();
   merit           = cur_merit_base * cur_bonus;
 
-  genome_length   = _length;
+  genome_length   = _genome.GetSize();
   (void) copied_size;                            // Unchanged
   (void) executed_size;                          // Unchanged
   gestation_time  = time_used - gestation_start;
@@ -427,7 +432,8 @@
   cur_inst_count.SetAll(0);
   cur_sense_count.SetAll(0); 
   sensed_resources.SetAll(-1.0);
-
+  SetupPromoterWeights(_genome, true);
+  
   // Setup other miscellaneous values...
   num_divides++;
   generation++;
@@ -484,6 +490,10 @@
   gestation_start = 0;
   fitness         = clone_phenotype.fitness;
   div_type        = clone_phenotype.div_type;
+  cur_promoter_weights = clone_phenotype.cur_promoter_weights; // @JEB Not correct if clone is not of fresh phenotype 
+  base_promoter_weights = clone_phenotype.base_promoter_weights; // @JEB Not correct if clone is not of fresh phenotype 
+  promoter_repression = clone_phenotype.promoter_repression; // @JEB Not correct if clone is not of fresh phenotype 
+  promoter_activation = clone_phenotype.promoter_activation; // @JEB Not correct if clone is not of fresh phenotype 
 
   assert(genome_length > 0);
   assert(copied_size > 0);
@@ -503,8 +513,8 @@
   cur_sense_count.SetAll(0);  
   for (int j = 0; j < sensed_resources.GetSize(); j++)
 	      sensed_resources[j] =  clone_phenotype.sensed_resources[j];
+  //SetupPromoterWeights(_genome); Do we reset here?
 
-
   // Copy last values from parent
   last_merit_base          = clone_phenotype.last_merit_base;
   last_bonus               = clone_phenotype.last_bonus;
@@ -794,6 +804,17 @@
   for (int i = 0; i < cur_task_count.GetSize(); i++)
     fp << " " << cur_task_count[i] << " (" << cur_task_quality[i] << ")";
   fp << endl;
+  
+  if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1)
+  {
+    fp << "Promoters:     ";
+    for (int i=0; i<cur_promoter_weights.GetSize(); i++)
+    {
+      if (cur_promoter_weights[i] != m_world->GetConfig().PROMOTER_BG_STRENGTH.Get()) fp << i << " (" << cur_promoter_weights[i] << ") ";
+    }
+    fp << endl;
+  }
+
 }
 
 int cPhenotype::CalcSizeMerit() const
@@ -832,4 +853,61 @@
   }
 
   return out_size;
+} 
+
+void cPhenotype::SetupPromoterWeights(const cGenome & _genome, const bool clear)
+{
+  if (!m_world->GetConfig().PROMOTERS_ENABLED.Get()) return;
+
+  // Ideally, this wouldn't be hard-coded
+  static cInstruction promoter_inst = m_world->GetHardwareManager().GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
+
+  int old_size = base_promoter_weights.GetSize();
+  cur_promoter_weights.Resize(_genome.GetSize());
+  base_promoter_weights.Resize(_genome.GetSize());
+  promoter_repression.Resize(_genome.GetSize());
+  promoter_activation.Resize(_genome.GetSize());
+
+  // Only change new regions of the genome (that might have been allocated since this was last called)
+  for ( int i = (clear ? 0 : old_size); i<_genome.GetSize(); i++)
+  {
+    base_promoter_weights[i] = 1;
+    promoter_repression[i] = 1;
+    promoter_activation[i] = 1;
+
+    // Now change the weights at instructions that are not promoters if called for
+    if ( _genome[i] != promoter_inst)
+    {
+      base_promoter_weights[i] *= m_world->GetConfig().PROMOTER_BG_STRENGTH.Get(); 
+    }
+    cur_promoter_weights[i] = base_promoter_weights[i];
+  }
 }
+
+void cPhenotype::DecayAllPromoterRegulation()
+{
+  for ( int i=0; i<cur_promoter_weights.GetSize(); i++)
+  {
+    promoter_activation[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
+    promoter_repression[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
+    cur_promoter_weights[i] = base_promoter_weights[i] * promoter_activation[i] / promoter_repression[i];
+  }
+}
+
+void cPhenotype::RegulatePromoter(const int i, const bool up )
+{
+  // Make sure we were initialized
+  assert ( (promoter_activation.GetSize() > 0) && (promoter_activation.GetSize() > 0) );
+  
+  if (up) {
+    promoter_activation[i] += m_world->GetConfig().REGULATION_STRENGTH.Get(); 
+    promoter_activation[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
+  }
+  else {
+    promoter_repression[i] += m_world->GetConfig().REGULATION_STRENGTH.Get(); 
+    promoter_repression[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
+  }
+  
+ cur_promoter_weights[i] = base_promoter_weights[i] * promoter_activation[i] / promoter_repression[i];
+}
+

Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/main/cPhenotype.h	2007-04-02 17:32:12 UTC (rev 1450)
@@ -28,6 +28,9 @@
 
 #include <fstream>
 
+#ifndef cGenome_h
+#include "cGenome.h"
+#endif
 #ifndef cMerit_h
 #include "cMerit.h"
 #endif
@@ -97,19 +100,25 @@
   double div_type;          // Type of the divide command used
 
   // 2. These are "in progress" variables, updated as the organism operates
-  double cur_bonus;               // Current Bonus
-  int cur_num_errors;             // Total instructions executed illeagally.
-  int cur_num_donates;            // Number of donations so far
-  tArray<int> cur_task_count;     // Total times each task was performed
-  tArray<int> eff_task_count;     // Total times each task was performed (resetable during the life of the organism)
-  tArray<double> cur_task_quality;	  // Average (total?) quality with which each task was performed
-  tArray<int> cur_reaction_count; // Total times each reaction was triggered.  
-  tArray<double> cur_reaction_add_reward; // Bonus change from triggering each reaction.
-  tArray<int> cur_inst_count;	    // Intsruction exection counter
-  tArray<int> cur_sense_count;     // Total times resource combinations have been sensed; @JEB 
-  tArray<double> sensed_resources; // Resources of which the organism is explictly aware
-  tArray<cCodeLabel> active_transposons; // Transposons that are active
+  double cur_bonus;                           // Current Bonus
+  int cur_num_errors;                         // Total instructions executed illeagally.
+  int cur_num_donates;                        // Number of donations so far
+  tArray<int> cur_task_count;                 // Total times each task was performed
+  tArray<int> eff_task_count;                 // Total times each task was performed (resetable during the life of the organism)
+  tArray<double> cur_task_quality;            // Average (total?) quality with which each task was performed
+  tArray<int> cur_reaction_count;             // Total times each reaction was triggered.  
+  tArray<double> cur_reaction_add_reward;     // Bonus change from triggering each reaction.
+  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<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 
+  tArray<double> promoter_activation;         // Amount of positive regulation in play at each site; @JEB 
+  tArray<double> promoter_repression;         // Amount of negative regulation in play at each site; @JEB 
+  
   tHashTable<void*, cTaskState*> m_task_states;
+
   
   // 3. These mark the status of "in progess" variables at the last divide.
   double last_merit_base;         // Either constant or based on genome length.
@@ -132,7 +141,7 @@
   int age;               // Number of updates organism has survived for.
   cString fault_desc;    // A description of the most recent error.
   double neutral_metric; // Undergoes drift (gausian 0,1) per generation
-  double life_fitness; 	 // Organism fitness during it's lifetime, 
+  double life_fitness; 	 // Organism fitness during its lifetime, 
 		         // calculated based on merit just before the divide
 
   // 5. Status Flags...  (updated at each divide)
@@ -173,16 +182,16 @@
   bool OK();
 
   // Run when being setup *as* and offspring.
-  void SetupOffspring(const cPhenotype & parent_phenotype, int _length);
+  void SetupOffspring(const cPhenotype & parent_phenotype, const cGenome & _genome);
 
   // Run when being setup as an injected organism.
-  void SetupInject(int _length);
+  void SetupInject(const cGenome & _genome);
 
   // Run when this organism successfully executes a divide.
-  void DivideReset(int _length);
+  void DivideReset(const cGenome & _genome);
   
   // Same as DivideReset(), but only run in test CPUs.
-  void TestDivideReset(int _length);
+  void TestDivideReset(const cGenome & _genome);
 
   // Run when an organism is being forced to replicate, but not at the end
   // of its replication cycle.  Assume exact clone with no mutations.
@@ -231,6 +240,7 @@
   const tArray<int>& GetCurSenseCount() const { assert(initialized == true); return cur_sense_count; }
   double GetSensedResource(int _in) { assert(initialized == true); return sensed_resources[_in]; }
   const tArray<cCodeLabel>& GetActiveTransposons() { assert(initialized == true); return active_transposons; }
+  const tArray<double>& GetCurPromoterWeights() { assert(initialized == true); return cur_promoter_weights; }
 
   double GetLastMeritBase() const { assert(initialized == true); return last_merit_base; }
   double GetLastBonus() const { assert(initialized == true); return last_bonus; }
@@ -283,7 +293,7 @@
   void SetFault(const cString& in_fault) { fault_desc = in_fault; }
   void SetNeutralMetric(double _in){ neutral_metric = _in; }
   void SetLifeFitness(double _in){ life_fitness = _in; }
-  void SetLinesExecuted(int _exe_size) { executed_size = _exe_size; }
+  void SetLinesExecuted(int _exe_size) { executed_size = _exe_size;   assert(executed_size > 0); }
   void SetLinesCopied(int _copied_size) { child_copied_size = _copied_size; }
   void SetDivType(double _div_type) { div_type = _div_type; }  
   void SetDivideSex(bool _divide_sex) { divide_sex = _divide_sex; }  
@@ -301,7 +311,10 @@
   void DecCurInstCount(int _inst_num)  { assert(initialized == true); cur_inst_count[_inst_num]--; } 
   
   void ActivateTransposon(cCodeLabel & in_label) { assert(initialized == true); active_transposons.Push(in_label); }
-
+  void SetupPromoterWeights(const cGenome & _genome, const bool clear = false);
+  void DecayAllPromoterRegulation();
+  void RegulatePromoter(const int i, const bool up );
+  
   void IncAge()      { assert(initialized == true); age++; }
   void IncCPUCyclesUsed() { assert(initialized == true); cpu_cycles_used++; }
   void IncTimeUsed(int i=1) { assert(initialized == true); time_used+=i; }

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/source/main/cPopulation.cc	2007-04-02 17:32:12 UTC (rev 1450)
@@ -33,6 +33,7 @@
 #include "cDataFile.h"
 #include "cEnvironment.h"
 #include "functions.h"
+#include "cGenome.h"
 #include "cGenomeUtil.h"
 #include "cGenotype.h"
 #include "cHardwareBase.h"
@@ -291,10 +292,10 @@
   tArray<cMerit> merit_array;
   
   // Update the parent's phenotype.
-  // This needs to be done before the parent goes into the brith chamber
+  // This needs to be done before the parent goes into the birth chamber
   // or the merit doesn't get passed onto the child correctly
   cPhenotype& parent_phenotype = parent_organism.GetPhenotype();
-  parent_phenotype.DivideReset(parent_organism.GetGenome().GetSize());
+  parent_phenotype.DivideReset(parent_organism.GetGenome());
   
   birth_chamber.SubmitOffspring(ctx, child_genome, parent_organism, child_array, merit_array);
   
@@ -328,8 +329,8 @@
     }
     
     // Update the phenotypes of each child....
-    const int child_length = child_array[i]->GetGenome().GetSize();
-    child_array[i]->GetPhenotype().SetupOffspring(parent_phenotype,child_length);
+    const cGenome & child_genome = child_array[i]->GetGenome();
+    child_array[i]->GetPhenotype().SetupOffspring(parent_phenotype,child_genome);
     
     child_array[i]->GetPhenotype().SetMerit(merit_array[i]);
     
@@ -2211,7 +2212,7 @@
   
   // Setup the phenotype...
   cPhenotype & phenotype = new_organism->GetPhenotype();
-  phenotype.SetupInject(new_genotype->GetLength());
+  phenotype.SetupInject(new_genotype->GetGenome());
   phenotype.SetMerit( cMerit(new_genotype->GetTestMerit(ctx)) );
   
   // @CAO are these really needed?

Modified: development/support/config/avida.cfg
===================================================================
--- development/support/config/avida.cfg	2007-04-02 17:01:48 UTC (rev 1449)
+++ development/support/config/avida.cfg	2007-04-02 17:32:12 UTC (rev 1450)
@@ -17,7 +17,7 @@
 ### ARCH_GROUP ###
 # Architecture Variables
 WORLD_X 60        # Width of the Avida world
-WORLD_Y 60       # Height of the Avida world
+WORLD_Y 60        # Height of the Avida world
 WORLD_GEOMETRY 2  # 1 = Bounded Grid
                   # 2 = Torus
 NUM_DEMES 0       # Number of independed groups in the population; 0=off
@@ -47,7 +47,10 @@
                          # 6 = Random within deme
                          # 7 = Organism faced by parent
                          # 8 = Next grid cell (id+1)
+                         # 9 = Largest energy used in entire population
+                         # 10 = Largest energy used in neighborhood
 PREFER_EMPTY 1           # Give empty cells preference in offsping placement?
+ALLOW_PARENT 1           # Allow births to replace the parent organism?
 DEATH_METHOD 2           # 0 = Never die of old age.
                          # 1 = Die when inst executed = AGE_LIMIT (+deviation)
                          # 2 = Die when inst executed = length*AGE_LIMIT (+dev)
@@ -106,6 +109,10 @@
 INJECT_INS_PROB 0.0   # Insertion rate (per site, applied on inject)
 INJECT_DEL_PROB 0.0   # Deletion rate (per site, applied on inject)
 INJECT_MUT_PROB 0.0   # Mutation rate (per site, applied on inject)
+META_COPY_MUT 0.0     # Prob. of copy mutation rate changing (per gen)
+META_STD_DEV 0.0      # Standard deviation of meta mutation size.
+MUT_RATE_SOURCE 1     # 1 = Mutation rates determined by environment.
+                      # 2 = Mutation rates inherited from parent.
 
 ### REVERSION_GROUP ###
 # Mutation Reversion
@@ -151,6 +158,17 @@
 MAX_DONATE_EDIT_DIST -1  # Limit on edit distance for donate; -1=no max
 MAX_DONATES 1000000      # Limit on number of donates organisms are allowed.
 
+### PROMOTER_GROUP ###
+# Promoters
+PROMOTERS_ENABLED 0        # Use the promoter/terminator execution scheme.
+                           # Certain instructions must also be included.
+PROMOTER_PROCESSIVITY 1.0  # Chance of not terminating before executing each instruction.
+PROMOTER_BG_STRENGTH 0     # Probability of positions that are not promoter
+                           # instructions initiating execution (promoters are 1).
+REGULATION_STRENGTH 1      # Strength added or subtracted to a promoter by regulation.
+REGULATION_DECAY_FRAC 0.1  # Fraction of regulation that decays away. 
+                           # (Max regulation = REGULATION_STRENGTH / REGULATION_DECAY_FRAC)
+
 ### GENEOLOGY_GROUP ###
 # Geneology
 TRACK_MAIN_LINEAGE 1  # Keep all ancestors of the active population?




More information about the Avida-cvs mailing list