[Avida-SVN] r2069 - in branches/energy: . documentation/notes source/actions source/analyze source/classification source/cpu source/main source/script source/tools

beckma24 at myxo.css.msu.edu beckma24 at myxo.css.msu.edu
Fri Sep 7 11:02:28 PDT 2007


Author: beckma24
Date: 2007-09-07 14:02:28 -0400 (Fri, 07 Sep 2007)
New Revision: 2069

Added:
   branches/energy/source/analyze/cAnalyzeGenotypeTreeStats.cc
   branches/energy/source/analyze/cAnalyzeGenotypeTreeStats.h
Modified:
   branches/energy/CMakeLists.txt
   branches/energy/documentation/notes/release-milestones.txt
   branches/energy/source/actions/PopulationActions.cc
   branches/energy/source/actions/PrintActions.cc
   branches/energy/source/analyze/cAnalyze.cc
   branches/energy/source/analyze/cAnalyze.h
   branches/energy/source/analyze/cAnalyzeGenotype.cc
   branches/energy/source/classification/cGenotypeControl.cc
   branches/energy/source/cpu/cHardwareCPU.cc
   branches/energy/source/cpu/cHardwareCPU.h
   branches/energy/source/cpu/cHardwareGX.cc
   branches/energy/source/cpu/cTestCPU.cc
   branches/energy/source/main/cAvidaConfig.h
   branches/energy/source/main/cMutationRates.cc
   branches/energy/source/main/cMutationRates.h
   branches/energy/source/main/cOrganism.cc
   branches/energy/source/main/cOrganism.h
   branches/energy/source/main/cPlasticPhenotype.cc
   branches/energy/source/main/cPlasticPhenotype.h
   branches/energy/source/main/cPopulation.cc
   branches/energy/source/main/cPopulationCell.cc
   branches/energy/source/main/cPopulationCell.h
   branches/energy/source/main/cTaskLib.cc
   branches/energy/source/script/ASTree.h
   branches/energy/source/script/cASTDumpVisitor.cc
   branches/energy/source/script/cParser.cc
   branches/energy/source/tools/cMerit.cc
   branches/energy/source/tools/cMerit.h
Log:
Merged development branch

Modified: branches/energy/CMakeLists.txt
===================================================================
--- branches/energy/CMakeLists.txt	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/CMakeLists.txt	2007-09-07 18:02:28 UTC (rev 2069)
@@ -112,6 +112,7 @@
 SET(ANALYZE_SOURCES
   ${ANALYZE_DIR}/cAnalyze.cc
   ${ANALYZE_DIR}/cAnalyzeGenotype.cc
+  ${ANALYZE_DIR}/cAnalyzeGenotypeTreeStats.cc
   ${ANALYZE_DIR}/cAnalyzeJobQueue.cc
   ${ANALYZE_DIR}/cAnalyzeJobWorker.cc
   ${ANALYZE_DIR}/cMutationalNeighborhood.cc

Modified: branches/energy/documentation/notes/release-milestones.txt
===================================================================
--- branches/energy/documentation/notes/release-milestones.txt	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/documentation/notes/release-milestones.txt	2007-09-07 18:02:28 UTC (rev 2069)
@@ -8,101 +8,60 @@
 
 
 Visualized development/support timeline (* current):
---2.0--
-     --2.1--
-            --2.2----
-              --2.3--
-                     --2.4-------------
-                       --2.5--
-                              --2.6-------------
-                                --2.7*-
-                                       --2.8----------------------
-                                         --2.9--
-                                                --3.0-------------
-+ end of planned timeline, begin future releases +                                                
-                                                  --3.1--
-                                                         --3.2-----------
-                                                           --3.3--
-                                                                  --3.4-----------
-                                                                    --3.5--
-                                                                           --3.6--
+--2.6----
+  --2.7--
+         *-2.8----
+           --2.9--
+                  --3.0----
+                    --3.1--
+                           --3.2----
+                             --3.3--
+                                    --3.4----
+                                      --3.5--
+                                             --3.6----
+                                               --3.7--
+                                                      --3.8----
+                                                        --3.9--
+                                                               --4.0----
 
 
-Version 2.0 - stable      - Status: End of Life
-Version 2.1 - development - Status: Completed
-Version 2.2 - stable      - Status: End of Life
-Version 2.3 - development - Status: Completed
-Version 2.4 - stable      - Status: End of Life
-Version 2.5 - development - Status: Completed
+Version 2.6 - stable      - Status: End of Life
+Version 2.7 - development - Status: Wrapping Up
+Version 2.8 - stable      - Status: Pre-release preparation
 
+Version 2.9 - development - Target: August 2008    - Status: Soon
 
-Version 2.6 - stable      - Target: < Mid 2007     - Status: Active Maintenance
+David:
+- Completed AvidaScript
+  - Merged 'avida' and 'avida-s' functionality
+- Cleanup Landscaping tools
++ Error reporting, input validation
 
-Currently at 2.6.0
-
-
-Version 2.7 - development - Target: July 2007      - Status: Active Development
-
-Dave B:
-+ Consistency test support
-  * simplify development
-  * automatic expected results
-  * performance tests
-  - documentation
-+ Consistency test coverage
-  + mid-run (* classic, * transsmt)
-  + analyze mode
-+ Transition all applicable output files to cDataFile objects, as opposed to raw ostream
-+ AvidaScript
-  + lexer
-  + parser
-  - threaded driver, multiple executing worlds via 'avida-s'
-+ Cleanup Landscaping tools
-
-Ben:
-+ Energy model
-
 Dave K:
 - Topology manager
   + environment named regions
-? Group/Deme Framework
 
-Ofria:
-- Core GUI framework
+Charles:
+- Completed Viewers based on Core Viewer/GUI frameworks
 
-Art:
-+ his damn research
+Bess:
++ Consistency test coverage
 
-All:
-- Update documentation
-- Code release cleanup
-
-
-
-Version 2.8 - stable      - Target: < Mid 2008     - Status: Planned, pending version 2.7 completion
-
-- Stable maintenance
-
-
-Version 2.9 - development - Target: July 2008      - Status: Planned
-
-- Completed AS language support
-- Remove Analyze Mode
-- Merged 'avida' and 'avida-s' functionality
+Unassigned:
 - New Mutation framework
-- Basic OS X native GUI
-- Update documentation
-- Error reporting, input validation
 - Schedulable object framework (organism threads scheduled rather than organisms, events, etc.) 
 - Serialization
+
+All:
+- Update documentation
 - Code release cleanup
 
+
 **** NOTE: Backwards compatibility breaks at this point ****
 
 
 Version 3.0 - stable      - Target: Ongoing        - Status: Planned, pending version 2.9 completion
 
-- Stable maintenance
-
-
 Version 3.1 - development - Target: tbd            - Status: feature set tdb
+
+- Basic OS X native GUI

Modified: branches/energy/source/actions/PopulationActions.cc
===================================================================
--- branches/energy/source/actions/PopulationActions.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/actions/PopulationActions.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -810,7 +810,6 @@
     }
 
     switch (m_mut_type) {
-      case POINT: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetPointMutProb(m_prob); break;
       case COPY: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetCopyMutProb(m_prob); break;
       case INS: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInsMutProb(m_prob); break;
       case DEL: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetDelMutProb(m_prob); break;
@@ -918,7 +917,6 @@
     }
     
     switch (m_mut_type) {
-      case POINT: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetPointMutProb(prob); break;
       case COPY: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetCopyMutProb(prob); break;
       case INS: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInsMutProb(prob); break;
       case DEL: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetDelMutProb(prob); break;

Modified: branches/energy/source/actions/PrintActions.cc
===================================================================
--- branches/energy/source/actions/PrintActions.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/actions/PrintActions.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -1393,7 +1393,7 @@
 			if (ctx.GetAnalyzeMode()) //We're in analyze mode, so process the current batch
 			{
 				cAnalyze& analyze = m_world->GetAnalyze();  
-				if (!analyze.GetCurrentBatch().IsAligned()) analyze.CommandAlign(""); //Let analyze take charge of aligning this batch
+				if (!analyze.GetCurrentBatch().IsAligned()) analyze.AlignCurrentBatch(); //Let analyze take charge of aligning this batch
 				tListIterator<cAnalyzeGenotype> batch_it(m_world->GetAnalyze().GetCurrentBatch().List());
 				cAnalyzeGenotype* genotype = NULL;
 				while((genotype = batch_it.Next()))
@@ -1515,6 +1515,8 @@
           << "# gestation time" << endl;
       for (int k = 0; k < m_world->GetEnvironment().GetNumTasks(); k++)
         fot << "# task." << k << endl;
+      for (int k = 0; k < m_world->GetEnvironment().GetInputSize(); k++)
+        fot << "# env_input." << k << endl;
       fot << endl;
     }
     
@@ -1533,7 +1535,11 @@
         tArray<int> tasks = pp->GetLastTaskCount();
         for (int t = 0; t < tasks.GetSize(); t++)
           fot << tasks[t] << " ";
+        tArray<int> env_inputs = pp->GetEnvInputs();
+        for (int e = 0; e < env_inputs.GetSize(); e++)
+          fot << env_inputs[e] << " ";
         fot << endl;
+        
       }
     }
     

Modified: branches/energy/source/analyze/cAnalyze.cc
===================================================================
--- branches/energy/source/analyze/cAnalyze.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/analyze/cAnalyze.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -40,6 +40,7 @@
 #include "cAnalyzeFlowCommandDef.h"
 #include "cAnalyzeFunction.h"
 #include "cAnalyzeGenotype.h"
+#include "cAnalyzeGenotypeTreeStats.h"
 #include "tAnalyzeJob.h"
 #include "cAvidaContext.h"
 #include "cDataFile.h"
@@ -3220,97 +3221,113 @@
   // Load in the variables...
   cString filename("tree_stats.dat");
   if (cur_string.GetSize() != 0) filename = cur_string.PopWord();
+
+  ofstream& fp = m_world->GetDataFileOFStream(filename);
+
+  fp << "# Legend:" << endl;
+  fp << "# 1: Average cumulative stemminess" << endl;
+  fp << endl;
   
-  
-  cAnalyzeGenotype * genotype = NULL;
-  tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
-  const int num_gens = batch[cur_batch].List().GetSize();
-  
-  // Put all of the genotypes in an array for easy reference and collect
-  // other information on them as we process them.
-  tArray<cAnalyzeGenotype *> gen_array(num_gens);
-  tHashTable<int, int> id_hash;  // Store array pos for each id.
-  tArray<int> id_array(num_gens), pid_array(num_gens);
-  tArray<int> depth_array(num_gens), birth_array(num_gens);
-  int array_pos = 0;
-  while ((genotype = batch_it.Next()) != NULL) {
-    // Put the genotype in an array.
-    gen_array[array_pos] = genotype;
-    id_hash.Add(genotype->GetID(), array_pos);
-    id_array[array_pos] = genotype->GetID();
-    pid_array[array_pos] = genotype->GetParentID();
-    depth_array[array_pos] = genotype->GetDepth();
-    birth_array[array_pos] = genotype->GetUpdateBorn();
-    array_pos++;
-  }
-  
-  // Now collect information about the offspring of each individual.
-  tArray<int> ppos_array(num_gens), offspring_count(num_gens);
-  offspring_count.SetAll(0);
-  for (int pos = 0; pos < num_gens; pos++) {
-    int parent_id = gen_array[pos]->GetParentID();
-    if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
-      ppos_array[pos] = -1;
-      continue;
-    }
-    int parent_pos = -1;
-    id_hash.Find(parent_id, parent_pos);
-    ppos_array[pos] = parent_pos;
-    offspring_count[parent_pos]++;
-  }
-  
-  // For each genotype, figure out how far back you need to go to get to a
-  // branch point.
-  tArray<int> branch_dist_array(num_gens);
-  tArray<int> branch_pos_array(num_gens);
-  branch_dist_array.SetAll(-1);
-  branch_pos_array.SetAll(-1);
-  bool found = true;
-  int loop_count = 0;
-  while (found == true) {
-    found = false;
-    for (int pos = 0; pos < num_gens; pos++) {
-      if (branch_dist_array[pos] > -1) continue; // continue if its set.
-      found = true;
-      int parent_pos = ppos_array[pos];
-      if (parent_pos == -1) branch_dist_array[pos] = 0;  // Org is root.
-      else if (offspring_count[parent_pos] > 1) {        // Parent is branch.
-        branch_dist_array[pos] = 1;
-        branch_pos_array[pos] = parent_pos;
-      }
-      else if (branch_dist_array[parent_pos] > -1) {     // Parent calculated.
-        branch_dist_array[pos] = branch_dist_array[parent_pos]+1;
-        branch_pos_array[pos] = branch_pos_array[parent_pos];
-      }
-      // Otherwise, we are not yet ready to calculate this entry.
-    }
-    loop_count++;
-  }
-  
-  
-  // Cumulative Stemminess
-  for (int pos = 0; pos < num_gens; pos++) {
-    // We're only interested in internal n-furcating nodes.
-    if (pid_array[pos] == -1) continue;  // Don't want root.
-    if (offspring_count[pos] <= 1) continue; // No leaves or nonfurcating nodes
-    
-    // @CAO Find distance to all children.
-    // @CAO Find distance to parent branch.
-    // @CAO DO math.
-  }
-  
-  
-  cout << "LOOP COUNT:" << loop_count << endl;
-  for (int i = 0; i < num_gens; i++) {
-    int branch_pos = branch_pos_array[i];
-    int branch_id = (branch_pos == -1) ? -1 : id_array[branch_pos];
-    cout << i << " "
-      << id_array[i] << " "
-      << offspring_count[i] << " "
-      << branch_dist_array[i] << " "
-      << branch_id << " "
-      << endl;
-  }
+  cAnalyzeGenotypeTreeStats agts(m_world);
+  agts.AnalyzeBatchTree(batch[cur_batch].List());
+
+  fp << agts.AverageStemminess();
+  fp << endl;
+
+  /*
+  Below is the original implementation by Ofria.
+  -- kgn
+  */
+
+  //cAnalyzeGenotype * genotype = NULL;
+  //tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
+  //const int num_gens = batch[cur_batch].List().GetSize();
+  //
+  //// Put all of the genotypes in an array for easy reference and collect
+  //// other information on them as we process them.
+  //tArray<cAnalyzeGenotype *> gen_array(num_gens);
+  //tHashTable<int, int> id_hash;  // Store array pos for each id.
+  //tArray<int> id_array(num_gens), pid_array(num_gens);
+  //tArray<int> depth_array(num_gens), birth_array(num_gens);
+  //int array_pos = 0;
+  //while ((genotype = batch_it.Next()) != NULL) {
+  //  // Put the genotype in an array.
+  //  gen_array[array_pos] = genotype;
+  //  id_hash.Add(genotype->GetID(), array_pos);
+  //  id_array[array_pos] = genotype->GetID();
+  //  pid_array[array_pos] = genotype->GetParentID();
+  //  depth_array[array_pos] = genotype->GetDepth();
+  //  birth_array[array_pos] = genotype->GetUpdateBorn();
+  //  array_pos++;
+  //}
+  //
+  //// Now collect information about the offspring of each individual.
+  //tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+  //offspring_count.SetAll(0);
+  //for (int pos = 0; pos < num_gens; pos++) {
+  //  int parent_id = gen_array[pos]->GetParentID();
+  //  if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
+  //    ppos_array[pos] = -1;
+  //    continue;
+  //  }
+  //  int parent_pos = -1;
+  //  id_hash.Find(parent_id, parent_pos);
+  //  ppos_array[pos] = parent_pos;
+  //  offspring_count[parent_pos]++;
+  //}
+  //
+  //// For each genotype, figure out how far back you need to go to get to a
+  //// branch point.
+  //tArray<int> branch_dist_array(num_gens);
+  //tArray<int> branch_pos_array(num_gens);
+  //branch_dist_array.SetAll(-1);
+  //branch_pos_array.SetAll(-1);
+  //bool found = true;
+  //int loop_count = 0;
+  //while (found == true) {
+  //  found = false;
+  //  for (int pos = 0; pos < num_gens; pos++) {
+  //    if (branch_dist_array[pos] > -1) continue; // continue if its set.
+  //    found = true;
+  //    int parent_pos = ppos_array[pos];
+  //    if (parent_pos == -1) branch_dist_array[pos] = 0;  // Org is root.
+  //    else if (offspring_count[parent_pos] > 1) {        // Parent is branch.
+  //      branch_dist_array[pos] = 1;
+  //      branch_pos_array[pos] = parent_pos;
+  //    }
+  //    else if (branch_dist_array[parent_pos] > -1) {     // Parent calculated.
+  //      branch_dist_array[pos] = branch_dist_array[parent_pos]+1;
+  //      branch_pos_array[pos] = branch_pos_array[parent_pos];
+  //    }
+  //    // Otherwise, we are not yet ready to calculate this entry.
+  //  }
+  //  loop_count++;
+  //}
+  //
+  //
+  //// Cumulative Stemminess
+  //for (int pos = 0; pos < num_gens; pos++) {
+  //  // We're only interested in internal n-furcating nodes.
+  //  if (pid_array[pos] == -1) continue;  // Don't want root.
+  //  if (offspring_count[pos] <= 1) continue; // No leaves or nonfurcating nodes
+  //  
+  //  // @CAO Find distance to all children.
+  //  // @CAO Find distance to parent branch.
+  //  // @CAO DO math.
+  //}
+  //
+  //
+  //cout << "LOOP COUNT:" << loop_count << endl;
+  //for (int i = 0; i < num_gens; i++) {
+  //  int branch_pos = branch_pos_array[i];
+  //  int branch_id = (branch_pos == -1) ? -1 : id_array[branch_pos];
+  //  cout << i << " "
+  //    << id_array[i] << " "
+  //    << offspring_count[i] << " "
+  //    << branch_dist_array[i] << " "
+  //    << branch_id << " "
+  //    << endl;
+  //}
 }
 
 
@@ -7954,9 +7971,9 @@
 }
 
 
-void cAnalyze::LoadCommandList(cInitFile& init_file, tList<cAnalyzeCommand>& clist)
+int cAnalyze::LoadCommandList(cInitFile& init_file, tList<cAnalyzeCommand>& clist, int start_at)
 {
-  for (int i = 0; i < init_file.GetNumLines(); i++) {
+  for (int i = start_at; i < init_file.GetNumLines(); i++) {
     cString cur_string = init_file.GetLine(i);
     cString command = cur_string.PopWord();
     
@@ -7965,11 +7982,11 @@
     
     if (command == "END") {
       // We are done with this section of code; break out...
-      break;
+      return i;
     } else if (command_def != NULL && command_def->IsFlowCommand() == true) {
       // This code has a body to it... fill it out!
       cur_command = new cAnalyzeFlowCommand(command, cur_string);
-      LoadCommandList( init_file, *(cur_command->GetCommandList()) );
+      i = LoadCommandList(init_file, *(cur_command->GetCommandList()), i + 1); // Start processing at the next line
     } else {
       // This is a normal command...
       cur_command = new cAnalyzeCommand(command, cur_string);
@@ -7977,6 +7994,8 @@
     
     clist.PushRear(cur_command);
   }
+  
+  return init_file.GetNumLines();
 }
 
 void cAnalyze::InteractiveLoadCommandList(tList<cAnalyzeCommand> & clist)

Modified: branches/energy/source/analyze/cAnalyze.h
===================================================================
--- branches/energy/source/analyze/cAnalyze.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/analyze/cAnalyze.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -84,12 +84,7 @@
 #if USE_tMemTrack
   tMemTrack<cAnalyze> mt;
 #endif
-/*
-FIXME : switch back to private.
-- switched to public while I brainstorm.  @kgn 06.11.22
-*/
-//private:
-public:
+private:
   int cur_batch;
 
   /*
@@ -153,51 +148,73 @@
     COMPARE_RESULT_DIFF =  3  // Is different from parent (non qualtity).
   };
 
+
+  cAnalyze(); // @not_implemented
+  cAnalyze(const cAnalyze&); // @not_implemented
+  cAnalyze& operator=(const cAnalyze&); // @not_implemented
+
+public:
+  cAnalyze(cWorld* world);
+  ~cAnalyze();
+
+  void RunFile(cString filename);
+  void RunInteractive();
+  bool Send(const cString &text_input);
+  bool Send(const cStringList &list_input);
+  
+  int GetCurrentBatchID() { return cur_batch; }
+  cGenotypeBatch& GetCurrentBatch() { return batch[cur_batch]; }
+  cGenotypeBatch& GetBatch(int id) { assert(id >= 0 && id < MAX_BATCHES); return batch[id]; }
+  cAnalyzeJobQueue& GetJobQueue() { return m_jobqueue; }
+  
+  void AlignCurrentBatch() { CommandAlign(""); }
+
+  
+private:
   // Pop specific types of arguments from an arg list.
   cString PopDirectory(cString  in_string, const cString default_dir);
-  int PopBatch(const cString & in_string);
-  cAnalyzeGenotype * PopGenotype(cString gen_desc, int batch_id=-1);
+  int PopBatch(const cString& in_string);
+  cAnalyzeGenotype* PopGenotype(cString gen_desc, int batch_id = -1);
   cString & GetVariable(const cString & varname);
-
+  
   // Other arg-list methods
-  void LoadCommandList(cInitFile & init_file, tList<cAnalyzeCommand> & clist);
-  void InteractiveLoadCommandList(tList<cAnalyzeCommand> & clist);
-  void PreProcessArgs(cString & args);
-  void ProcessCommands(tList<cAnalyzeCommand> & clist);
-
+  int LoadCommandList(cInitFile& init_file, tList<cAnalyzeCommand>& clist, int start_line = 0);
+  void InteractiveLoadCommandList(tList<cAnalyzeCommand>& clist);
+  void PreProcessArgs(cString& args);
+  void ProcessCommands(tList<cAnalyzeCommand>& clist);
+  
   // Helper functions for printing to HTML files...
-  void HTMLPrintStat(const cFlexVar & value, std::ostream& fp, int compare=0,
-		     const cString & cell_flags="align=center", const cString & null_text="0", bool print_text=true);
-  int CompareFlexStat(const cFlexVar & org_stat, const cFlexVar & parent_stat, int compare_type=FLEX_COMPARE_MAX);
-
+  void HTMLPrintStat(const cFlexVar& value, std::ostream& fp, int compare=0,
+                     const cString& cell_flags="align=center", const cString& null_text = "0", bool print_text = true);
+  int CompareFlexStat(const cFlexVar& org_stat, const cFlexVar& parent_stat, int compare_type = FLEX_COMPARE_MAX);
+  
   // Deal with genotype data list (linking keywords to stats)
   void SetupGenotypeDataList();	
-  tDataEntryCommand<cAnalyzeGenotype> * GetGenotypeDataCommand(const cString & stat_entry);
+  tDataEntryCommand<cAnalyzeGenotype>* GetGenotypeDataCommand(const cString & stat_entry);
   void LoadGenotypeDataList(cStringList arg_list, tList< tDataEntryCommand<cAnalyzeGenotype> > & output_list);
-		      
+  
   void AddLibraryDef(const cString & name, void (cAnalyze::*_fun)(cString));
   void AddLibraryDef(const cString & name, void (cAnalyze::*_fun)(cString, tList<cAnalyzeCommand> &));
-  cAnalyzeCommandDefBase * FindAnalyzeCommandDef(const cString & name);
+  cAnalyzeCommandDefBase* FindAnalyzeCommandDef(const cString& name);
   void SetupCommandDefLibrary();
-  bool FunctionRun(const cString & fun_name, cString args);
-
+  bool FunctionRun(const cString& fun_name, cString args);
+  
   // Batch management...
-  int BatchUtil_GetMaxLength(int batch_id=-1);
-
+  int BatchUtil_GetMaxLength(int batch_id = -1);
+  
   // Comamnd helpers...
   void CommandDetail_Header(std::ostream& fp, int format_type,
-            tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it,
-            int time_step=-1);
+                            tListIterator< tDataEntryCommand<cAnalyzeGenotype> >& output_it, int time_step = -1);
   void CommandDetail_Body(std::ostream& fp, int format_type,
-            tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it,
-            int time_step=-1, int max_time=1);
+                          tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it,
+                          int time_step = -1, int max_time = 1);
   void CommandDetailAverage_Body(std::ostream& fp, int num_arguments,
-            tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it);
+                                 tListIterator< tDataEntryCommand<cAnalyzeGenotype> >& output_it);
   void CommandHistogram_Header(std::ostream& fp, int format_type,
-            tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it);
+                               tListIterator< tDataEntryCommand<cAnalyzeGenotype> >& output_it);
   void CommandHistogram_Body(std::ostream& fp, int format_type,
-            tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it);
-
+                             tListIterator< tDataEntryCommand<cAnalyzeGenotype> >& output_it);
+  
   // Loading methods...
   void LoadOrganism(cString cur_string);
   void LoadBasicDump(cString cur_string);
@@ -209,7 +226,7 @@
   // from a file specified by the user, or resource.dat by default.
   void LoadResources(cString cur_string);
   void LoadFile(cString cur_string);
-
+  
   // Reduction
   void CommandFilter(cString cur_string);
   void FindGenotype(cString cur_string);
@@ -222,7 +239,7 @@
   void KeepTopGenotypes(cString cur_string);
   void TruncateLineage(cString cur_string);
   
-
+  
   // Direct Output Commands...
   void CommandPrint(cString cur_string);
   void CommandTrace(cString cur_string);
@@ -235,14 +252,14 @@
   void CommandDetailAverage(cString cur_string);
   void CommandDetailIndex(cString cur_string);
   void CommandHistogram(cString cur_string);
-
+  
   // Population Analysis Commands...
   void CommandPrintPhenotypes(cString cur_string);
   void CommandPrintDiversity(cString cur_string);
   void CommandPrintTreeStats(cString cur_string);
   void PhyloCommunityComplexity(cString cur_string);
   void AnalyzeCommunityComplexity(cString cur_string);
-
+  
   // Individual Organism Analysis...
   void CommandFitnessMatrix(cString cur_string);
   void CommandMapTasks(cString cur_string);
@@ -251,23 +268,23 @@
   void CommandMapMutations(cString cur_string);
   void CommandMapDepth(cString cur_string);
   void CommandPairwiseEntropy(cString cur_string);
- 
+  
   // Population Comparison Commands...
   void CommandHamming(cString cur_string);
   void CommandLevenstein(cString cur_string);
   void CommandSpecies(cString cur_string);
   void CommandRecombine(cString cur_string);
-
+  
   // Lineage Analysis Commands...
   void CommandAlign(cString cur_string);
   void AnalyzeNewInfo(cString cur_string);  
   void MutationRevert(cString cur_string);
-
+  
   // Build Input Files for Avida
   void WriteClone(cString cur_string);
   void WriteInjectEvents(cString cur_string);
   void WriteCompetition(cString cur_string);
-
+  
   // Automated analysis...
   void AnalyzeMuts(cString cur_string);
   void AnalyzeInstructions(cString cur_string);
@@ -279,13 +296,13 @@
   void AnalyzePopComplexity(cString cur_string);
   void AnalyzeMateSelection(cString cur_string);
   void AnalyzeComplexityDelta(cString cur_string);
-
+  
   // Environment Manipulation
   void EnvironmentSetup(cString cur_string);
-
+  
   // Documentation...
   void CommandHelpfile(cString cur_string);
-
+  
   // Control...
   void VarSet(cString cur_string);
   void ConfigGet(cString cur_string);
@@ -304,55 +321,35 @@
   void IncludeFile(cString cur_string);
   void CommandSystem(cString cur_string);
   void CommandInteractive(cString cur_string);
-
+  
   // Uncategorized...
   void BatchCompete(cString cur_string);
-
+  
   // Functions...
-  void FunctionCreate(cString cur_string, tList<cAnalyzeCommand> & clist);
+  void FunctionCreate(cString cur_string, tList<cAnalyzeCommand>& clist);
+  
   // Looks up the resource concentrations that are the closest to the
   // given update and then fill in those concentrations into the environment.
   void FillResources(cTestCPU* testcpu, int update);
+  
   // Analyze the entropy of genotype under default environment
-  double AnalyzeEntropy(cAnalyzeGenotype * genotype, double mut_rate);
+  double AnalyzeEntropy(cAnalyzeGenotype* genotype, double mut_rate);
+  
   // Analyze the entropy of child given parent and default environment
-  double AnalyzeEntropyGivenParent(cAnalyzeGenotype * genotype, 
-				   cAnalyzeGenotype * parent, 
-				   double mut_rate);
+  double AnalyzeEntropyGivenParent(cAnalyzeGenotype* genotype, cAnalyzeGenotype* parent, double mut_rate);
+  
   // Calculate the increased information in genotype1 comparing to genotype2 
   // line by line. If information in genotype1 is less than that in genotype2 
   // in a line, increasing is 0. Usually this is used for child-parent comparison.
-  double IncreasedInfo(cAnalyzeGenotype * genotype1, 
-		       cAnalyzeGenotype * genotype2, 
-		       double mut_rate);
-
+  double IncreasedInfo(cAnalyzeGenotype* genotype1, cAnalyzeGenotype* genotype2, double mut_rate);
+  
   //Calculate covarying information between pairs of sites
-  tMatrix<double> AnalyzeEntropyPairs(cAnalyzeGenotype * genotype,
-					       double mut_rate);
-
+  tMatrix<double> AnalyzeEntropyPairs(cAnalyzeGenotype* genotype, double mut_rate);
   
-  // Flow Control...
-  void CommandForeach(cString cur_string, tList<cAnalyzeCommand> & clist);
-  void CommandForRange(cString cur_string, tList<cAnalyzeCommand> & clist);
 
-  cAnalyze(const cAnalyze &); // Intentially not implemented
-
-public:
-  cAnalyze(cWorld* world);
-  ~cAnalyze();
-
-  void RunFile(cString filename);
-  void RunInteractive();
-  bool Send(const cString &text_input);
-  bool Send(const cStringList &list_input);
-  
-  int GetCurrentBatchID() { return cur_batch; }
-  cGenotypeBatch& GetCurrentBatch() { return batch[cur_batch]; }
-  cGenotypeBatch& GetBatch(int id) {
-    assert(id >= 0 && id < MAX_BATCHES);
-    return batch[id];
-  }
-  cAnalyzeJobQueue& GetJobQueue() { return m_jobqueue; }
+  // Flow Control...
+  void CommandForeach(cString cur_string, tList<cAnalyzeCommand>& clist);
+  void CommandForRange(cString cur_string, tList<cAnalyzeCommand>& clist);
 };
 
 #endif

Modified: branches/energy/source/analyze/cAnalyzeGenotype.cc
===================================================================
--- branches/energy/source/analyze/cAnalyzeGenotype.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/analyze/cAnalyzeGenotype.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -414,7 +414,7 @@
   const cPlasticPhenotype* likely_phenotype = recalc_data.GetMostLikelyPhenotype();
   
   viable         = likely_phenotype->IsViable();
-  m_env_inputs   = likely_phenotype->GetEnvInputs()[0];
+  m_env_inputs   = likely_phenotype->GetEnvInputs();
   executed_flags = likely_phenotype->GetExecutedFlags();
   length         = likely_phenotype->GetGenomeLength();
   copy_length    = likely_phenotype->GetCopiedSize();

Copied: branches/energy/source/analyze/cAnalyzeGenotypeTreeStats.cc (from rev 2068, development/source/analyze/cAnalyzeGenotypeTreeStats.cc)
===================================================================
--- branches/energy/source/analyze/cAnalyzeGenotypeTreeStats.cc	                        (rev 0)
+++ branches/energy/source/analyze/cAnalyzeGenotypeTreeStats.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -0,0 +1,393 @@
+
+#include "cAnalyzeGenotypeTreeStats.h"
+
+#include "cAnalyzeGenotype.h"
+#include "tHashTable.h"
+#include "cWorld.h"
+
+
+void cAnalyzeGenotypeTreeStats::PrintAGLData(tArray<cAGLData> &agl){
+  for(int i=0; i < agl.GetSize(); i++){
+    cout << i << ":";
+    cout << " " << agl[i].id;
+    cout << " " << agl[i].pid;
+    cout << " " << agl[i].depth;
+    cout << " " << agl[i].birth;
+    cout << " " << agl[i].ppos;
+    cout << " " << agl[i].offspring_count;
+    cout << " " << agl[i].anc_branch_dist;
+    cout << " " << agl[i].anc_branch_id;
+    cout << " " << agl[i].anc_branch_pos;
+    cout << " " << agl[i].off_branch_dist_acc;
+    cout << " " << agl[i].cumulative_stemminess;
+    cout << " " << agl[i].traversal_visited;
+    for(int j=0; j < agl[i].offspring_positions.GetSize(); j++){
+      cout << " " << agl[i].offspring_positions[j];
+    }
+    cout << endl;
+  }
+}
+
+void cAnalyzeGenotypeTreeStats::AnalyzeBatchTree(tList<cAnalyzeGenotype> &genotype_list){
+  cAnalyzeGenotype * genotype = NULL;
+  tListIterator<cAnalyzeGenotype> batch_it(genotype_list);
+  const int num_gens = genotype_list.GetSize();
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Number of genotypes: " << num_gens << endl;
+  }
+
+
+  int array_pos = 0;
+
+  /*
+  Put all of the genotypes in an array for easy reference and collect other
+  information on them as we process them. {{{4
+  */
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Scanning genotypes..." << endl;
+  }
+  tArray<cAnalyzeGenotype *> gen_array(num_gens);
+  tHashTable<int, int> id_hash;  // Store array pos for each id.
+  tArray<int> id_array(num_gens), pid_array(num_gens);
+  tArray<int> depth_array(num_gens), birth_array(num_gens);
+
+  array_pos = 0;
+  batch_it.Reset();
+  while ((genotype = batch_it.Next()) != NULL) {
+    id_hash.Add(genotype->GetID(), array_pos);
+    array_pos++;
+  }
+
+  m_agl.Resize(num_gens);
+  array_pos = 0;
+  batch_it.Reset();
+  while ((genotype = batch_it.Next()) != NULL) {
+    // Put the genotype in an array.
+    m_agl[array_pos].genotype = genotype;
+    m_agl[array_pos].id = genotype->GetID();
+    m_agl[array_pos].pid = genotype->GetParentID();
+    m_agl[array_pos].depth = genotype->GetDepth();
+    m_agl[array_pos].birth = genotype->GetUpdateBorn();
+    array_pos++;
+  }
+
+  //// Now collect information about the offspring of each individual. {{{4
+  tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+  offspring_count.SetAll(0);
+
+  // For each genotype, figure out how far back you need to go to get to a branch point. {{{4
+  tArray<int> anc_branch_dist_array(num_gens);
+  tArray<int> anc_branch_pos_array(num_gens);
+  anc_branch_dist_array.SetAll(-1);
+  anc_branch_pos_array.SetAll(-1);
+  bool found = true;
+  int loop_count = 0;
+
+  /*
+  Link each offspring to its parent. {{{4
+  */
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Assembling tree..." << endl;
+  }
+  for (int pos = 0; pos < num_gens; pos++) {
+    //cAnalyzeGenotype * genotype = gen_array[pos];
+    cAnalyzeGenotype * genotype = m_agl[pos].genotype;
+    int parent_id = genotype->GetParentID();
+    if (-1 != parent_id){
+      bool found_parent = id_hash.Find(parent_id, m_agl[pos].ppos);
+      if (found_parent){
+        int parent_position = m_agl[pos].ppos;
+        m_agl[parent_position].offspring_positions.Push(pos);
+        ///* XXX I think I'll be able to remove this. */
+        //cAnalyzeGenotype * parent_genotype = m_agl[parent_position].genotype;
+        //genotype->LinkParent(parent_genotype);
+      } else {
+        if (m_world->GetVerbosity() >= VERBOSE_ON) {
+          cerr << "Error: the parent of a non-root tree node is missing - " << endl;
+        }
+        return;
+      }
+    }
+  }
+
+  /*
+  Count offspring of each parent. {{{4
+  */
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Loading offspring counts..." << endl;
+  }
+  for (int pos = 0; pos < num_gens; pos++) {
+    m_agl[pos].offspring_count = m_agl[pos].offspring_positions.GetSize();
+  }
+
+
+  /*
+  For each genotype, figure out how far back you need to go to get to a branch point. {{{4
+  */
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Finding branch points..." << endl;
+  }
+  found = true;
+  loop_count = 0;
+  while (found == true) {
+    if (false && m_world->GetVerbosity() >= VERBOSE_ON) {
+      cout << endl << "  wave " << loop_count << "...";
+    }
+    found = false;
+
+    int genotypes_already_set = 0;
+    int genotypes_identified_as_root = 0;
+    int genotypes_with_branching_parent = 0;
+    int genotypes_with_calced_parent = 0;
+    int genotypes_not_ready = 0;
+
+    for (int pos = 0; pos < num_gens; pos++) {
+      if (m_agl[pos].anc_branch_dist > -1){
+        genotypes_already_set++;
+        continue; // continue if its set.
+      }
+      found = true;
+      int parent_pos = m_agl[pos].ppos;
+      if (parent_pos == -1) {
+        genotypes_identified_as_root++;
+        m_agl[pos].anc_branch_dist = 0;  // Org is root.
+      } else if (m_agl[parent_pos].offspring_count > 1) {        // Parent is branch.
+        genotypes_with_branching_parent++;
+        m_agl[pos].anc_branch_dist = 1;
+        m_agl[pos].anc_branch_id = m_agl[parent_pos].id;
+        m_agl[pos].anc_branch_pos = parent_pos;
+      } else if (m_agl[parent_pos].anc_branch_dist > -1) {     // Parent calculated.
+        genotypes_with_calced_parent++;
+        m_agl[pos].anc_branch_dist = m_agl[parent_pos].anc_branch_dist + 1;
+        m_agl[pos].anc_branch_id = m_agl[parent_pos].anc_branch_id;
+        m_agl[pos].anc_branch_pos = m_agl[parent_pos].anc_branch_pos;
+      } else {
+        genotypes_not_ready++;
+        // Otherwise, we are not yet ready to calculate this entry.
+      }
+    }
+    if (false && m_world->GetVerbosity() >= VERBOSE_ON) {
+      cout << " (" << genotypes_already_set << "," << genotypes_identified_as_root << "," << genotypes_with_branching_parent << "," << genotypes_with_calced_parent << "," << genotypes_not_ready << ")" << endl;
+    }
+    loop_count++;
+  }
+
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Building n-furcating subtree..." << endl;
+  }
+  // compute number of subtree nodes.
+  int branch_tree_size = 0;
+  for (int pos = 0; pos < num_gens; pos++) {
+    //if(m_agl[pos].offspring_count != 1){
+    if(m_agl[pos].offspring_count > 1){
+      branch_tree_size++;
+    }
+  }
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Number of n-furcating nodes: " << branch_tree_size << endl;
+  }
+  if (branch_tree_size <= 0){
+    if (m_world->GetVerbosity() >= VERBOSE_ON) {
+      cerr << "Error: no branches found in tree - " << endl;
+    }
+    return;
+  }
+
+  m_agl2.Resize(branch_tree_size);  // Store agl data for each id.
+  tHashTable<int, int> id_hash_2;
+  int array_pos_2 = 0;
+  if (true) for (int pos = 0; pos < num_gens; pos++) {
+    int offs_count = m_agl[pos].offspring_count;
+    //if (offs_count != 1){
+    if (offs_count > 1){
+      m_agl2[array_pos_2].id = m_agl[pos].id;
+      m_agl2[array_pos_2].pid = m_agl[pos].pid;
+      m_agl2[array_pos_2].depth = m_agl[pos].depth;
+      m_agl2[array_pos_2].birth = m_agl[pos].birth;
+      m_agl2[array_pos_2].anc_branch_dist = m_agl[pos].anc_branch_dist;
+      m_agl2[array_pos_2].anc_branch_id = m_agl[pos].anc_branch_id;
+      /*
+      missing still are ppos (skip this), offspring_count (redundant),
+      anc_branch_pos, off_branch_dist_acc (to be calculated),
+      offspring_positions
+      */
+      id_hash_2.Add(m_agl2[array_pos_2].id, array_pos_2);
+      array_pos_2++;
+    }
+  }
+
+  // find branch ancestor positions. {{{4
+  for (int pos = 0; pos < branch_tree_size; pos++){
+    int anc_branch_id = m_agl2[pos].anc_branch_id;
+    id_hash_2.Find(anc_branch_id, m_agl2[pos].anc_branch_pos);
+    int anc_branch_pos = m_agl2[pos].anc_branch_pos;
+    if(0 <= anc_branch_pos){
+      m_agl2[anc_branch_pos].offspring_positions.Push(pos);
+    }
+  }
+  
+  /*
+  For DFS of branch tree, locate root. {{{4
+  */
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Finding root of n-furcating subtree..." << endl;
+  }
+  cAGLData *root = 0;
+  for (int pos = 0; pos < branch_tree_size; pos++){
+    m_agl2[pos].traversal_visited = false;
+    /*
+    root : anc_branch_dist: 0 anc_branch_id: -1 anc_branch_pos: -1 
+
+    Only one of these conditions should be needed. I'm mixing-in a
+    sanity check here. I ought to move it...
+    */
+    if( (m_agl2[pos].anc_branch_dist == 0)
+      ||(m_agl2[pos].anc_branch_id == -1)
+      ||(m_agl2[pos].anc_branch_pos == -1)
+    ){
+      root = &(m_agl2[pos]);
+      /* Sanity check. */
+      if(
+        !(
+          //(m_agl2[pos].anc_branch_dist == 0) &&
+          (m_agl2[pos].anc_branch_id == -1) &&
+          (m_agl2[pos].anc_branch_pos == -1)
+        )
+      ){
+        if (m_world->GetVerbosity() >= VERBOSE_ON) {
+          cerr << "Error: while looking for root of subtree, found inconsistencies - " << endl;
+          cerr << " root ancestor-branch-distance: " << m_agl2[pos].anc_branch_dist << endl;
+          cerr << " root ancestor-branch-id: " << m_agl2[pos].anc_branch_id << endl;
+          cerr << " root ancestor-branch-pos: " << m_agl2[pos].anc_branch_id << endl;
+        }
+        return;
+      }
+    }
+  }
+
+  /*
+  DFS of branch tree, to accumulate branch distances. {{{4
+  */
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Accumulating branch distances..." << endl;
+  }
+  tList<cAGLData> dfs_stack;
+  if(0 != root){
+    /* DFS. */
+    dfs_stack.Push(root);
+    cAGLData *node = 0;
+    while (0 < dfs_stack.GetSize()){
+      node = dfs_stack.Pop();
+      if (0 != node){
+        if (! node->traversal_visited){
+          dfs_stack.Push(node);
+          node->off_branch_dist_acc = 0;
+          for (int i = 0; i < node->offspring_positions.GetSize(); i++){
+            int pos = node->offspring_positions[i];
+            if (! m_agl2[pos].traversal_visited){
+              dfs_stack.Push(&(m_agl2[pos]));
+            }
+          }
+          node->traversal_visited = true;
+        } else {
+          /*
+          Child nodes, if any, have been visited and have added their
+          off_branch_dist_acc to this node.
+          */
+          if(0 <= node->anc_branch_pos){
+            /*
+            Only accumulate to parent if there is a parent (i.e., this
+            is not the root.)
+            */
+            m_agl2[node->anc_branch_pos].off_branch_dist_acc += node->anc_branch_dist;
+            m_agl2[node->anc_branch_pos].off_branch_dist_acc += node->off_branch_dist_acc;
+          }
+        }
+      }
+    }
+  } else {
+    if (m_world->GetVerbosity() >= VERBOSE_ON) {
+      cerr << "Error: couldn't find root of subtree - " << endl;
+    }
+    return;
+  }
+
+  /*
+  Compute cumulative stemminesses. {{{4
+  */
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Computing cumulative stemminesses..." << endl;
+  }
+  for (int pos = 0; pos < branch_tree_size; pos++){
+    if (0 == m_agl2[pos].anc_branch_dist){
+      /* Correct stemminess for root... */
+      /*
+      Let me rephrase that. If anc_branch_dist is zero and all is well,
+      we're dealing with the root.
+      */
+      m_agl2[pos].cumulative_stemminess = 0.0;
+    } else {
+      m_agl2[pos].cumulative_stemminess =
+      (
+        (double)(m_agl2[pos].anc_branch_dist)
+        /
+        (
+          (double)(m_agl2[pos].off_branch_dist_acc) + (double)(m_agl2[pos].anc_branch_dist)
+        )
+      );
+    }
+  }
+
+  /*
+  Compute average cumulative stemminess. {{{4
+  */
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "Computing average cumulative stemminess..." << endl;
+  }
+  m_stemminess_sum = 0.0;
+  m_average_stemminess = 0.0;
+  m_inner_nodes = 0;
+  if (1 < branch_tree_size) {
+    for (int pos = 0; pos < branch_tree_size; pos++){
+      bool not_leaf = true;
+      if (m_should_exclude_leaves) {
+        not_leaf = (0 < m_agl2[pos].off_branch_dist_acc);
+      }
+      bool not_root = (0 < m_agl2[pos].anc_branch_id);
+      if (not_leaf && not_root){
+        m_stemminess_sum += m_agl2[pos].cumulative_stemminess;
+        m_inner_nodes++;
+      }
+    }
+  }
+  if(0 < m_inner_nodes){
+    m_average_stemminess = m_stemminess_sum / (m_inner_nodes);
+  }
+
+  /*
+  Print branch tree. {{{4
+  Use to get expected data for making following test.
+  */
+
+  if (false && m_world->GetVerbosity() >= VERBOSE_ON) {
+    for (int pos = 0; pos < branch_tree_size; pos++){
+      cout << "id: " << m_agl2[pos].id;
+      cout << " offspring_count: " << m_agl2[pos].offspring_positions.GetSize();
+      cout << " anc_branch_id: " << m_agl2[pos].anc_branch_id;
+      cout << " anc_branch_dist: " << m_agl2[pos].anc_branch_dist;
+      cout << " off_branch_dist_acc: " << m_agl2[pos].off_branch_dist_acc;
+      cout << " cumulative_stemminess: " << m_agl2[pos].cumulative_stemminess;
+      cout << endl;
+      if (0 < m_agl2[pos].offspring_positions.GetSize()) {
+        cout << "  offspring ids:";
+        for (int i = 0; i < m_agl2[pos].offspring_positions.GetSize(); i++){
+          cout << " " << m_agl2[pos].offspring_positions[i];
+        }
+        cout << endl;
+      }
+    }
+    cout << "m_stemminess_sum: " << m_stemminess_sum << endl;
+    cout << "m_average_stemminess: " << m_average_stemminess << endl;
+    cout << "m_inner_nodes: " << m_inner_nodes << endl;
+  }
+}

Copied: branches/energy/source/analyze/cAnalyzeGenotypeTreeStats.h (from rev 2068, development/source/analyze/cAnalyzeGenotypeTreeStats.h)
===================================================================
--- branches/energy/source/analyze/cAnalyzeGenotypeTreeStats.h	                        (rev 0)
+++ branches/energy/source/analyze/cAnalyzeGenotypeTreeStats.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -0,0 +1,98 @@
+#ifndef cAnalyzeGenotypeTreeStats_h
+#define cAnalyzeGenotypeTreeStats_h
+
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+#ifndef tList_h
+#include "tList.h"
+#endif
+
+
+class cAnalyzeGenotype;
+class cWorld;
+
+
+/*
+Convenience class cAGLData serves to collect various data I found I needed
+while building the class cAnalyzeGenotypeTreeStats.
+*/
+class cAGLData {
+public:
+  cAnalyzeGenotype *genotype;
+  int id;
+  int pid;
+  int depth;
+  int birth;
+  int ppos;
+  int offspring_count;
+  int anc_branch_dist;
+  int anc_branch_id;
+  int anc_branch_pos;
+  int off_branch_dist_acc;
+  double cumulative_stemminess;
+  bool traversal_visited;
+  tArray<int> offspring_positions;
+
+  cAGLData()
+  : genotype(0)
+  , id(-1)
+  , pid(-1)
+  , depth(-1)
+  , birth(-1)
+  , ppos(-1)
+  , offspring_count(-1)
+  , anc_branch_dist(-1)
+  , anc_branch_id(-1)
+  , anc_branch_pos(-1)
+  , off_branch_dist_acc(-1)
+  , cumulative_stemminess(-1.)
+  , traversal_visited(false)
+  , offspring_positions(0)
+  {}
+};
+
+/*
+class cAnalyzeGenotypeTreeStats
+
+This class will eventually collect various kinds of statistics about various
+kinds of trees (e.g., phylogenetic).
+
+For now it only figures out "average cumulative stemminess".
+*/
+class cAnalyzeGenotypeTreeStats {
+public:
+  tArray<cAGLData> m_agl;
+  tArray<cAGLData> m_agl2;
+
+  double m_stemminess_sum;
+  double m_average_stemminess;
+  int m_inner_nodes;
+  bool m_should_exclude_leaves;
+
+  cWorld* m_world;
+
+public:
+  cAnalyzeGenotypeTreeStats(cWorld* world)
+  : m_agl(0)
+  , m_agl2(0)
+  , m_stemminess_sum(0.0)
+  , m_average_stemminess(0.0)
+  , m_inner_nodes(0)
+  , m_should_exclude_leaves(true)
+  , m_world(world)
+  {}
+
+  tArray<cAGLData> &AGL(){ return m_agl; }
+  tArray<cAGLData> &AGL2(){ return m_agl2; }
+  double StemminessSum(){ return m_stemminess_sum; }
+  double AverageStemminess(){ return m_average_stemminess; }
+  int InnerNodes(){ return m_inner_nodes; }
+  bool ExcludesLeaves(){ return m_should_exclude_leaves; }
+
+  void PrintAGLData(tArray<cAGLData> &agl);
+
+  void AnalyzeBatchTree(tList<cAnalyzeGenotype> &genotype_list);
+};
+
+#endif

Modified: branches/energy/source/classification/cGenotypeControl.cc
===================================================================
--- branches/energy/source/classification/cGenotypeControl.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/classification/cGenotypeControl.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -204,29 +204,22 @@
 
 bool cGenotypeControl::Adjust(cGenotype & in_genotype)
 {
-  cGenotype * cur_genotype = in_genotype.GetPrev();
+  cGenotype* cur_genotype = in_genotype.GetPrev();
 
   // Check to see if this genotype should be removed completely.
-
-  if (in_genotype.GetNumOrganisms() == 0 &&
-      in_genotype.GetDeferAdjust() == false) {
+  if (in_genotype.GetNumOrganisms() == 0 && in_genotype.GetDeferAdjust() == false) {
     m_world->GetClassificationManager().RemoveGenotype(in_genotype);
     return false;
   }
 
   // Do not adjust the position of this genotype if it was and still is the
   // best genotype, or if it is otherwise in the proper spot...
+  if (CheckPos(in_genotype)) return true;
 
-  if (CheckPos(in_genotype)) {
-    return true;
-  }
-
   // Otherwise, remove it from the queue (for just the moment).
-
   Remove(in_genotype);
 
   // If this genotype is the best, put it there.
-
   if (in_genotype.GetNumOrganisms() > best->GetNumOrganisms()) {
     Insert(in_genotype, best->GetPrev());
     best = &in_genotype;

Modified: branches/energy/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/energy/source/cpu/cHardwareCPU.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/cpu/cHardwareCPU.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -308,6 +308,7 @@
     
     // High-level instructions
     tInstLibEntry<tMethod>("repro", &cHardwareCPU::Inst_Repro),
+    tInstLibEntry<tMethod>("repro-sex", &cHardwareCPU::Inst_ReproSex),
     tInstLibEntry<tMethod>("repro-A", &cHardwareCPU::Inst_Repro),
     tInstLibEntry<tMethod>("repro-B", &cHardwareCPU::Inst_Repro),
     tInstLibEntry<tMethod>("repro-C", &cHardwareCPU::Inst_Repro),
@@ -356,9 +357,10 @@
     tInstLibEntry<tMethod>("time", &cHardwareCPU::Inst_GetUpdate),
     
     // Promoter Model
+    tInstLibEntry<tMethod>("promoter", &cHardwareCPU::Inst_Promoter),
     tInstLibEntry<tMethod>("terminate", &cHardwareCPU::Inst_Terminate),
-    tInstLibEntry<tMethod>("promoter", &cHardwareCPU::Inst_Promoter),
     tInstLibEntry<tMethod>("regulate", &cHardwareCPU::Inst_Regulate),
+    tInstLibEntry<tMethod>("numberate", &cHardwareCPU::Inst_Numberate),
     
     // Energy usage
     tInstLibEntry<tMethod>("double-energy-usage", &cHardwareCPU::Inst_DoubleEnergyUsage),
@@ -467,20 +469,22 @@
   }
 #endif   
 
+  // Promoter model
   if (m_world->GetConfig().PROMOTERS_ENABLED.Get())
   {
     // Ideally, this shouldn't be hard-coded
     cInstruction promoter_inst = m_world->GetHardwareManager().GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
-    promoter_search_pos = 0;
-    promoter_inst_executed = 0;
-    promoter_pos.Resize(0);
-    promoter_active.Resize(0);
+
+    m_promoter_index = -1; // Meaning the last promoter was nothing
+    m_promoter_offset = 0;
+    m_promoter_regulation = 0;
+    m_promoters.Resize(0);
     for (int i=0; i<GetMemory().GetSize(); i++)
     {
       if ( (GetMemory())[i] == promoter_inst)
       {
-        promoter_pos.Push(i);
-        promoter_active.Push(true);
+        int code = Numberate(i-1, -1);
+        m_promoters.Push( cPromoter(i,code) );
       }
     }
   }
@@ -506,27 +510,27 @@
   cur_head = nHardware::HEAD_IP;
   read_label.Clear();
   next_label.Clear();
+  
+  // Promoter model
+  m_promoter_inst_executed = 0;
 }
 
-
-
 // This function processes the very next command in the genome, and is made
 // to be as optimized as possible.  This is the heart of avida.
 
 void cHardwareCPU::SingleProcess(cAvidaContext& ctx)
 {
   int last_IP_pos = IP().GetPosition();
-
+  
   // Mark this organism as running...
   organism->SetRunning(true);
+  cPhenotype& phenotype = organism->GetPhenotype();
   
-  cPhenotype & phenotype = organism->GetPhenotype();
+  // First instruction - check whether we should be starting at a promoter, when enabled.
+  if (phenotype.GetCPUCyclesUsed() == 0 && m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1)
+    Inst_Terminate(m_world->GetDefaultContext());
   
-  if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) {
-    //First instruction - check whether we should be starting at a promoter.
-    if (phenotype.GetCPUCyclesUsed() == 0) Inst_Terminate(m_world->GetDefaultContext());
-  }
-  
+  // Count the cpu cycles used
   phenotype.IncCPUCyclesUsed();
   if (!m_world->GetConfig().NO_CPU_CYCLE_TIME.Get()) phenotype.IncTimeUsed();
 
@@ -558,6 +562,14 @@
     // Test if costs have been paid and it is okay to execute this now...
     bool exec = SingleProcess_PayCosts(ctx, cur_inst);
 
+    // If there are no active promoters and a certain mode is set, then don't execute any further instructions
+    if ((m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) 
+      && (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2) 
+      && (m_promoter_index == -1) ) 
+    { 
+      exec = false;
+    }
+    
     // Now execute the instruction...
     if (exec == true) {
       // NOTE: This call based on the cur_inst must occur prior to instruction
@@ -572,7 +584,7 @@
       
       //Add to the promoter inst executed count before executing the inst (in case it is a terminator)
       if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) {
-        promoter_inst_executed++;
+        m_threads[m_cur_thread].IncPromoterInstExecuted();
       }
 
       if (exec == true) SingleProcess_ExecuteInst(ctx, cur_inst);
@@ -583,29 +595,19 @@
       
       // Pay the time cost of the instruction now
       phenotype.IncTimeUsed(time_cost);
-      
-      // In the promoter model, there may be a chance of termination
-      // that causes execution to start at a new instruction (per instruction executed)
-      if ( m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1 ) {
-        const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY_INST.Get();
-        if ( ctx.GetRandom().P(1-processivity) ) Inst_Terminate(ctx);
+            
+      // In the promoter model, we may force termination after a certain number of inst have been executed
+      if ( m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1 )
+      {
+        const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY.Get();
+        if ( ctx.GetRandom().P(1-processivity) ) 
+          Inst_Terminate(ctx);
+        if ( m_world->GetConfig().PROMOTER_INST_MAX.Get() && (m_threads[m_cur_thread].GetPromoterInstExecuted() >= m_world->GetConfig().PROMOTER_INST_MAX.Get()) ) 
+          Inst_Terminate(ctx);
       }
-      
+
     } // if exec
-    
-    // In the promoter model, there may be a chance of termination
-    // that causes execution to start at a new instruction (per cpu cycle executed)
-    // @JEB - since processivities usually v. close to 1 it doesn't
-    // improve speed much to combine with "per instruction" block
-    if ( m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1 )
-    {
-      const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY.Get();
-      if ( ctx.GetRandom().P(1-processivity) ) 
-        Inst_Terminate(ctx);
-      if ( m_world->GetConfig().PROMOTER_MAX_INST.Get() && (promoter_inst_executed >= m_world->GetConfig().PROMOTER_MAX_INST.Get()) ) 
-        Inst_Terminate(ctx);
-    }
-    
+        
   } // Previous was executed once for each thread...
   
   // Kill creatures who have reached their max num of instructions executed
@@ -724,13 +726,16 @@
       
   if (m_world->GetConfig().PROMOTERS_ENABLED.Get())
   {
-    fp << "Promoters:";
-    for (int i=0; i<promoter_pos.GetSize(); i++)
+    fp << "Promoters: index=" << m_promoter_index << " offset=" << m_promoter_offset;
+    fp << " exe_inst=" << m_threads[m_cur_thread].GetPromoterInstExecuted();
+    fp << " regulation=0x" << setbase(16) << setfill('0') << setw(8) << m_promoter_regulation << endl;
+    for (int i=0; i<m_promoters.GetSize(); i++)
     {
-      fp << " " << promoter_pos[i] << "-" << (promoter_active[i] ? "on" : "off"); 
+      fp << setfill(' ') << setbase(10) << i << "(" << m_promoters[i].m_pos << "):";
+      fp << "Ox" << setbase(16) << setfill('0') << setw(8) << (m_promoters[i].m_bit_code ^ m_promoter_regulation) << " "; 
     }
-    fp << endl;
-    fp << "Instructions executed past promoter: " << promoter_inst_executed << endl;
+    fp << endl;    
+    fp << setfill(' ') << setbase(10) << endl;
   }    
   fp.flush();
 }
@@ -2594,6 +2599,13 @@
   return true;
 }
 
+bool cHardwareCPU::Inst_ReproSex(cAvidaContext& ctx)
+{
+  organism->GetPhenotype().SetDivideSex(true);
+  organism->GetPhenotype().SetCrossNum(1);
+  return Inst_Repro(ctx);
+}
+
 bool cHardwareCPU::Inst_TaskPutRepro(cAvidaContext& ctx)
 {
   // Do normal IO, but don't zero register
@@ -4278,56 +4290,188 @@
   return true;
 }
 
-// Move execution to a new promoter
+// Move the instruction ptr to the next active 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);
+  // Optionally,
+  // Reset the thread.
+  if (m_world->GetConfig().TERMINATION_RESETS.Get())
+  {
+    //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);
+    
+    //Setting this makes it harder to do things. You have to be modular.
+    organism->GetOrgInterface().ResetInputs(ctx);   // Re-randomize the inputs this organism sees
+    organism->ClearInput();                         // Also clear their input buffers, or they can still claim
+                                                    // rewards for numbers no longer in their environment!
+  }
+  
+  // Reset our count
+  m_threads[m_cur_thread].ResetPromoterInstExecuted();
+  m_advance_ip = false;
+  const int reg_used = REG_BX; // register to put chosen promoter code in, for now always BX
 
-  // We want to execute the promoter that we land on.
-  promoter_inst_executed = 0;
-  m_advance_ip = false;
+  // Search for an active promoter  
+  int start_offset = m_promoter_offset;
+  int start_index  = m_promoter_index;
   
-  //Setting this makes it harder to do things. You have to be modular.
-  organism->GetOrgInterface().ResetInputs(ctx);   // Re-randomize the inputs this organism sees
-  organism->ClearInput();                         // Also clear their input buffers, or they can still claim
-                                                  // rewards for numbers no longer in their environment!
-  
-  // Find the next active promoter
-  int started_search_pos = promoter_search_pos;
-  
-  while (promoter_pos.GetSize() > 0) // conditional infinite loop, breaks out
+  bool no_promoter_found = true;
+  if ( m_promoters.GetSize() > 0 ) 
   {
-    promoter_search_pos++;
-    promoter_search_pos %= promoter_active.GetSize();
-    if (promoter_active[promoter_search_pos]) break;
-    if (started_search_pos == promoter_search_pos) break;
-  } 
+    while( true )
+    {
+      // If the next promoter is active, then break out
+      NextPromoter();
+      if (IsActivePromoter()) 
+      {
+        no_promoter_found = false;
+        break;
+      }
+      
+      // If we just checked the promoter that we were originally on, then there
+      // are no active promoters.
+      if ( (start_offset == m_promoter_offset) && (start_index == m_promoter_index) ) break;
+
+      // If we originally were not on a promoter, then stop once we check the
+      // first promoter and an offset of zero
+      if (start_index == -1)
+      {
+          start_index = 0;
+      }
+    } 
+  }
   
-  //Can't find a promoter -- start at the beginning of the genome (or die! or sleep!)
-  if ((promoter_pos.GetSize() == 0) || ((promoter_search_pos == started_search_pos) && (!promoter_active[promoter_search_pos])))
+  if (no_promoter_found)
   {
-    IP().Set(0);
+    if ((m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 0) || (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2))
+    {
+      // Set defaults for when no active promoter is found
+      m_promoter_index = -1;
+      IP().Set(0);
+      GetRegister(reg_used) = 0;
+      
+      // @JEB HACK! -- All kinds of bad stuff happens if execution length is zero. For now:
+      if (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2) GetMemory().SetFlagExecuted(0);
+    }
+    // Death to organisms that refuse to use promoters!
+    else if (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 1)
+    {
+      organism->Die();
+    }
+    else
+    {
+      cout << "Unrecognized NO_ACTIVE_PROMOTER_EFFECT setting: " << m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() << endl;
+    }
   }
   else
   {
-    IP().Set(promoter_pos[promoter_search_pos]);
+    // We found an active match, offset to just after it.
+    // and put its bit code in BX for the organism to have
+      // cHeadCPU will do the mod genome size for us
+    IP().Set(m_promoters[m_promoter_index].m_pos + 1);
+    GetRegister(reg_used) = m_promoters[m_promoter_index].m_bit_code;
   }
-  
   return true;
 }
 
-// To be implemented...
+// Get a new regulation code (which is XOR'ed with promoter codes).
 bool cHardwareCPU::Inst_Regulate(cAvidaContext& ctx)
 {
+  const int reg_used = FindModifiedRegister(REG_BX);
+  m_promoter_regulation = GetRegister(reg_used);
   return true;
 }
 
+// Create a number from inst bit codes
+bool cHardwareCPU::Inst_Numberate(cAvidaContext& ctx)
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  
+  // advance the IP now, so that it rests on the beginning of our number
+  IP().Advance();
+  m_advance_ip = false;
+  
+  int num = Numberate(IP().GetPosition(), +1);
+  GetRegister(reg_used) = num;
+  return true;
+}
 
+// Move to the next promoter.
+void cHardwareCPU::NextPromoter()
+{
+  // Move promoter index, rolling over if necessary
+  m_promoter_index++;
+  if (m_promoter_index == m_promoters.GetSize())
+  {
+    m_promoter_index = 0;
+    
+    // Move offset, rolling over when there are not enough bits before we would have to wrap around left
+    m_promoter_offset+=m_world->GetConfig().PROMOTER_EXE_LENGTH.Get();
+    if (m_promoter_offset + m_world->GetConfig().PROMOTER_EXE_LENGTH.Get() >= cHardwareCPU::PROMOTER_CODE_SIZE)
+    {
+      m_promoter_offset = 0;
+    }
+  }
+}
+
+
+// Check whether the current promoter is active.
+bool cHardwareCPU::IsActivePromoter()
+{
+  assert( m_promoters.GetSize() != 0 );
+  int count = 0;
+  unsigned int code = m_promoters[m_promoter_index].m_bit_code ^ m_promoter_regulation;
+  for(int i=0; i<m_world->GetConfig().PROMOTER_EXE_LENGTH.Get(); i++)
+  {
+    int offset = m_promoter_offset + i;
+    offset %= cHardwareCPU::PROMOTER_CODE_SIZE;
+    int state = code >> offset;
+    count += (state & 1);
+  }
+
+  return (count >= m_world->GetConfig().PROMOTER_EXE_THRESHOLD.Get());
+}
+
+// Construct a promoter bit code from instruction bit codes
+int cHardwareCPU::Numberate(int _pos, int _dir)
+{  
+  int code_size = 0;
+  unsigned int code = 0;
+  int j = _pos;
+  j %= GetMemory().GetSize();
+  while (code_size < cHardwareCPU::PROMOTER_CODE_SIZE)
+  {
+    unsigned int inst_code = (unsigned int) GetInstSet().GetInstructionCode( (GetMemory())[j] );
+    // shift bits in, one by one ... excuse the counter pun
+    for (int code_on = 0; (code_size < cHardwareCPU::PROMOTER_CODE_SIZE) && (code_on < m_world->GetConfig().INST_CODE_LENGTH.Get()); code_on++)
+    {
+      if (_dir < 0)
+      {
+        code >>= 1; // shift first so we don't go one too far at the end
+        code += (1 << (cHardwareCPU::PROMOTER_CODE_SIZE - 1)) * (inst_code & 1);
+        inst_code >>= 1; 
+      }
+      else
+      {
+        code <<= 1; // shift first so we don't go one too far at the end;        
+        code += (inst_code >> (m_world->GetConfig().INST_CODE_LENGTH.Get() - 1)) & 1;
+        inst_code <<= 1; 
+      }
+      code_size++;
+    }
+    
+     // move back one inst
+    j += GetMemory().GetSize() + _dir;
+    j %= GetMemory().GetSize();
+
+  }
+  return code;
+}
+
+
 /*! Send a message to the organism that is currently faced by this cell,
 where the label field of sent message is from register ?BX?, and the data field
 is from register ~?BX?.
@@ -4343,7 +4487,6 @@
   return organism->SendMessage(ctx, msg);
 }
 
-
 /*! This method /attempts/ to retrieve a message -- It may not be possible, as in
 the case of an empty receive buffer.
 

Modified: branches/energy/source/cpu/cHardwareCPU.h
===================================================================
--- branches/energy/source/cpu/cHardwareCPU.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/cpu/cHardwareCPU.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -89,13 +89,14 @@
   static const int NUM_HEADS = nHardware::NUM_HEADS >= NUM_REGISTERS ? nHardware::NUM_HEADS : NUM_REGISTERS;
   enum tRegisters { REG_AX = 0, REG_BX, REG_CX, REG_DX, REG_EX, REG_FX };
   static const int NUM_NOPS = 3;
+  static const int PROMOTER_CODE_SIZE = sizeof(int) * 8; // Number of bits in promoter codes
   
   // --------  Data Structures  --------
   struct cLocalThread
   {
   private:
     int m_id;
-    
+    int m_promoter_inst_executed;
   public:
     int reg[NUM_REGISTERS];
     cHeadCPU heads[NUM_HEADS];
@@ -115,6 +116,9 @@
     void Reset(cHardwareBase* in_hardware, int in_id);
     int GetID() const { return m_id; }
     void SetID(int in_id) { m_id = in_id; }
+    int GetPromoterInstExecuted() { return m_promoter_inst_executed; }
+    void IncPromoterInstExecuted() { m_promoter_inst_executed++; }
+    void ResetPromoterInstExecuted() { m_promoter_inst_executed = 0; }
   };
 
     
@@ -137,13 +141,24 @@
   bool m_mal_active;         // Has an allocate occured since last divide?
   bool m_advance_ip;         // Should the IP advance after this instruction?
   bool m_executedmatchstrings;	// Have we already executed the match strings instruction?
+
+  // <-- Promoter model
+  int m_promoter_index;       //site to begin looking for the next active promoter from
+  int m_promoter_offset;      //bit offset when testing whether a promoter is on
+  int m_promoter_regulation;  //bit code that modifies current execution, via an XOR
   
-  // Promoter model
-  int promoter_search_pos;      //site to begin looking for the next active promoter from
-  int promoter_inst_executed;   //num inst executed since last termination
-  tArray<int> promoter_pos;     //positions with promoter instructions
-  tArray<bool> promoter_active; //whether each promoter is active (same size as promoter_pos)
-  
+  struct cPromoter 
+  {
+  public:
+    int m_pos;      //position within genome
+    int m_bit_code; //bit code of promoter
+  public:
+    cPromoter(int _pos = 0, int _bit_code = 0) { m_pos = _pos; m_bit_code = _bit_code; }
+    ~cPromoter() { ; }
+  };
+  tArray<cPromoter> m_promoters;
+  // Promoter Model -->
+
   bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
   
   // --------  Stack Manipulation...  --------
@@ -396,6 +411,7 @@
   bool Inst_InjectThread(cAvidaContext& ctx);
   bool Inst_Transposon(cAvidaContext& ctx);
   bool Inst_Repro(cAvidaContext& ctx);
+  bool Inst_ReproSex(cAvidaContext& ctx);
   bool Inst_TaskPutRepro(cAvidaContext& ctx);
   bool Inst_TaskPutResetInputsRepro(cAvidaContext& ctx);
   bool Inst_Sterilize(cAvidaContext& ctx);
@@ -536,7 +552,13 @@
   bool Inst_Promoter(cAvidaContext& ctx);
   bool Inst_Terminate(cAvidaContext& ctx);
   bool Inst_Regulate(cAvidaContext& ctx);
+  bool Inst_Numberate(cAvidaContext& ctx);
 
+    // Helper functions //
+  bool IsActivePromoter();
+  void NextPromoter();
+  int Numberate(int _pos, int _dir);
+
   //// Messaging ////
   bool Inst_SendMessage(cAvidaContext& ctx);
   bool Inst_RetrieveMessage(cAvidaContext& ctx);

Modified: branches/energy/source/cpu/cHardwareGX.cc
===================================================================
--- branches/energy/source/cpu/cHardwareGX.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/cpu/cHardwareGX.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -3626,13 +3626,13 @@
   
   bool ret = true;
   // Normal h-copy, unless a deletion occured
-  if (!organism->TestCopyDel(ctx)) {
+  if (!organism->TestDelMut(ctx)) {
       // Normal h-copy
     ret = Inst_HeadCopy(ctx);
   }
   
   // Divide Insertion
-  if (organism->TestCopyIns(ctx)) {
+  if (organism->TestInsMut(ctx)) {
     write.GetMemory().Insert(write.GetPosition(), GetInstSet().GetRandomInst(ctx));
     // Advance the write head;
     write++;

Modified: branches/energy/source/cpu/cTestCPU.cc
===================================================================
--- branches/energy/source/cpu/cTestCPU.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/cpu/cTestCPU.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -221,7 +221,7 @@
   
   organism.GetHardware().SetTrace(tracer);
   while (time_used < time_allocated && organism.GetHardware().GetMemory().GetSize() &&
-         organism.GetPhenotype().GetNumDivides() == 0)
+         organism.GetPhenotype().GetNumDivides() == 0 && !organism.IsDead())
   {
     time_used++;
     

Modified: branches/energy/source/main/cAvidaConfig.h
===================================================================
--- branches/energy/source/main/cAvidaConfig.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cAvidaConfig.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -465,14 +465,15 @@
 
   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_MAX_INST, int, 20, "Maximum number of instructions to execute before terminating.");
+  CONFIG_ADD_VAR(PROMOTER_INST_MAX, int, 0, "Maximum number of instructions to execute before terminating. 0 = off");
   CONFIG_ADD_VAR(PROMOTER_PROCESSIVITY, double, 1.0, "Chance of not terminating after each cpu cycle.");
   CONFIG_ADD_VAR(PROMOTER_PROCESSIVITY_INST, double, 1.0, "Chance of not terminating after 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. \nMax regulation = 2^(REGULATION_STRENGTH/REGULATION_DECAY_FRAC)");
+  CONFIG_ADD_VAR(TERMINATION_RESETS, int, 0, "Does termination reset the thread's state?");
+  CONFIG_ADD_VAR(NO_ACTIVE_PROMOTER_EFFECT, int, 0, "What happens when there are no active promoters?\n0 = Start execution at the beginning of the genome.\n1 = Kill the organism.\n2 = Stop the organism from executing any further instructions.");
+  CONFIG_ADD_VAR(PROMOTER_EXE_LENGTH, int, 4, "Length of promoter windows used to determine execution.");
+  CONFIG_ADD_VAR(PROMOTER_EXE_THRESHOLD, int, 3, "Minimum number of bits that must be set in a promoter window to allow execution.");
   CONFIG_ADD_VAR(INST_CODE_LENGTH, int, 4, "Instruction binary code length (number of bits)");
-  CONFIG_ADD_VAR(INST_CODE_DEFAULT_TYPE, int, 0, "Default value of instruction binary code value.\n0 = All zeros\n1 = Based of the instruction number");
+  CONFIG_ADD_VAR(INST_CODE_DEFAULT_TYPE, int, 0, "Default value of instruction binary code value.\n0 = All zeros\n1 = Based off the instruction number");
 
   CONFIG_ADD_GROUP(COLORS_GROUP, "Output colors for when data files are printed in HTML mode.\nThere are two sets of these; the first are for lineages,\nand the second are for mutation tests.");
   CONFIG_ADD_VAR(COLOR_DIFF, cString, "CCCCFF", "Color to flag stat that has changed since parent.");

Modified: branches/energy/source/main/cMutationRates.cc
===================================================================
--- branches/energy/source/main/cMutationRates.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cMutationRates.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -31,7 +31,6 @@
 
 void cMutationRates::Setup(cWorld* world)
 {
-  exec.point_mut_prob = world->GetConfig().POINT_MUT_PROB.Get();
   copy.mut_prob = world->GetConfig().COPY_MUT_PROB.Get();
   copy.slip_prob = world->GetConfig().COPY_SLIP_PROB.Get();
   divide.ins_prob = world->GetConfig().INS_MUT_PROB.Get();
@@ -52,7 +51,6 @@
 
 void cMutationRates::Clear()
 {
-  exec.point_mut_prob = 0.0;
   copy.mut_prob = 0.0;
   copy.slip_prob = 0.0;
   divide.ins_prob = 0.0;
@@ -73,7 +71,6 @@
 
 void cMutationRates::Copy(const cMutationRates& in_muts)
 {
-  exec.point_mut_prob = in_muts.exec.point_mut_prob;
   copy.mut_prob = in_muts.copy.mut_prob;
   copy.slip_prob = in_muts.copy.slip_prob;
   divide.ins_prob = in_muts.divide.ins_prob;

Modified: branches/energy/source/main/cMutationRates.h
===================================================================
--- branches/energy/source/main/cMutationRates.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cMutationRates.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -40,12 +40,6 @@
 private:
   // Mutations are divided up by when they occur...
 
-  // ...anytime during execution...
-  struct sExecMuts {
-    double point_mut_prob;
-  };
-  sExecMuts exec;
-
   // ...during an instruction copy...
   struct sCopyMuts {
     double mut_prob;
@@ -93,28 +87,26 @@
   void Clear();
   void Copy(const cMutationRates& in_muts);
 
-  bool TestPointMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(exec.point_mut_prob); }
-  bool TestCopyMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(copy.mut_prob); }
-  bool TestCopyIns(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.ins_prob); }
-  bool TestCopyDel(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.del_prob); }
-  bool TestCopySlip(cAvidaContext& ctx) const { return (copy.slip_prob == 0.0) ? 0 : ctx.GetRandom().P(copy.slip_prob); }
+  // Copy muts should always check if they are 0.0 before consulting the random number generator for performance
+  bool TestCopyMut(cAvidaContext& ctx) const { return (copy.mut_prob == 0.0) ? false : ctx.GetRandom().P(copy.mut_prob); }
+  bool TestCopySlip(cAvidaContext& ctx) const { return (copy.slip_prob == 0.0) ? false : ctx.GetRandom().P(copy.slip_prob); }
+  
+  bool TestInsMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.ins_prob); }
+  bool TestDelMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.del_prob); }
   bool TestDivideMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_mut_prob); }
   bool TestDivideIns(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_ins_prob); }
   bool TestDivideDel(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_del_prob); }
-  bool TestDivideSlip(cAvidaContext& ctx) const { return (divide.divide_slip_prob == 0.0) ? 0 : ctx.GetRandom().P(divide.divide_slip_prob); }
-  //bool TestDivideSlip(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_slip_prob); }
-    // @JEB The conditional just avoids calling for a random number to maintain consistency with past versions.
-    // It can be cleaned up in the future.
+  bool TestDivideSlip(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_slip_prob); }
   bool TestParentMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.parent_mut_prob); }
+  
   double DoMetaCopyMut(cAvidaContext& ctx) {
-    if (ctx.GetRandom().P(meta.copy_mut_prob) == false) return 1.0;
+    if (meta.copy_mut_prob == 0.0 || !ctx.GetRandom().P(meta.copy_mut_prob)) return 1.0;
     const double exp = ctx.GetRandom().GetRandNormal() * meta.standard_dev;
     const double change = pow(2.0, exp);
     copy.mut_prob *= change;
     return change;
   }
 
-  double GetPointMutProb() const     { return exec.point_mut_prob; }
   double GetCopyMutProb() const      { return copy.mut_prob; }
   double GetInsMutProb() const       { return divide.ins_prob; }
   double GetDelMutProb() const       { return divide.del_prob; }
@@ -130,7 +122,6 @@
   double GetMetaCopyMutProb() const  { return meta.copy_mut_prob; }
   double GetMetaStandardDev() const  { return meta.standard_dev; }
   
-  void SetPointMutProb(double in_prob)  { exec.point_mut_prob    = in_prob; }
   void SetCopyMutProb(double in_prob)   { copy.mut_prob          = in_prob; }
   void SetInsMutProb(double in_prob)    { divide.ins_prob        = in_prob; }
   void SetDelMutProb(double in_prob)    { divide.del_prob        = in_prob; }

Modified: branches/energy/source/main/cOrganism.cc
===================================================================
--- branches/energy/source/main/cOrganism.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cOrganism.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -69,6 +69,7 @@
   , m_max_executed(-1)
   , m_is_running(false)
   , m_is_sleeping(false)
+  , m_is_dead(false)
   , m_net(NULL)
   , m_msg(0)
 {

Modified: branches/energy/source/main/cOrganism.h
===================================================================
--- branches/energy/source/main/cOrganism.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cOrganism.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -121,6 +121,7 @@
   int m_max_executed;      // Max number of instruction executed before death.  
   bool m_is_running;       // Does this organism have the CPU?
   bool m_is_sleeping;      // Is this organisms sleeping?
+  bool m_is_dead;          // Is this organism dead?
   
   class cNetSupport
   {
@@ -181,6 +182,7 @@
   void SetSleeping(bool in_sleeping) { m_is_sleeping = in_sleeping; }
   bool IsSleeping() { return m_is_sleeping; }
   
+  bool IsDead() { return m_is_dead; }
   
   // --------  cOrgInterface Methods  --------
   cHardwareBase& GetHardware() { return *m_hardware; }
@@ -193,7 +195,7 @@
   int GetNextInput(int& in_input_pointer) { return m_interface->GetInputAt(in_input_pointer); } //@JEB alternate for GX
   tBuffer<int>& GetInputBuf() { return m_input_buf; }
   tBuffer<int>& GetOutputBuf() { return m_output_buf; }
-  void Die() { m_interface->Die(); }
+  void Die() { m_interface->Die(); m_is_dead = true; }
   void Kaboom(int dist) { m_interface->Kaboom(dist);}
   void SpawnDeme() { m_interface->SpawnDeme(); }
   int GetCellID() { return m_interface->GetCellID(); }
@@ -269,8 +271,8 @@
 
   // --------  Mutation Rate Convenience Methods  --------
   bool TestCopyMut(cAvidaContext& ctx) const { return m_mut_rates.TestCopyMut(ctx); }
-  bool TestCopyIns(cAvidaContext& ctx) const { return m_mut_rates.TestCopyIns(ctx); }
-  bool TestCopyDel(cAvidaContext& ctx) const { return m_mut_rates.TestCopyDel(ctx); }
+  bool TestInsMut(cAvidaContext& ctx) const { return m_mut_rates.TestInsMut(ctx); }
+  bool TestDelMut(cAvidaContext& ctx) const { return m_mut_rates.TestDelMut(ctx); }
   bool TestCopySlip(cAvidaContext& ctx) const { return m_mut_rates.TestCopySlip(ctx); }
   bool TestDivideMut(cAvidaContext& ctx) const { return m_mut_rates.TestDivideMut(ctx); }
   bool TestDivideIns(cAvidaContext& ctx) const { return m_mut_rates.TestDivideIns(ctx); }

Modified: branches/energy/source/main/cPlasticPhenotype.cc
===================================================================
--- branches/energy/source/main/cPlasticPhenotype.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cPlasticPhenotype.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -29,16 +29,13 @@
 
 bool cPlasticPhenotype::AddObservation( cCPUTestInfo& test_info )
 {
-  tArray<int> env_inputs = test_info.GetTestCPUInputs();
   cPhenotype& test_phenotype = test_info.GetTestPhenotype();
   if (test_phenotype == *this ){
     if (m_num_observations == 0){
-      m_env_inputs.Resize(1, env_inputs.GetSize());
+      m_env_inputs = test_info.GetTestCPUInputs();
       SetExecutedFlags(test_info);
       m_viable = test_info.IsViable();
-    } else
-      m_env_inputs.Resize(m_env_inputs.GetNumRows()+1, env_inputs.GetSize());
-    m_env_inputs[m_env_inputs.GetNumRows()-1] = env_inputs;
+    } 
     m_num_observations++;
     return true;
   }

Modified: branches/energy/source/main/cPlasticPhenotype.h
===================================================================
--- branches/energy/source/main/cPlasticPhenotype.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cPlasticPhenotype.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -36,8 +36,8 @@
 #include "cPhenotype.h"
 #endif
 
-#ifndef tMatrix_h
-#include "tMatrix.h"
+#ifndef tArray_h
+#include "tArray.h"
 #endif
 
 
@@ -48,7 +48,7 @@
   private:
     int m_num_observations;
     int m_num_trials;
-    tMatrix<int> m_env_inputs;
+    tArray<int> m_env_inputs;
     
     //Information retrieved from test_info not available in phenotype
     cString m_executed_flags;
@@ -70,7 +70,7 @@
     int GetNumObservations()      const { return m_num_observations; }
     int GetNumTrials()            const { return m_num_trials; }
     double GetFrequency()         const { return static_cast<double>(m_num_observations) / m_num_trials; }
-    tMatrix<int> GetEnvInputs()   const { return m_env_inputs; }
+    tArray<int> GetEnvInputs()   const { return m_env_inputs; }
     int IsViable()               const { return m_viable; }
     cString GetExecutedFlags()    const { return m_executed_flags; }
   

Modified: branches/energy/source/main/cPopulation.cc
===================================================================
--- branches/energy/source/main/cPopulation.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cPopulation.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -2057,7 +2057,7 @@
   cPopulationCell& cell = GetCell(cell_id);
   assert(cell.IsOccupied()); // Unoccupied cell getting processor time!
   cOrganism* cur_org = cell.GetOrganism();
-  cur_org->GetHardware().SingleProcess(ctx);
+  cell.GetHardware()->SingleProcess(ctx);
   if (cur_org->GetPhenotype().GetToDelete() == true) {
     delete cur_org;
   }

Modified: branches/energy/source/main/cPopulationCell.cc
===================================================================
--- branches/energy/source/main/cPopulationCell.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cPopulationCell.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -40,6 +40,7 @@
 cPopulationCell::cPopulationCell(const cPopulationCell& in_cell)
   : m_world(in_cell.m_world)
   , m_organism(in_cell.m_organism)
+  , m_hardware(in_cell.m_hardware)
   , m_inputs(in_cell.m_inputs)
   , m_cell_id(in_cell.m_cell_id)
   , m_deme_id(in_cell.m_deme_id)
@@ -59,6 +60,7 @@
 {
   m_world = in_cell.m_world;
   m_organism = in_cell.m_organism;
+  m_hardware = in_cell.m_hardware;
   m_inputs = in_cell.m_inputs;
   m_cell_id = in_cell.m_cell_id;
   m_deme_id = in_cell.m_deme_id;
@@ -167,6 +169,7 @@
 
   // Adjust this cell's attributes to account for the new organism.
   m_organism = new_org;
+  m_hardware = &new_org->GetHardware();
   m_organism_count++;
 
   // Adjust the organism's attributes to match this cell.
@@ -194,6 +197,7 @@
     m_world->GetPopulation().GetDeme(m_deme_id).GiveBackCellEnergy(m_cell_id, m_organism->GetPhenotype().GetStoredEnergy() * m_world->GetConfig().FRAC_ENERGY_TRANSFER.Get());
   }
   m_organism = NULL;
+  m_hardware = NULL;
   return out_organism;
 }
 

Modified: branches/energy/source/main/cPopulationCell.h
===================================================================
--- branches/energy/source/main/cPopulationCell.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cPopulationCell.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -38,6 +38,7 @@
 #include "tList.h"
 #endif
 
+class cHardwareBase;
 class cPopulation;
 class cOrganism;
 class cPopulationCell;
@@ -50,6 +51,7 @@
 private:
   cWorld* m_world;
   cOrganism* m_organism;                    // The occupent of this cell.
+  cHardwareBase* m_hardware;
   tList<cPopulationCell> m_connections;  // A list of neighboring cells.
   cMutationRates* m_mut_rates;           // Mutation rates at this cell.
   tArray<int> m_inputs;                 // Environmental Inputs...
@@ -69,7 +71,7 @@
 
   
 public:
-  cPopulationCell() : m_world(NULL), m_organism(NULL), m_mut_rates(NULL), m_organism_count(0) { ; }
+  cPopulationCell() : m_world(NULL), m_organism(NULL), m_hardware(NULL), m_mut_rates(NULL), m_organism_count(0) { ; }
   cPopulationCell(const cPopulationCell& in_cell);
   ~cPopulationCell() { delete m_mut_rates; }
 
@@ -80,6 +82,7 @@
   void Rotate(cPopulationCell& new_facing);
 
   inline cOrganism* GetOrganism() const { return m_organism; }
+  inline cHardwareBase* GetHardware() const { return m_hardware; }
   inline tList<cPopulationCell>& ConnectionList() { return m_connections; }
   inline cPopulationCell& GetCellFaced() { return *(m_connections.GetFirst()); }
   int GetFacing();  // Returns the facing of this cell.

Modified: branches/energy/source/main/cTaskLib.cc
===================================================================
--- branches/energy/source/main/cTaskLib.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/main/cTaskLib.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -2168,7 +2168,6 @@
   // if the org hasn't output yet enough numbers, just return without completing any tasks
   if (ctx.GetOutputBuffer().GetNumStored() < ctx.GetOutputBuffer().GetCapacity()) return 0;
 
-
   double quality = 0.0;
   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
 
@@ -2287,6 +2286,21 @@
       break;
     }
 
+    case 12:
+    {
+      vars[0] = vars[0]*.9+.1;
+	Fx = vars[0];
+	break;
+    }
+
+    case 13:
+    {
+      vars[0] = vars[0]*.9+.1;
+      vars[1] = vars[1]*5;
+      Fx = (1+vars[1])/vars[0];
+      break;
+    }
+
     default:
       quality = .001;
   }

Modified: branches/energy/source/script/ASTree.h
===================================================================
--- branches/energy/source/script/ASTree.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/script/ASTree.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -446,18 +446,24 @@
   tManagedPointerArray<cString> m_nodes;
   bool m_last_wild;
   bool m_last_named;
+  cASTNode* m_expr;
   
 public:
-  cASTUnpackTarget() : m_last_wild(false), m_last_named(false) { ; }
-  ~cASTUnpackTarget() { ; }
+  cASTUnpackTarget() : m_last_wild(false), m_last_named(false), m_expr(NULL) { ; }
+  ~cASTUnpackTarget() { delete m_expr; }
   
   inline void AddVar(const cString& name) { m_nodes.Push(name); }
   inline int GetSize() const { return m_nodes.GetSize(); }
   inline const cString& GetVar(int idx) const { return m_nodes[idx]; }
   
+  inline bool IsLastNamed() const { return m_last_named; }
+  inline bool IsLastWild() const { return m_last_wild; }
+  
   inline void SetLastNamed() { m_last_wild = true; m_last_named = true; }
   inline void SetLastWild() { m_last_wild = true; m_last_named = false; }
   
+  cASTNode* GetExpression() const { return m_expr; }
+  void SetExpression(cASTNode* expr) { delete m_expr; m_expr = expr; }
   
   void Accept(cASTVisitor& visitor);
 };

Modified: branches/energy/source/script/cASTDumpVisitor.cc
===================================================================
--- branches/energy/source/script/cASTDumpVisitor.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/script/cASTDumpVisitor.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -388,5 +388,38 @@
 
 void cASTDumpVisitor::visitUnpackTarget(cASTUnpackTarget& node)
 {
-  // @todo
+  m_depth++;
+  
+  // Array unpack portion
+  indent();
+  cout << "@{";
+  m_depth++;
+  
+  for (int i = 0; i < node.GetSize(); i++) {
+    cout << endl;
+    indent();
+    cout << node.GetVar(i);
+  }
+  if (node.IsLastNamed()) {
+    cout << "..";
+  } else if (node.IsLastWild()) {
+    cout << endl;
+    indent();
+    cout << "..";
+  }
+  cout << endl;
+  m_depth--;
+  indent();
+  cout << "}" << endl;
+  
+  // Equals
+  m_depth--;
+  indent();
+  cout << "=" << endl;
+  m_depth++;
+  
+  // Expression portion
+  node.GetExpression()->Accept(*this);
+  
+  m_depth--;
 }

Modified: branches/energy/source/script/cParser.cc
===================================================================
--- branches/energy/source/script/cParser.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/script/cParser.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -291,6 +291,12 @@
       PARSE_UNEXPECT();
     }
   }
+  
+  if (nextToken() != TOKEN(ARR_CLOSE)) PARSE_UNEXPECT();
+  if (nextToken() != TOKEN(ASSIGN)) PARSE_UNEXPECT();
+  nextToken(); // consume '='
+  
+  (*ut).SetExpression(parseExpression());
 
   return ut.Release();
 }

Modified: branches/energy/source/tools/cMerit.cc
===================================================================
--- branches/energy/source/tools/cMerit.cc	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/tools/cMerit.cc	2007-09-07 18:02:28 UTC (rev 2069)
@@ -16,21 +16,19 @@
 
 void cMerit::UpdateValue(double in_value)
 {
-  const int max_bits = sizeof(unsigned int)*8;
-  static double mult[max_bits];
-  static bool mult_initilalized = false;
+  static const int max_bits = sizeof(unsigned int) * 8;
+  struct sExponentMultiplier
+  {
+    double mult[max_bits + 1];
+    sExponentMultiplier() { for (int i = 0; i <= max_bits; i++) mult[i] = pow(2.0, i - 1); }
+  };
+  static sExponentMultiplier exp;
 
+  
   // Do not allow negative merits. If less than 1, set to 0.
   if (in_value < 1.0) in_value = 0.0;
 
-  // Initilize multipliers only once
-  if (mult_initilalized == false) {
-    mult_initilalized = true;
-    for (int i = 0; i < max_bits; ++i) mult[i] = pow(2.0, i);
-  }
-
   value = in_value;
-
   double mant = frexp(value, &bits);
 
   if (bits > max_bits)
@@ -38,7 +36,7 @@
   else
     offset = 0;
 
-  base = static_cast<unsigned int>(mant * mult[bits-offset-1] * 2);
+  base = static_cast<unsigned int>(mant * exp.mult[bits - offset] * 2.0);
 }
 
 

Modified: branches/energy/source/tools/cMerit.h
===================================================================
--- branches/energy/source/tools/cMerit.h	2007-09-07 17:38:22 UTC (rev 2068)
+++ branches/energy/source/tools/cMerit.h	2007-09-07 18:02:28 UTC (rev 2069)
@@ -98,7 +98,7 @@
 
   static double EnergyToMerit(const double orgEnergy, cWorld* m_world);
 
-  std::ostream& BinaryPrint(std::ostream& os = std::cout) const ;
+  std::ostream& BinaryPrint(std::ostream& os = std::cout) const;
 };
 
 




More information about the Avida-cvs mailing list