[Avida-cvs] [Avida2-svn] r290 - in branches/brysonda: documentation/content/using source/cpu source/event source/main source/support source/testsuites/functional_testsuites/default.md5sum source/testsuites/functional_testsuites/default.tail source/testsuites/functional_testsuites/default.tail.disabled source/testsuites/functional_testsuites/tedious.tail.disabled source/tools source/viewers

brysonda@myxo.css.msu.edu brysonda at myxo.css.msu.edu
Thu Aug 25 11:43:57 PDT 2005


Author: brysonda
Date: 2005-08-25 14:43:56 -0400 (Thu, 25 Aug 2005)
New Revision: 290

Modified:
   branches/brysonda/documentation/content/using/analyze_mode.html
   branches/brysonda/source/cpu/code_label.hh
   branches/brysonda/source/cpu/hardware_4stack.cc
   branches/brysonda/source/cpu/hardware_cpu.cc
   branches/brysonda/source/cpu/hardware_cpu.hh
   branches/brysonda/source/cpu/hardware_smt.cc
   branches/brysonda/source/cpu/hardware_smt.h
   branches/brysonda/source/cpu/hardware_smt_constants.h
   branches/brysonda/source/cpu/head_multi_mem.hh
   branches/brysonda/source/event/event_factory_manager.cc
   branches/brysonda/source/event/event_factory_manager.hh
   branches/brysonda/source/event/population_event_factory.hh
   branches/brysonda/source/main/analyze.cc
   branches/brysonda/source/main/analyze.hh
   branches/brysonda/source/main/analyze_genotype.cc
   branches/brysonda/source/main/analyze_genotype.hh
   branches/brysonda/source/main/birth_chamber.cc
   branches/brysonda/source/main/birth_chamber.hh
   branches/brysonda/source/main/config.cc
   branches/brysonda/source/main/genotype_control.cc
   branches/brysonda/source/main/phenotype.cc
   branches/brysonda/source/main/phenotype.hh
   branches/brysonda/source/main/primitive.cc
   branches/brysonda/source/support/genesis
   branches/brysonda/source/testsuites/functional_testsuites/default.md5sum/genesis
   branches/brysonda/source/testsuites/functional_testsuites/default.tail.disabled/genesis
   branches/brysonda/source/testsuites/functional_testsuites/default.tail/genesis
   branches/brysonda/source/testsuites/functional_testsuites/tedious.tail.disabled/genesis
   branches/brysonda/source/tools/tDictionary.hh
   branches/brysonda/source/tools/tObjectFactory.h
   branches/brysonda/source/viewers/zoom_screen.cc
Log:
merge in r289 from trunk

Modified: branches/brysonda/documentation/content/using/analyze_mode.html
===================================================================
--- branches/brysonda/documentation/content/using/analyze_mode.html	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/documentation/content/using/analyze_mode.html	2005-08-25 18:43:56 UTC (rev 290)
@@ -139,10 +139,11 @@
         processing done before interactive mode starts.  You can type "quit"
         at any point to continue with the normal processing of the file.
 <tr><td><b>DEBUG [<font color="#0000AA">message</font>] </b><br>
-    	This is an "echo" command that will print a message (its arguments)
-        on the screen.  If there are any variables (see below) in the message,
-        they will be translated before printing, so this is a good way of
-        debugging your programs.
+        <b>ECHO [<font color="#0000AA">message</font>] </b><br>
+    	These are both "echo" commands that will print a message (the
+        arguments given) onto the screen.  If there are any variables (see
+        below) in the message, they will be translated before printing, so
+        this is a good way of debugging your programs.
 </table>
 
 <p>

Modified: branches/brysonda/source/cpu/code_label.hh
===================================================================
--- branches/brysonda/source/cpu/code_label.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/cpu/code_label.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -77,14 +77,8 @@
 
 void cCodeLabel::Rotate(const int rot, const int base)
 {
-  //for (int i = 0; i < size; i++) {
-  //  nop_sequence[i] += rot;
-  //  if (nop_sequence[i] == 3) nop_sequence[i]++; //IGNORING NOP-D FOR NOW!
-  //  if (nop_sequence[i] >= base) nop_sequence[i] -= base;
-  //}
   for (int i = 0; i < size; i++) {
     nop_sequence[i] += rot;
-    //if (nop_sequence[i] == 3) nop_sequence[i]++; //IGNORING NOP-D FOR NOW!
     if (nop_sequence[i] >= base) nop_sequence[i] -= base;
   }
 }

Modified: branches/brysonda/source/cpu/hardware_4stack.cc
===================================================================
--- branches/brysonda/source/cpu/hardware_4stack.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/cpu/hardware_4stack.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -227,14 +227,6 @@
     functions
   );
 
-  cout <<
-  "<cHardware4Stack::initInstLib> debug: important post-init values:" <<endl<<
-  " --- GetSize(): " << inst_lib->GetSize() <<endl<<
-  " --- GetNumNops(): " << inst_lib->GetNumNops() <<endl<<
-  " --- GetName(last): " <<
-  inst_lib->GetName(inst_lib->GetSize() - 1) <<endl<<
-  endl;
-
   return inst_lib;
 }
 

Modified: branches/brysonda/source/cpu/hardware_cpu.cc
===================================================================
--- branches/brysonda/source/cpu/hardware_cpu.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/cpu/hardware_cpu.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -246,6 +246,8 @@
 		  "Copy the position of the ?IP? head into CX"),
     cInstEntryCPU("if-label",  &cHardwareCPU::Inst_IfLabel, true,
 		  "Execute next if we copied complement of attached label"),
+    cInstEntryCPU("if-label2",  &cHardwareCPU::Inst_IfLabel2, true,
+		  "If copied label compl., exec next inst; else SKIP W/NOPS"),
     cInstEntryCPU("set-flow",  &cHardwareCPU::Inst_SetFlow, true,
 		  "Set flow-head to position in ?CX?"),
 
@@ -265,6 +267,7 @@
     cInstEntryCPU("div-sex",    &cHardwareCPU::Inst_HeadDivideSex),
     cInstEntryCPU("div-asex",   &cHardwareCPU::Inst_HeadDivideAsex),
     cInstEntryCPU("div-asex-w",   &cHardwareCPU::Inst_HeadDivideAsexWait),
+    cInstEntryCPU("div-sex-MS",   &cHardwareCPU::Inst_HeadDivideMateSelect),
 
     cInstEntryCPU("h-divide1",      &cHardwareCPU::Inst_HeadDivide1),
     cInstEntryCPU("h-divide2",      &cHardwareCPU::Inst_HeadDivide2),
@@ -357,14 +360,6 @@
     functions
   );
 
-  cout <<
-  "<cHardwareCPU::initInstLib> debug: important post-init values:" <<endl<<
-  " --- GetSize(): " << inst_lib->GetSize() <<endl<<
-  " --- GetNumNops(): " << inst_lib->GetNumNops() <<endl<<
-  " --- GetName(last): " <<
-  inst_lib->GetName(inst_lib->GetSize() - 1) <<endl<<
-  endl;
-
   return inst_lib;
 }
 
@@ -3202,6 +3197,19 @@
   return true;
 }
 
+// This is a variation on IfLabel that will skip the next command if the "if"
+// is false, but it will also skip all nops following that command.
+bool cHardwareCPU::Inst_IfLabel2()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+  if (GetLabel() != GetReadLabel()) {
+    IP().Advance();
+    if (inst_set->IsNop( IP().GetNextInst() ))  IP().Advance();
+  }
+  return true;
+}
+
 bool cHardwareCPU::Inst_HeadDivideMut(double mut_multiplier)
 {
   AdjustHeads();
@@ -3241,6 +3249,23 @@
   return Inst_HeadDivide(); 
 }
 
+bool cHardwareCPU::Inst_HeadDivideMateSelect()  
+{ 
+  // Take the label that follows this divide and use it as the ID for which
+  // other organisms this one is willing to mate with.
+  ReadLabel();
+  organism->GetPhenotype().SetMateSelectID( GetLabel().AsInt(NUM_NOPS) );
+
+//   int mate_id = GetLabel().AsInt(NUM_NOPS);
+//   if (mate_id > 0) cout << mate_id << " "
+// 			<< GetLabel().AsString() << endl;
+
+  // Proceed as normal with the rest of mate selection.
+  organism->GetPhenotype().SetDivideSex(true);
+  organism->GetPhenotype().SetCrossNum(1);
+  return Inst_HeadDivide(); 
+}
+
 bool cHardwareCPU::Inst_HeadDivide1()  { return Inst_HeadDivideMut(1); }
 bool cHardwareCPU::Inst_HeadDivide2()  { return Inst_HeadDivideMut(2); }
 bool cHardwareCPU::Inst_HeadDivide3()  { return Inst_HeadDivideMut(3); }

Modified: branches/brysonda/source/cpu/hardware_cpu.hh
===================================================================
--- branches/brysonda/source/cpu/hardware_cpu.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/cpu/hardware_cpu.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -412,6 +412,7 @@
   bool Inst_JumpHead();
   bool Inst_GetHead();
   bool Inst_IfLabel();
+  bool Inst_IfLabel2();
   bool Inst_HeadDivide();
   bool Inst_HeadRead();
   bool Inst_HeadWrite();
@@ -432,6 +433,7 @@
   bool Inst_HeadDivideSex();
   bool Inst_HeadDivideAsex();
   bool Inst_HeadDivideAsexWait();
+  bool Inst_HeadDivideMateSelect();
 
   bool Inst_HeadDivide1();
   bool Inst_HeadDivide2();

Modified: branches/brysonda/source/cpu/hardware_smt.cc
===================================================================
--- branches/brysonda/source/cpu/hardware_smt.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/cpu/hardware_smt.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -161,19 +161,11 @@
   tInstLib<cHardwareSMT::tMethod> *inst_lib =
     new tInstLib<cHardwareSMT::tMethod>(n_size, f_size, n_names, f_names, nop_mods, functions, error, def);
 	
-  cout <<
-		"<cHardwareSMT::initInstLib> debug: important post-init values:" <<endl<<
-		" --- GetSize(): " << inst_lib->GetSize() <<endl<<
-		" --- GetNumNops(): " << inst_lib->GetNumNops() <<endl<<
-		" --- GetName(last): " <<
-		inst_lib->GetName(inst_lib->GetSize() - 1) <<endl<<
-		endl;
-	
   return inst_lib;
 }
 
 cHardwareSMT::cHardwareSMT(cOrganism* in_organism, cInstSet* in_inst_set)
-  : cHardwareBase(in_organism, in_inst_set), m_mem_array(nHardwareSMT::NUM_MEMORY_SPACES)
+  : cHardwareBase(in_organism, in_inst_set), m_mem_array(1)
 {
   m_functions = s_inst_slib->GetFunctions();
 	
@@ -215,11 +207,8 @@
 void cHardwareSMT::Reset()
 {
   // Setup the memory...
-  for (int i = 1; i < nHardwareSMT::NUM_MEMORY_SPACES; i++) {
-		m_mem_array[i].Resize(1);
-		GetMemory(i) = cGenome(ConvertToInstruction(i)); 
-  }
-	
+  m_mem_array.Resize(1);
+  
   // We want to reset to have a single thread.
   m_threads.Resize(1);
 	
@@ -396,7 +385,7 @@
 {
   bool result = true;
 	
-  for(int i = 0 ; i < nHardwareSMT::NUM_MEMORY_SPACES; i++) {
+  for(int i = 0 ; i < m_mem_array.GetSize(); i++) {
     if (!m_mem_array[i].OK()) result = false;
   }
 	
@@ -843,7 +832,7 @@
   
 	// FIND THE FIRST EMPTY MEMORY SPACE
   int target_mem_space;
-  for (target_mem_space = 0; target_mem_space < nHardwareSMT::NUM_MEMORY_SPACES; target_mem_space++)
+  for (target_mem_space = 0; target_mem_space < m_mem_array.GetSize(); target_mem_space++)
 	{
 		if(isEmpty(target_mem_space))
 		{
@@ -851,12 +840,12 @@
 		}
 	}
   
-  if (target_mem_space == nHardwareSMT::NUM_MEMORY_SPACES)
+  if (target_mem_space == m_mem_array.GetSize())
 	{
 		return false;
 	}
 	
-  assert(target_mem_space >=0 && target_mem_space < nHardwareSMT::NUM_MEMORY_SPACES);
+  assert(target_mem_space >=0 && target_mem_space < m_mem_array.GetSize());
   
   if(ForkThread()) {
     // Inject the new code
@@ -1090,7 +1079,7 @@
 void cHardwareSMT::ReadLabel(int max_size)
 {
   int count = 0;
-  cHeadMultiMem * inst_ptr = &( IP() );
+  cHeadMultiMem* inst_ptr = &( IP() );
 	
   GetLabel().Clear();
 	
@@ -1778,24 +1767,27 @@
 //13 
 bool cHardwareSMT::Inst_SetMemory()   // Allocate maximal more
 {
+  ReadLabel();
   int mem_space_used = FindModifiedStack(-1);
   
-  if(mem_space_used==-1) {
+  if (GetLabel().GetSize() == 0) {
+    GetHead(HEAD_FLOW).Set(0, 0);
+  } else {
+    int mem_space_used = FindMemorySpaceLabel(-1);
+    
+    if (mem_space_used != -1) {
+      
+    } else {
+      
+    }
+    
     mem_space_used = FindFirstEmpty();
     if(mem_space_used==-1)
       return false;
+    GetHead(HEAD_FLOW).Set(0, mem_space_used);
   }
   
-  GetHead(HEAD_FLOW).Set(0, mem_space_used);
   return true;
-  
-  //const int cur_size = GetMemory(0).GetSize();
-  //const int alloc_size = Min((int) (cConfig::GetChildSizeRange() * cur_size),
-  //			     MAX_CREATURE_SIZE - cur_size);
-  //if( Allocate_Main(alloc_size) ) {
-  //  Stack(STACK_AX).Push(cur_size);
-  //  return true;
-  //} else return false;
 }
 
 //14
@@ -2131,11 +2123,11 @@
   bool OK=true;
   const int current_mem_space = IP().GetMemSpace();
 	
-  for(int x = 1; x < nHardwareSMT::NUM_MEMORY_SPACES; x++)
+  for(int x = 1; x < m_mem_array.GetSize(); x++)
 	{
 		OK=true;
 		
-		int index = (current_mem_space+x) % nHardwareSMT::NUM_MEMORY_SPACES;
+		int index = (current_mem_space + x) % m_mem_array.GetSize();
 		
 		for(int y=0; y<GetMemory(index).GetSize() && OK; y++)
 		{

Modified: branches/brysonda/source/cpu/hardware_smt.h
===================================================================
--- branches/brysonda/source/cpu/hardware_smt.h	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/cpu/hardware_smt.h	2005-08-25 18:43:56 UTC (rev 290)
@@ -101,8 +101,8 @@
   cHardwareSMT(cOrganism * in_organism, cInstSet * in_inst_set);
   explicit cHardwareSMT(const cHardwareSMT &);
   ~cHardwareSMT() { ; }
-  void Recycle(cOrganism * new_organism, cInstSet * in_inst_set);
-  static cInstLibBase *GetInstLib();
+  void Recycle(cOrganism* new_organism, cInstSet * in_inst_set);
+  static cInstLibBase* GetInstLib();
   static cString GetDefaultInstFilename() { return "inst_lib.4stack"; }
   static void WriteDefaultInstSet() { ; }
 	
@@ -171,14 +171,14 @@
   const cCPUMemory & GetMemory() const { return m_mem_array[0]; }
   cCPUMemory & cHardwareSMT::GetMemory(int mem_space)
   {
-    if(mem_space >= nHardwareSMT::NUM_MEMORY_SPACES)
-      mem_space %= nHardwareSMT::NUM_MEMORY_SPACES;
+    if(mem_space >= m_mem_array.GetSize())
+      mem_space %= m_mem_array.GetSize();
     return m_mem_array[mem_space];
   }
   const cCPUMemory & cHardwareSMT::GetMemory(int mem_space) const
   {
-    if(mem_space >= nHardwareSMT::NUM_MEMORY_SPACES)
-      mem_space %= nHardwareSMT::NUM_MEMORY_SPACES;
+    if(mem_space >= m_mem_array.GetSize())
+      mem_space %= m_mem_array.GetSize();
     return m_mem_array[mem_space];
   }
   
@@ -249,6 +249,7 @@
   int FindModifiedStack(int default_stack);
   int FindModifiedHead(int default_head);
   int FindComplementStack(int base_stack);
+  int FindMemorySpaceLabel(int default_mem);
 	
   void Fault(int fault_loc, int fault_type, cString fault_desc=""); 
   bool Allocate_Necro(const int new_size);

Modified: branches/brysonda/source/cpu/hardware_smt_constants.h
===================================================================
--- branches/brysonda/source/cpu/hardware_smt_constants.h	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/cpu/hardware_smt_constants.h	2005-08-25 18:43:56 UTC (rev 290)
@@ -20,7 +20,6 @@
   enum tStacks { STACK_AX = 0, STACK_BX, STACK_CX, STACK_DX };
   
   static const int NUM_NOPS = 4;
-  static const int NUM_MEMORY_SPACES = 4; 
 }
 
 #endif

Modified: branches/brysonda/source/cpu/head_multi_mem.hh
===================================================================
--- branches/brysonda/source/cpu/head_multi_mem.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/cpu/head_multi_mem.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -46,7 +46,7 @@
   void SetInst(const cInstruction & value);
   void InsertInst(const cInstruction & in_char);
   void RemoveInst();
-  const cInstruction & GetNextInst();
+  const cInstruction& GetNextInst();
 
   bool & FlagCopied();
   bool & FlagMutated();

Modified: branches/brysonda/source/event/event_factory_manager.cc
===================================================================
--- branches/brysonda/source/event/event_factory_manager.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/event/event_factory_manager.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -9,6 +9,8 @@
 #include "event.hh"
 #endif
 
+#include <iostream>
+
 using namespace std;
 
 
@@ -21,10 +23,8 @@
 }
 
 cEventFactoryManager::~cEventFactoryManager(){
-  vector<tObjectFactory<cEvent ()>*>::iterator it = m_factory_list.begin();
-  
-  for( ; it != m_factory_list.end(); it++ )
-    delete *it;
+  tListIterator<tObjectFactory<cEvent ()> > it(m_factory_list);  
+  while (it.Next() != NULL) delete it.Get();
 }
 
 
@@ -35,22 +35,20 @@
   cEvent* event = NULL;
   
   // factory_id < 0 => send to all factories
-  if( factory_id < 0 ){
-    vector<tObjectFactory<cEvent ()>*>::iterator it;
-    for( it = m_factory_list.begin(); it != m_factory_list.end(); it++ ){
-      if( *it != NULL )
-        event = (*it)->Create(name);
-      if ( event != NULL ) // if we have found one factory that can create the
-                           //                    event we want we stop.
-        break;
+  if( factory_id < 0 ) {
+    tListIterator<tObjectFactory<cEvent ()> > it(m_factory_list);
+    while (it.Next() != NULL) {
+      event = (it.Get())->Create(name);
+      
+      // if we have found one factory that can create the event we want we stop.
+      if (event != NULL) break;
     }
   }
   else{
     // send to particular factory
-    if ( factory_id >= static_cast<int>( m_factory_list.size() ) )
-      return NULL;
-    if( m_factory_list[factory_id] != NULL )
-      event = m_factory_list[factory_id]->Create(name);
+    if (factory_id >= m_factory_list.GetSize()) return NULL;
+    if( m_factory_list.GetPos(factory_id) != NULL )
+      event = m_factory_list.GetPos(factory_id)->Create(name);
   }
   
   event->Configure(args);
@@ -61,11 +59,25 @@
 int cEventFactoryManager::AddFactory(tObjectFactory<cEvent ()>* factory)
 {
   assert( factory != NULL );
-  m_factory_list.push_back(factory);
+  m_factory_list.Push(factory);
   
-  int id = m_factory_list.size();
+  int id = m_factory_list.GetSize();
   factory->SetFactoryId(id);
   
   return id;
 }
 
+void cEventFactoryManager::PrintAllEventDescriptions()
+{
+  tListIterator<tObjectFactory<cEvent ()> > it(m_factory_list);
+  while (it.Next() != NULL) {
+    tList<cEvent> events;
+    it.Get()->CreateAll(events);
+    
+    tListIterator<cEvent> events_it(events);
+    while (events_it.Next() != NULL) {
+      cout << events_it.Get()->GetDescription() << endl;
+      delete events_it.Get();
+    }
+  }
+}
\ No newline at end of file

Modified: branches/brysonda/source/event/event_factory_manager.hh
===================================================================
--- branches/brysonda/source/event/event_factory_manager.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/event/event_factory_manager.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -8,7 +8,9 @@
 #ifndef EVENT_FACTORY_MANAGER_HH
 #define EVENT_FACTORY_MANAGER_HH
 
-#include <vector>
+#ifndef TLIST_HH
+#include "tList.hh"
+#endif
 
 #ifndef TOBJECTFACTORY_H
 #include "tObjectFactory.h"
@@ -31,7 +33,7 @@
 
 class cEventFactoryManager {
 private:
-  std::vector<tObjectFactory<cEvent ()>*> m_factory_list;
+  tList< tObjectFactory<cEvent ()> > m_factory_list;
 
   // not implemented, prevents inadvertent wrong instantiation
   cEventFactoryManager( const cEventFactoryManager & );
@@ -48,6 +50,8 @@
    * sends it to the particular factory requested.
    **/
   cEvent* ConstructEvent(const cString name, const cString & args, int factory_id = -1);
+  
+  void PrintAllEventDescriptions();
 };
 
 #endif

Modified: branches/brysonda/source/event/population_event_factory.hh
===================================================================
--- branches/brysonda/source/event/population_event_factory.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/event/population_event_factory.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -31,8 +31,6 @@
     cPopulationEvent* event = static_cast<cPopulationEvent*>(this->tObjectFactory<cEvent ()>::Create(key));
     if( event != NULL ){
       event->SetFactoryId( GetFactoryId() );
-      
-      assert( m_population != NULL );
       event->SetPopulation( m_population );
     }
     return event;

Modified: branches/brysonda/source/main/analyze.cc
===================================================================
--- branches/brysonda/source/main/analyze.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/analyze.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -9,6 +9,7 @@
 #include <sstream>
 #include <string>
 #include <queue>
+#include <stack>
 
 #include "analyze.hh"
 
@@ -637,7 +638,7 @@
     
     // Calculate entropy ...
     double this_entropy = 0.0;
-    this_entropy -= (1-mut_rate)*log(static_cast<double>(1-mut_rate))/log(static_cast<double>(num_insts));
+    this_entropy -= (1.0 - mut_rate) * log(1.0 - mut_rate) / log(static_cast<double>(num_insts));
     for (int i = 0; i < num_insts; i ++) {
       if (i == parent_inst) { continue; }
       prob[i] = prob[i] * mut_rate;
@@ -1721,7 +1722,7 @@
     fp << "</table>" << endl
     << "</center>" << endl;
   }
-  }
+}
 
 void cAnalyze::CommandDetailAverage_Body(ostream & fp, int num_outputs,
                                          tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it)
@@ -2063,9 +2064,180 @@
     fp << "</table>" << endl
     << "</center>" << endl;
   }
+}
+
+void cAnalyze::CommandHistogram(cString cur_string)
+{
+  if (verbose == true) cout << "Histogram batch " << cur_batch << endl;
+  else cout << "Histograming..." << endl;
+  
+  // Load in the variables...
+  cString filename("histogram.dat");
+  if (cur_string.GetSize() != 0) filename = cur_string.PopWord();
+  
+  // Construct a linked list of details needed...
+  tList< tDataEntryCommand<cAnalyzeGenotype> > output_list;
+  tListIterator< tDataEntryCommand<cAnalyzeGenotype> > output_it(output_list);
+  LoadGenotypeDataList(cur_string, output_list);
+  
+  // Determine the file type...
+  int file_type = FILE_TYPE_TEXT;
+  cString file_extension(filename);
+  while (file_extension.Find('.') != -1) file_extension.Pop('.');
+  if (file_extension == "html") file_type = FILE_TYPE_HTML;
+  
+  // Setup the file...
+  if (filename == "cout") {
+    CommandHistogram_Header(cout, file_type, output_it);
+    CommandHistogram_Body(cout, file_type, output_it);
+  } else {
+    ofstream & fp = data_file_manager.GetOFStream(filename);
+    CommandHistogram_Header(fp, file_type, output_it);
+    CommandHistogram_Body(fp, file_type, output_it);
   }
+  
+  // And clean up...
+  while (output_list.GetSize() != 0) delete output_list.Pop();
+}
 
+void cAnalyze::CommandHistogram_Header(ostream & fp, int format_type,
+       tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it)
+{
+  // Write out the header on the file
+  if (format_type == FILE_TYPE_TEXT) {
+    fp << "#filetype histogram_data" << endl;
+    fp << "#format ";
+    while (output_it.Next() != NULL) {
+      const cString & entry_name = output_it.Get()->GetName();
+      fp << entry_name << " ";
+    }
+    fp << endl << endl;
+    
+    // Give the more human-readable legend.
+    fp << "# Histograms:" << endl;
+    int count = 0;
+    while (output_it.Next() != NULL) {
+      const cString & entry_desc = output_it.Get()->GetDesc();
+      fp << "# " << ++count << ": " << entry_desc << endl;
+    }
+    fp << endl;
+  } else { // if (format_type == FILE_TYPE_HTML) {
+    fp << "<html>" << endl
+       << "<body bgcolor=\"#FFFFFF\"" << endl
+       << " text=\"#000000\"" << endl
+       << " link=\"#0000AA\"" << endl
+       << " alink=\"#0000FF\"" << endl
+       << " vlink=\"#000044\">" << endl
+       << endl
+       << "<h1 align=center>Histograms for " << batch[cur_batch].Name()
+       << "</h1>" << endl
+       << endl
+       << "<center>" << endl
+       << "<table border=1 cellpadding=2><tr>" << endl;
+    
+    while (output_it.Next() != NULL) {
+      const cString & entry_desc = output_it.Get()->GetDesc();
+      const cString & entry_name = output_it.Get()->GetName();
+      fp << "<tr><th bgcolor=\"#AAAAFF\"><a href=\"#"
+	 << entry_name << "\">"
+	 << entry_desc << "</a></tr>";
+    }
+    fp << "</tr></table>" << endl;    
+  }
+}
 
+
+void cAnalyze::CommandHistogram_Body(ostream & fp, int format_type,
+	     tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it)
+{
+  output_it.Reset();
+  tDataEntryCommand<cAnalyzeGenotype> * data_command = NULL;
+    
+  while ((data_command = output_it.Next()) != NULL) {
+    if (format_type == FILE_TYPE_TEXT) {
+      fp << "# --- " << data_command->GetDesc() << " ---" << endl;
+    } else {
+      fp << "<table cellpadding=3>" << endl
+	 << "<tr><th colspan=3><a name=\"" << data_command->GetName() << "\">"
+	 << data_command->GetDesc() << "</th></tr>" << endl;
+    }
+
+    tDictionary<int> count_dict;
+
+    // Loop through all genotypes in this batch to collect the info we need.
+    tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
+    cAnalyzeGenotype * cur_genotype;
+    while ((cur_genotype = batch_it.Next()) != NULL) {
+      data_command->SetTarget(cur_genotype);
+      const cString cur_name(data_command->GetEntry().AsString());
+      int count = 0;
+      count_dict.Find(cur_name, count);
+      count += cur_genotype->GetNumCPUs();
+      count_dict.SetValue(cur_name, count);
+    }
+
+    tList<cString> name_list;
+    tList<int> count_list;
+    count_dict.AsLists(name_list, count_list);
+
+    // Figure out the maximum count and the maximum widths...
+    int max_count = 0;
+    int max_name_width = 0;
+    int max_count_width = 0;
+    tListIterator<int> count_it(count_list);
+    tListIterator<cString> name_it(name_list);
+    while (count_it.Next() != NULL) {
+      const cString cur_name( *(name_it.Next()) );
+      const int cur_count = *(count_it.Get());
+      const int name_width = cur_name.GetSize();
+      const int count_width = cStringUtil::Stringf("%d", cur_count).GetSize();
+      if (cur_count > max_count) max_count = cur_count;
+      if (name_width > max_name_width) max_name_width = name_width;
+      if (count_width > max_count_width) max_count_width = count_width;
+    }
+
+    // Do some final calculations now that we know the maximums...
+    const int max_stars = 75 - max_name_width - max_count_width;
+
+    // Now print everything out...
+    count_it.Reset();
+    name_it.Reset();
+    while (count_it.Next() != NULL) {
+      const cString cur_name( *(name_it.Next()) );
+      const int cur_count = *(count_it.Get());
+      if (cur_count == 0) continue;
+      int num_stars = (cur_count * max_stars) / max_count;
+
+      if (format_type == FILE_TYPE_TEXT) {
+	fp << setw(max_name_width) << cur_name << "  " 
+	   << setw(max_count_width) << cur_count << "  ";
+	for (int i = 0; i < num_stars; i++) { fp << '#'; }
+	fp << endl;
+      } else { // FILE_TYPE_HTML
+	fp << "<tr><td>" << cur_name
+	   << "<td>" << cur_count
+	   << "<td>";
+	for (int i = 0; i < num_stars; i++) { fp << '#'; }
+	fp << "</tr>" << endl;
+      }
+    }
+
+    if (format_type == FILE_TYPE_TEXT) {
+      // Skip a line between histograms...
+      fp << endl;
+    } else {
+      fp << "</table><br><br>" << endl << endl;;
+    }
+  }
+  
+  // If in HTML mode, we need to end the file...
+  if (format_type == FILE_TYPE_HTML) {
+    fp << "</table>" << endl
+    << "</center>" << endl;
+  }
+}
+
+
 ///// Population Analysis Commands ////
 
 void cAnalyze::CommandPrintPhenotypes(cString cur_string)
@@ -2247,20 +2419,28 @@
   }
 }
 
+
 void cAnalyze::CommunityComplexity(cString cur_string)
 {
-  cout << "Analyze community complexity for current population ...\n";
 
-  // Get mutation rate
-  double mut_rate = cur_string.PopWord().AsDouble();
+  /////////////////////////////////////////////////////////////////////////
+  // Calculate the mutual information between all genotypes and environment
+  /////////////////////////////////////////////////////////////////////////
 
+  cout << "Analyze biocomplexity of current population about environment ...\n";
 
-  // Create the directory using the string given as the second argument
+  // Get the number of genotypes that are gonna be analyzed.
+  int max_genotypes = cur_string.PopWord().AsInt();
+
+  // Get update
+  int update = cur_string.PopWord().AsInt();
+
+  // Get the directory  
   cString dir = cur_string.PopWord();
   cString defaultDir = "community_cpx/";
   cString directory = PopDirectory(dir, defaultDir);
 
-  // Create the file that saves the result 
+  // Get the file name that saves the result 
   cString filename = cur_string.PopWord();
   if (filename.IsEmpty()) {
     filename = "community.complexity.dat";
@@ -2271,105 +2451,463 @@
 
   cpx_fp << "# Legend:" << endl;
   cpx_fp << "# 1: Genotype ID" << endl;
-  cpx_fp << "# 2: Parent ID" << endl;
-  cpx_fp << "# 3: Fitness" << endl;
-  cpx_fp << "# 4: New Information" << endl;
+  cpx_fp << "# 2: Entropy given Known Genotypes" << endl;
+  cpx_fp << "# 3: Entropy given Both Known Genotypes and Env" << endl;
+  cpx_fp << "# 4: New Information about Environment" << endl;
   cpx_fp << "# 5: Total Complexity" << endl;
-  cpx_fp << "# 6: New Information - Lost Informtion" << endl;
-  cpx_fp << "# 7: Net Total Complexity" << endl << endl;
+  cpx_fp << endl;
 
+  /////////////////////////////////////////////////////////////////////////////////
+  // Loop through all of the genotypes in all batches and build id vs. genotype map
 
-  ////////////////////////////////////////////////////////////////////////////////
-  // Loop through all of the genotypes in this batch and build parent-genotype map
-  
-  typedef multimap< int, cAnalyzeGenotype *, less<int> > tMultimap;
-  tMultimap children;       
+  map<int, cAnalyzeGenotype *> genotype_database;
+  for (int i = 0; i < MAX_BATCHES; ++ i) {
+    tListIterator<cAnalyzeGenotype> batch_it(batch[i].List());
+    cAnalyzeGenotype * genotype = NULL;
+    while ((genotype = batch_it.Next()) != NULL) {
+      genotype_database.insert(make_pair(genotype->GetID(), genotype));
+    }
+  }
+
+  ////////////////////////////////////////////////
+  // Check if all the genotypes having same length
+
+  int length_genome;
+  if (genotype_database.size() > 0) {
+    length_genome = genotype_database.begin()->second->GetLength();
+  }
+  map<int, cAnalyzeGenotype *>::iterator gen_iterator = genotype_database.begin();
+  for (; gen_iterator != genotype_database.end(); ++ gen_iterator) {
+    if (gen_iterator->second->GetLength() != length_genome) {
+      cerr << "Genotype " << gen_iterator->first << " has different genome length." << endl;
+      exit(1);
+    }
+  }
+
+  ///////////////////////
+  // Backup test CPU data
+  bool backupUsage = cTestCPU::UseResources();
+  tArray<double> backupResources(cTestCPU::GetResources());
+  cTestCPU::UseResources() = true;
+  FillResources(update);
+
+  ///////////////////////////////////////////////////////////////////////
+  // Choose the first n most abundant genotypes and put them in community
+
+  vector<cAnalyzeGenotype *> community;
+  cAnalyzeGenotype * genotype = NULL;
   tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
-  cAnalyzeGenotype * genotype = NULL;
+
+  while (((genotype = batch_it.Next()) != NULL) && (community.size() < max_genotypes)) {
+    community.push_back(genotype);
+  }
+    
+  ///////////////////////////
+  // Measure hamming distance
+
+  int size_community = community.size();
+  if (size_community == 0) {
+    cerr << "There is no genotype in this community." << endl;
+    cpx_fp.close();
+    exit(1);
+  }
+  typedef pair<int,int> gen_pair;
+  map<gen_pair, int> hamming_dist;
   
-  while ((genotype = batch_it.Next()) != NULL) {
-    children.insert(make_pair(genotype->GetParentID(), genotype));
+  for (int i = 0; i< size_community; ++ i) {
+    for (int j = i+1; j < size_community; ++ j) {
+      int dist = cGenomeUtil::FindHammingDistance(community[i]->GetGenome(),
+						  community[j]->GetGenome());
+      int id1 = community[i]->GetID();
+      int id2 = community[j]->GetID();
+
+      hamming_dist.insert(make_pair(gen_pair(id1, id2), dist));
+      hamming_dist.insert(make_pair(gen_pair(id2, id1), dist));
+    }
   }
 
-  // Put the first genotype (root of the phylogenetic tree) in the queue.
-  // Breadth-first traversal of the phylogeny_tree. Accumulate new information
-  // in the child compared to its parent.
-  typedef pair<cAnalyzeGenotype *, cAnalyzeGenotype *> tGenotypePair; // genotype and its parent
-  queue<tGenotypePair> genotype_queue;
+  //////////////////////////////////
+  // Get Most Recent Common Ancestor
 
-  // Look for the root that has multiple childrent.
-  int genotype_id = children.begin()->second->GetID(); 
-  while (children.count(genotype_id) == 1 && children.size() > 1) {
-    children.erase(children.begin());
-    genotype_id = children.begin()->second->GetID();
+  map<gen_pair, cAnalyzeGenotype *> mrca;
+  map<gen_pair, int> raw_dist;
+  for (int i = 0; i< size_community; ++ i) {
+    for (int j = i+1; j < size_community; ++ j) {
+				    
+      cAnalyzeGenotype * lineage1_genotype = community[i];
+      cAnalyzeGenotype * lineage2_genotype = community[j];
+      int total_dist = 0;
+
+      while (lineage1_genotype->GetID() != lineage2_genotype->GetID()) {
+	if (lineage1_genotype->GetID() > lineage2_genotype->GetID()) {
+	  int parent_id = lineage1_genotype->GetParentID();
+	  cAnalyzeGenotype * parent = genotype_database.find(parent_id)->second;
+
+	  total_dist += cGenomeUtil::FindHammingDistance(lineage1_genotype->GetGenome(),
+							 parent->GetGenome());
+	  lineage1_genotype = parent;
+	} else {
+	  int parent_id = lineage2_genotype->GetParentID();
+	  cAnalyzeGenotype * parent = genotype_database.find(parent_id)->second;
+	  total_dist += cGenomeUtil::FindHammingDistance(lineage2_genotype->GetGenome(),
+							 parent->GetGenome());
+      
+	  lineage2_genotype = parent;
+	}
+      }
+
+      int id1 = community[i]->GetID();
+      int id2 = community[j]->GetID();
+      mrca.insert(make_pair(gen_pair(id1, id2), lineage1_genotype));
+      mrca.insert(make_pair(gen_pair(id2, id1), lineage1_genotype));
+      raw_dist.insert(make_pair(gen_pair(id1, id2), total_dist));
+      raw_dist.insert(make_pair(gen_pair(id2, id1), total_dist));
+    }
   }
 
-  if (children.begin() != children.end()) {
-    genotype_queue.push( tGenotypePair(children.begin()->second, NULL) );
+  /*
+  ////////////////////////////////////////////////////////////////////////////////////////////
+  // Sort the genotype that is next genotype is the most closest one to all previous genotypes
+
+  vector<cAnalyzeGenotype *> sorted_community;
+  vector<cAnalyzeGenotype *> left_genotypes = community;
+
+  // Put the first genotype in left to sorted.
+  sorted_community.push_back(*left_genotypes.begin());
+  left_genotypes.erase(left_genotypes.begin());
+
+  while (left_genotypes.size() > 0) {
+    int min_total_hamming = size_community * length_genome;
+    int index_next;
+
+    for (int next = 0; next < left_genotypes.size(); ++ next) {
+      int total_hamming = 0;
+      int id1 = left_genotypes[next]->GetID();
+      
+      for (int given = 0; given < sorted_community.size(); ++ given) {
+	int id2 = sorted_community[given]->GetID();
+	total_hamming += hamming_dist.find(gen_pair(id1, id2))->second;
+      }
+
+      if (total_hamming < min_total_hamming) {
+	min_total_hamming = total_hamming;
+	index_next = next;
+      }
+    }
+
+    sorted_community.push_back(left_genotypes[index_next]);
+    left_genotypes.erase(left_genotypes.begin() + index_next);
   }
 
-  double community_cpx = 0.0;
-  double community_cpx_m2 = 0.0;       // Add net new information in the phylogeny.
-  while (genotype_queue.size() > 0) {
+  */
 
-    cAnalyzeGenotype * cur_genotype = genotype_queue.front().first;
-    cAnalyzeGenotype * parent_genotype = genotype_queue.front().second;
-    genotype_queue.pop();
-    cur_genotype->Recalculate();
-    cout << cur_genotype->GetID() << endl;
+  vector<cAnalyzeGenotype *> sorted_community = community;
+  /////////////////////////////////////////////
+  // Loop through genotypes in sorted community
 
-    
-    if (parent_genotype == NULL) {     // The root of phylogenetic tree
-      double entropy = AnalyzeEntropy(cur_genotype, mut_rate);
-      community_cpx = cur_genotype->GetLength() - entropy;
-      community_cpx_m2 = community_cpx;
-      cpx_fp << cur_genotype->GetID() << " -1 " << cur_genotype->GetFitness() << " 0 " 
-	     << community_cpx << " 0 " << community_cpx_m2 << endl;
+  double complexity = 0.0;
+  vector<cAnalyzeGenotype *> given_genotypes;
+  int num_insts = inst_set.GetSize();
+
+  for (int i = 0; i < size_community; ++ i) {
+    genotype = sorted_community[i];
+
+    // Skip the dead organisms
+    genotype->Recalculate();
+    if (genotype->GetFitness() == 0) {
+      continue;
+    }
+
+    vector<double> one_line_prob(num_insts, 0.0);
+    vector< vector<double> > prob(length_genome, one_line_prob);
+
+    cout << endl << genotype->GetID() << endl;
+
+    /*if (given_genotypes.size() >= 2) {
+
+      ///////////////////////////////////////////////////////////////////
+      // Look for two given genotypes that has minimun depth dist with it
+
+      cAnalyzeGenotype * min_depth_gen = given_genotypes[0];
+      cAnalyzeGenotype * tmrca = mrca.find(gen_pair(genotype->GetID(), 
+						    given_genotypes[0]->GetID()))->second;
+      int min_depth_dist = genotype->GetDepth() + given_genotypes[0]->GetDepth() - 2 * tmrca->GetDepth();
+      
+      cAnalyzeGenotype * second_min_gen = given_genotypes[1];
+      tmrca = mrca.find(gen_pair(genotype->GetID(), given_genotypes[1]->GetID()))->second;
+      int second_min_depth = genotype->GetDepth() + given_genotypes[1]->GetDepth() - 2 * tmrca->GetDepth();
+
+      for (int i = 2; i < given_genotypes.size(); ++ i) {
+	cAnalyzeGenotype * given_genotype = given_genotypes[i];
+	cAnalyzeGenotype * tmrca = mrca.find(gen_pair(genotype->GetID(),
+						      given_genotype->GetID()))->second;
+	int dist = genotype->GetDepth() + given_genotype->GetDepth() - 2 * tmrca->GetDepth();
+
+	if (dist < min_depth_dist) {
+	  second_min_depth = min_depth_dist;
+	  second_min_gen = min_depth_gen;
+	  min_depth_dist = dist;
+	  min_depth_gen = given_genotype;
+	} else if (dist >= min_depth_dist && dist < second_min_depth) {
+	  second_min_depth = dist;
+	  second_min_gen = given_genotype;
+	}
+      }
+
+      const cGenome & given_genome1 = min_depth_gen->GetGenome();
+      const cGenome & given_genome2 = second_min_gen->GetGenome();
+      for (int line = 0; line < length_genome; ++ line) {
+	int given_inst = given_genome1[line].GetOp();
+	prob[line][given_inst] += pow(1 - 1.0/length_genome, min_depth_dist);
+	given_inst = given_genome2[line].GetOp();
+	prob[line][given_inst] += pow(1 - 1.0/length_genome, min_depth_dist);
+      }
+
+      cpx_fp << genotype->GetID() << " " << min_depth_dist << " " << second_min_depth 
+	     << " " << raw_dist.find(gen_pair(genotype->GetID(), min_depth_gen->GetID()))->second
+	     << " " << raw_dist.find(gen_pair(genotype->GetID(), second_min_gen->GetID()))->second
+	     << " ";
+      
+	
+    } else  if (given_genotypes.size() == 1) {
+      //////////////////////////////////////////////////////
+      // Calculate the probability of each inst at each line
+      cAnalyzeGenotype * tmrca = mrca.find(gen_pair(genotype->GetID(), 
+						    given_genotypes[0]->GetID()))->second;
+      int dist = genotype->GetDepth() + given_genotypes[0]->GetDepth() - 2 * tmrca->GetDepth();
+      const cGenome & given_genome = given_genotypes[0]->GetGenome();
+
+      for (int line = 0; line < length_genome; ++ line) {
+	int given_inst = given_genome[line].GetOp();
+	prob[line][given_inst] += pow(1 - 1.0/length_genome, dist);
+      }
+      
+      cpx_fp << genotype->GetID() << " " << dist << " " 
+	     << raw_dist.find(gen_pair(genotype->GetID(), given_genotypes[0]->GetID()))->second << " ";
     } else {
+      cpx_fp << genotype->GetID() << " ";
+      }*/
 
-      // Compare with its parent to measure new information 
-      double newinfo = IncreasedInfo(cur_genotype, parent_genotype, mut_rate);
-      community_cpx += newinfo;
-      cpx_fp << cur_genotype->GetID() << " " << parent_genotype->GetID() << " " 
-	     << cur_genotype->GetFitness() << " " << newinfo << " " << community_cpx;
+    if (given_genotypes.size() >= 1) {
+      //////////////////////////////////////////////////
+      // Look for a genotype that is closest to this one
+      
+      cAnalyzeGenotype * min_depth_gen = given_genotypes[0];
+      cAnalyzeGenotype * tmrca = mrca.find(gen_pair(genotype->GetID(), 
+						    given_genotypes[0]->GetID()))->second;
+      int min_depth_dist = genotype->GetDepth() + given_genotypes[0]->GetDepth() - 2 * tmrca->GetDepth();
 
-      // Only if current genotype is viable, compare it with its parent for net new info
-      if (cur_genotype->GetFitness() > 0) {
+      for (int i = 1; i < given_genotypes.size() ; ++ i) {
+	cAnalyzeGenotype * given_genotype = given_genotypes[i];
+	cAnalyzeGenotype * tmrca = mrca.find(gen_pair(genotype->GetID(),
+						      given_genotype->GetID()))->second;
+	int dist = genotype->GetDepth() + given_genotype->GetDepth() - 2 * tmrca->GetDepth();
 	
-	// Compare with its parent to measure net new information
-	double lostinfo = IncreasedInfo(parent_genotype, cur_genotype, mut_rate);
-	community_cpx_m2 += newinfo - lostinfo;
-	cpx_fp << " " << newinfo - lostinfo << " " << community_cpx_m2 << endl;
+	if (dist < min_depth_dist) {
+	  min_depth_dist = dist;
+	  min_depth_gen = given_genotype;
+	}
+      }
+
+      const cGenome & given_genome = min_depth_gen->GetGenome();
+      const cGenome & base_genome = genotype->GetGenome();
+      cGenome mod_genome(base_genome);
+      for (int line = 0; line < length_genome; ++ line) {
+	int given_inst = given_genome[line].GetOp();
+	mod_genome = base_genome;
+	mod_genome[line].SetOp(given_inst);
+	cAnalyzeGenotype test_genotype(mod_genome, inst_set);
+	test_genotype.Recalculate();
+
+	// Only when given inst make the genotype alive
+	if (test_genotype.GetFitness() > 0) {
+	  prob[line][given_inst] += pow(1 - 1.0/length_genome, min_depth_dist);
+	}
+      }
       
-      } else {
-	cpx_fp << " " << 0 << " " << community_cpx_m2 << endl;
+      cpx_fp << genotype->GetID() << " " << min_depth_dist << " " 
+	     << raw_dist.find(gen_pair(genotype->GetID(), min_depth_gen->GetID()))->second << " "
+	     << hamming_dist.find(gen_pair(genotype->GetID(), min_depth_gen->GetID()))->second << "   ";
+    } else {
+      cpx_fp << genotype->GetID() << " ";
+    }
 
-	// This genotype should not have children
-	if (children.count(cur_genotype->GetID()) != 0) {
-	  cpx_fp << "Error: This genotype has children but it shouldn't." << endl;
-	  cpx_fp.close();
-	  return;
+    /////////////////////////////////////////
+    // Normalize the probability at each line
+
+    for (int line = 0; line < length_genome; ++ line) {
+      double cur_total_prob = 0.0;
+      for (int inst = 0; inst < num_insts; ++ inst) {
+	cur_total_prob += prob[line][inst];
+      }
+      if (cur_total_prob > 1) {
+	for (int inst = 0; inst < num_insts; ++ inst) {
+	  prob[line][inst] = prob[line][inst] / cur_total_prob;
 	}
+	cur_total_prob = 1.0;
       }
+      double left_prob = 1 - cur_total_prob;
+
+      // Check the number of insts that could make genotype alive ...
+      int num_alive = 0;
+      const cGenome & base_genome = genotype->GetGenome();
+      cGenome mod_genome(base_genome);
+      for (int inst = 0; inst < num_insts; ++ inst) {
+	mod_genome[line].SetOp(inst);
+	cAnalyzeGenotype test_genotype(mod_genome, inst_set);
+	test_genotype.Recalculate();
+
+	// Only when given inst make the genotype alive
+	if (test_genotype.GetFitness() > 0) {
+	  num_alive ++;
+	} else {
+	  prob[line][inst] = -1;
+	}
+      }
+	  
+      for (int inst = 0; inst < num_insts; ++ inst) {
+	if (prob[line][inst] == -1) {
+	  prob[line][inst] = 0;
+	} else {
+	  prob[line][inst] += left_prob / num_alive;
+	}	
+      }
+
     }
 
-    // Add the children of current genotype to the queue
-    typedef pair<tMultimap::iterator, tMultimap::iterator> pairii;
-    pairii child_range = children.equal_range(cur_genotype->GetID());
-    tMultimap::iterator child_pos = child_range.first;
-    for (; child_pos != child_range.second; ++ child_pos) {
-      cAnalyzeGenotype * cur_child = child_pos->second;
-      genotype_queue.push( tGenotypePair(cur_child, cur_genotype) );
+    /////////////////////////////////
+    // Calculate entropy of each line  
+    vector<double> entropy(length_genome, 0.0);
+    for (int line = 0; line < length_genome; ++ line) {
+      for (int inst = 0; inst < num_insts; ++ inst) {
+	if (prob[line][inst] > 0) {
+	  entropy[line] -= prob[line][inst] * log(prob[line][inst]) / log(num_insts*1.0);
+	}
+      }
     }
 
-    // Delete the children of current genotype from map
-    children.erase(child_range.first, child_range.second);
+
+    ///////////////////////////////////////////////////////////////////
+    // Point mutation at all lines of code to look for neutral mutation
+    cout << "Test point mutation." << endl;
+    vector<bool> one_line_neutral(num_insts, false);
+    vector< vector<bool> > neutral_mut(length_genome, one_line_neutral);
+   
+    genotype->Recalculate();
+    double base_fitness = genotype->GetFitness();
+    cout << base_fitness << endl;
+    const cGenome & base_genome = genotype->GetGenome();
+    cGenome mod_genome(base_genome);
+      
+    for (int line = 0; line < length_genome; ++ line) {
+      int cur_inst = base_genome[line].GetOp();
+      
+      for (int mod_inst = 0; mod_inst < num_insts; ++ mod_inst) {
+	mod_genome[line].SetOp(mod_inst);
+	cAnalyzeGenotype test_genotype(mod_genome, inst_set);
+	test_genotype.Recalculate();
+	if (test_genotype.GetFitness() >= base_fitness) {
+	  neutral_mut[line][mod_inst] = true;
+	}
+      }
+      
+      mod_genome[line].SetOp(cur_inst);
+    }
+
+
+    /////////////////////////////////////////////////////
+    // Redistribute the probability of insts at each line
+    vector< vector<double> > prob_given_env(length_genome, one_line_prob);
     
+    for (int line = 0; line < length_genome; ++ line) {
+      double total_prob = 0.0;
+      for (int inst = 0; inst < num_insts; ++ inst) {
+	if (neutral_mut[line][inst] == true) {
+	  total_prob += prob[line][inst];
+	}
+      }
+
+      if (total_prob == 0) {
+	cout << "total prob is zero." ;
+	exit(1);
+      }
+
+      for (int inst = 0; inst < num_insts; ++ inst) {
+	if (neutral_mut[line][inst] == true) {
+	  prob_given_env[line][inst] = prob[line][inst] / total_prob;
+	} else {
+	  prob_given_env[line][inst] = 0.0;
+	}
+      }
+      
+    }
+
+    ////////////////////////////////////////////////
+    // Calculate the entropy given environment
+
+    vector<double> entropy_given_env(length_genome, 0.0);
+    for (int line = 0; line < length_genome; ++ line) {
+      for (int inst = 0; inst < num_insts; ++ inst) {
+	if (prob_given_env[line][inst] > 0) {
+	  entropy_given_env[line] -= prob_given_env[line][inst] * log(prob_given_env[line][inst]) / 
+	                             log(num_insts*1.0);
+	}
+      }
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Calculate the information between genotype and env given other genotypes
+    double information = 0.0;
+    double entropy_before = 0.0;
+    double entropy_after = 0.0;
+    for (int line = 0; line < length_genome; ++ line) {
+      entropy_before += entropy[line];
+      entropy_after += entropy_given_env[line];
+
+      if (entropy[line] >= entropy_given_env[line]) {
+	information += entropy[line] - entropy_given_env[line];	
+      } else {    // Negative information is deemed as new information ...
+	
+	// Count the number of insts that can make genotype alive
+	int num_inst_alive = 0;
+	for (int inst = 0; inst < num_insts; ++ inst) {
+	  if (prob[line][inst] > 0) {
+	    num_inst_alive ++;
+	  }
+	}
+	
+	double entropy_before = - log(1.0/num_inst_alive) / log(num_insts*1.0);
+	information += entropy_before - entropy_given_env[line];
+	if (information < 0) {
+	  cout << "Negative information at site " << line << endl;
+	  exit(1);
+	}
+      }
+
+    }
+    complexity += information;
+
+    cpx_fp << entropy_before << " " << entropy_after << " "
+	   << information << " " << complexity << "   ";
+
+    genotype->PrintTasks(cpx_fp, 0, -1);
+    cpx_fp << endl; 
+
+    /////////////////////////////////////////////////////////////
+    // This genotype becomes the given condition of next genotype
+
+    given_genotypes.push_back(genotype);
+
   }
 
+  // Set the test CPU back to the state it was 
+  cTestCPU::UseResources() = backupUsage;
+  cTestCPU::SetupResourceArray(backupResources);
+    
   cpx_fp.close();
   return;
-  
+	 
 }
 
 void cAnalyze::CommandLandscape(cString cur_string)
@@ -2424,7 +2962,134 @@
   }
 }
 
+
+// This command will take the current batch and analyze how well organisms
+// cross-over with each other, both across the population and between mates.
+
+void cAnalyze::AnalyzeMateSelection(cString cur_string)
+{
+  int sample_size = 10000;
+  if (cur_string.GetSize() != 0) sample_size = cur_string.PopWord().AsInt();
+  cString filename("none");
+  if (cur_string.GetSize() != 0) filename = cur_string.PopWord();
   
+  cout << "Mate Selection... " << endl;
+  
+  // Next, we create an array that contains pointers to all of the organisms
+  // in this batch.  Note that we want to select genotypes based on their
+  // abundance, so they will have one entry in the array per organism.  Note
+  // that we only consider viable genotypes.
+
+  // Start by counting the total number of organisms.
+  int org_count = 0;
+  cAnalyzeGenotype * genotype = NULL;
+  tListIterator<cAnalyzeGenotype> list_it(batch[cur_batch].List());
+  while ((genotype = list_it.Next()) != NULL) {
+    if (genotype->GetViable() == false) continue;
+    org_count += genotype->GetNumCPUs();
+  }
+
+  // Create an array of the correct size.
+  tArray<cAnalyzeGenotype *> genotype_array(org_count);
+
+  // And insert all of the organisms into the array.
+  int cur_pos = 0;
+  while ((genotype = list_it.Next()) != NULL) {
+    if (genotype->GetViable() == false) continue;
+    int cur_count = genotype->GetNumCPUs();
+    for (int i = 0; i < cur_count; i++) {
+      genotype_array[cur_pos++] = genotype;
+    }
+  }
+  
+
+  // Setup some variables;
+  cAnalyzeGenotype * genotype2 = NULL;
+  int total_matches_tested = 0;
+  int fail_count = 0;
+  int match_fail_count = 0;
+
+  // Loop through all of the tests, picking random organisms each time and
+  // performing a random cross test.
+  for (int test_id = 0; test_id < sample_size; test_id++) {
+    genotype = genotype_array[ g_random.GetUInt(org_count) ];
+    genotype2 = genotype_array[ g_random.GetUInt(org_count) ];
+
+    // Stop immediately if we're comparing a genotype to itself.
+    if (genotype == genotype2) {
+      total_matches_tested++;
+      continue;
+    }
+
+    // Setup the random parameters for this test.
+    cCPUMemory test_genome0 = genotype->GetGenome(); 
+    cCPUMemory test_genome1 = genotype2->GetGenome(); 
+          
+    double start_frac = g_random.GetDouble();
+    double end_frac = g_random.GetDouble();
+    if (start_frac > end_frac) nFunctions::Swap(start_frac, end_frac);
+          
+    int start0 = (int) (start_frac * (double) test_genome0.GetSize());
+    int end0   = (int) (end_frac * (double) test_genome0.GetSize());
+    int size0 = end0 - start0;
+
+    int start1 = (int) (start_frac * (double) test_genome1.GetSize());
+    int end1   = (int) (end_frac * (double) test_genome1.GetSize());
+    int size1 = end1 - start1;
+
+    int new_size0 = test_genome0.GetSize() - size0 + size1;   
+    int new_size1 = test_genome1.GetSize() - size1 + size0;
+
+    // Setup some statistics for this particular test.
+    bool cross_viable = true;
+    bool same_mate_id = ( genotype->GetMateID() == genotype2->GetMateID() );
+    if (same_mate_id == true) total_matches_tested++;
+
+    // Don't Crossover if offspring will be illegal!!!
+    if (new_size0 < MIN_CREATURE_SIZE || new_size0 > MAX_CREATURE_SIZE || 
+	new_size1 < MIN_CREATURE_SIZE || new_size1 > MAX_CREATURE_SIZE) { 
+      fail_count++; 
+      if (same_mate_id == true) match_fail_count++;
+      continue; 
+    } 
+
+    // Do the replacement...  We're only going to test genome0, so we only
+    // need to modify that one.
+    cGenome cross1 = cGenomeUtil::Crop(test_genome1, start1, end1);
+    test_genome0.Replace(start0, size0, cross1);
+
+    // Do the test.
+    cCPUTestInfo test_info;
+          
+    // Run each side, and determine viability...
+    cTestCPU::TestGenome(test_info, test_genome0);
+    if( test_info.IsViable() == false ) {
+      fail_count++;
+      if (same_mate_id == true) match_fail_count++;
+    }
+  }
+
+  // Calculate the final answer
+  double fail_frac = (double) fail_count / (double) sample_size;
+  double match_fail_frac =
+    (double) match_fail_count / (double) total_matches_tested;
+  cout << "  ave fraction failed = " << fail_frac << endl
+       << "  ave matches failed = " << match_fail_frac << endl
+       << "  total mate matches = " <<  total_matches_tested
+       << " / " << sample_size<< endl;
+
+  if (filename == "none") return;
+  
+  cDataFile & df = data_file_manager.Get(filename);
+  df.WriteComment( "Mate selection information" );
+  df.WriteTimeStamp();  
+  
+  df.Write(fail_frac,       "Average fraction failed");
+  df.Write(match_fail_frac, "Average fraction of mate matches failed");
+  df.Endl();
+}
+
+  
 void cAnalyze::CommandFitnessMatrix(cString cur_string)
 {
   if (verbose == true) cout << "Calculating fitness matrix for batch " << cur_batch << endl;
@@ -2532,7 +3197,7 @@
       cout << output_it.Get()->GetName() << " ";
     }
     cout << endl;
-    }
+  }
   
   
   ///////////////////////////////////////////////////////
@@ -2758,7 +3423,7 @@
     delete [] col_fail_count;
     
     }
-    }
+}
 
 void cAnalyze::CommandAverageModularity(cString cur_string)
 {
@@ -3648,24 +4313,14 @@
             break; 
           } 
           
-          if (size0 > 0 && size1 > 0) {
-            cGenome cross0 = cGenomeUtil::Crop(test_genome0, start0, end0);
-            cGenome cross1 = cGenomeUtil::Crop(test_genome1, start1, end1);
-            test_genome0.Replace(start0, size0, cross1);
-            test_genome1.Replace(start1, size1, cross0);
-          }
-          else if (size0 > 0) {
-            cGenome cross0 = cGenomeUtil::Crop(test_genome0, start0, end0);
-            test_genome1.Replace(start1, size1, cross0);
-          }
-          else if (size1 > 0) {
-            cGenome cross1 = cGenomeUtil::Crop(test_genome1, start1, end1);
-            test_genome0.Replace(start0, size0, cross1);
-          }
+	  // Swap the components
+	  cGenome cross0 = cGenomeUtil::Crop(test_genome0, start0, end0);
+	  cGenome cross1 = cGenomeUtil::Crop(test_genome1, start1, end1);
+	  test_genome0.Replace(start0, size0, cross1);
+	  test_genome1.Replace(start1, size1, cross0);
           
+	  // Run each side, and determine viability...
           cCPUTestInfo test_info;
-          
-          // Run each side, and determine viability...
           cTestCPU::TestGenome(test_info, test_genome0);
           cross1_viable = test_info.IsViable();
           
@@ -5729,8 +6384,11 @@
                               ("fitness",     "Fitness",         &cAnalyzeGenotype::GetFitness,
                                &cAnalyzeGenotype::SetFitness, &cAnalyzeGenotype::CompareFitness));
   genotype_data_list.PushRear(new tDataEntry<cAnalyzeGenotype, double>
-                              ("div_type",     "Divide Type",         &cAnalyzeGenotype::GetDivType,
+                              ("div_type",     "Divide Type",    &cAnalyzeGenotype::GetDivType,
                                &cAnalyzeGenotype::SetDivType));
+  genotype_data_list.PushRear(new tDataEntry<cAnalyzeGenotype, int>
+                              ("mate_id",     "Mate Selection ID Number",  &cAnalyzeGenotype::GetMateID,
+                               &cAnalyzeGenotype::SetMateID));
   genotype_data_list.PushRear(new tDataEntry<cAnalyzeGenotype, double>
                               ("fitness_ratio", "Fitness Ratio", &cAnalyzeGenotype::GetFitnessRatio,
                                (void (cAnalyzeGenotype::*)(double)) NULL,
@@ -5937,6 +6595,7 @@
   AddLibraryDef("DETAIL_BATCHES", &cAnalyze::CommandDetailBatches);
   AddLibraryDef("DETAIL_AVERAGE", &cAnalyze::CommandDetailAverage);
   AddLibraryDef("DETAIL_INDEX", &cAnalyze::CommandDetailIndex);
+  AddLibraryDef("HISTOGRAM", &cAnalyze::CommandHistogram);
   
   // Population analysis commands...
   AddLibraryDef("PRINT_PHENOTYPES", &cAnalyze::CommandPrintPhenotypes);
@@ -5977,6 +6636,7 @@
   AddLibraryDef("ANALYZE_MUTATION_TRACEBACK",
                 &cAnalyze::AnalyzeMutationTraceback);
   AddLibraryDef("ANALYZE_EPISTASIS", &cAnalyze::AnalyzeEpistasis);
+  AddLibraryDef("ANALYZE_MATE_SELECTION", &cAnalyze::AnalyzeMateSelection);
   
   // Environment manipulation
   AddLibraryDef("ENVIRONMENT", &cAnalyze::EnvironmentSetup);
@@ -5995,6 +6655,7 @@
   AddLibraryDef("RENAME", &cAnalyze::BatchRename);
   AddLibraryDef("STATUS", &cAnalyze::PrintStatus);
   AddLibraryDef("DEBUG", &cAnalyze::PrintDebug);
+  AddLibraryDef("ECHO", &cAnalyze::PrintDebug);
   AddLibraryDef("VERBOSE", &cAnalyze::ToggleVerbose);
   AddLibraryDef("INCLUDE", &cAnalyze::IncludeFile);
   AddLibraryDef("SYSTEM", &cAnalyze::CommandSystem);

Modified: branches/brysonda/source/main/analyze.hh
===================================================================
--- branches/brysonda/source/main/analyze.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/analyze.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -112,6 +112,10 @@
             int time_step=-1, int max_time=1);
   void CommandDetailAverage_Body(std::ostream & fp, int num_arguments,
             tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it);
+  void CommandHistogram_Header(std::ostream & fp, int format_type,
+            tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it);
+  void CommandHistogram_Body(std::ostream & fp, int format_type,
+            tListIterator< tDataEntryCommand<cAnalyzeGenotype> > & output_it);
 
 private:
   // Loading methods...
@@ -146,6 +150,7 @@
   void CommandDetailBatches(cString cur_string);
   void CommandDetailAverage(cString cur_string);
   void CommandDetailIndex(cString cur_string);
+  void CommandHistogram(cString cur_string);
 
   // Population Analysis Commands...
   void CommandPrintPhenotypes(cString cur_string);
@@ -184,7 +189,7 @@
   void AnalyzeComplexity(cString cur_string);
   void AnalyzePopComplexity(cString cur_string);
   void AnalyzeEpistasis(cString cur_string);
-  
+  void AnalyzeMateSelection(cString cur_string);
 
   // Environment Manipulation
   void EnvironmentSetup(cString cur_string);

Modified: branches/brysonda/source/main/analyze_genotype.cc
===================================================================
--- branches/brysonda/source/main/analyze_genotype.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/analyze_genotype.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -184,6 +184,7 @@
   fitness = test_phenotype.GetFitness();
   errors = test_phenotype.GetLastNumErrors();
   div_type = test_phenotype.GetDivType();
+  mate_id = test_phenotype.MateSelectID();
   task_counts = test_phenotype.GetLastTaskCount();
 
   // Setup a new parent stats if we have a parent to work with.

Modified: branches/brysonda/source/main/analyze_genotype.hh
===================================================================
--- branches/brysonda/source/main/analyze_genotype.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/analyze_genotype.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -67,6 +67,7 @@
   double fitness;
   int errors;
   double div_type;
+  int mate_id;
 
   tArray<int> task_counts;
 
@@ -144,6 +145,7 @@
   void SetGestTime(int _gest) { gest_time = _gest; }
   void SetFitness(double _fitness) { fitness = _fitness; }
   void SetDivType(double _div_type) { div_type = _div_type; }
+  void SetMateID(int _mate_id) { mate_id = _mate_id; }
   void SetParentDist(int _dist) { parent_dist = _dist; }
   void SetAncestorDist(int _dist) { ancestor_dist = _dist; }
   void SetLineageLabel(int _label) { lineage_label = _label; }
@@ -183,6 +185,7 @@
     { return ((double) GetMinLength()) / (double) gest_time; }
   double GetFitness() const { return fitness; }
   double GetDivType() const { return div_type; }
+  int GetMateID() const { return mate_id; }
   int GetUpdateBorn() const { return update_born; }
   int GetUpdateDead() const { return update_dead; }
   int GetDepth() const { return depth; }

Modified: branches/brysonda/source/main/birth_chamber.cc
===================================================================
--- branches/brysonda/source/main/birth_chamber.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/birth_chamber.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -245,6 +245,36 @@
 }
 
 cBirthChamber::cBirthEntry *
+  cBirthChamber::FindSexMateSelectWaiting(const cGenome & child_genome,
+					  cOrganism & parent)
+{
+  const int mate_id = parent.GetPhenotype().MateSelectID();
+
+  // If this is a new largest ID, increase the array size.
+  if (mate_select_wait_entry.GetSize() <= mate_id) {
+    int old_wait_size = mate_select_wait_entry.GetSize();
+    mate_select_wait_entry.Resize(mate_id + 1);
+    for (int i = old_wait_size; i <= mate_id; i++) {
+      mate_select_wait_entry[i].is_waiting = false;
+    }
+  }
+
+  // Determine if we have an offspring of this length waiting already...
+  if (mate_select_wait_entry[mate_id].is_waiting == false) {
+    cGenotype * parent_genotype = parent.GetGenotype();
+    parent_genotype->IncDeferAdjust();
+    mate_select_wait_entry[mate_id].genome = child_genome;
+    mate_select_wait_entry[mate_id].merit = parent.GetPhenotype().GetMerit();
+    mate_select_wait_entry[mate_id].parent_genotype = parent_genotype;
+    mate_select_wait_entry[mate_id].is_waiting = true;
+    return NULL;
+  }
+
+  // There is already a child waiting -- do crossover between the two.
+  return &( mate_select_wait_entry[mate_id] ); 
+}
+
+cBirthChamber::cBirthEntry *
   cBirthChamber::FindSexLocalWaiting(const cGenome & child_genome,
 				   cOrganism & parent)
 {
@@ -512,21 +542,28 @@
   // First check if the birth method is one of the local ones... 
   if (cConfig::GetBirthMethod() < NUM_LOCAL_POSITION_CHILD) { 
     old_entry = FindSexLocalWaiting(child_genome, parent);
-  } else {
-    // ... then check if population is split into demes
-    if (cConfig::GetBirthMethod() == POSITION_CHILD_DEME_RANDOM) {
-      old_entry = FindSexDemeWaiting(child_genome, parent);
-    } else { 
-      // ... it must be global, but now check if recombination must be 
-      // only with organisms of the same length
-      if (cConfig::GetSameLengthSex() == 0) {
-        old_entry = FindSexGlobalWaiting(child_genome, parent);
-      } else {
-        old_entry = FindSexSizeWaiting(child_genome, parent);
-      }
-    }
   }
+  // ... then check if population is split into demes
+  else if (cConfig::GetBirthMethod() == POSITION_CHILD_DEME_RANDOM) {
+    old_entry = FindSexDemeWaiting(child_genome, parent);
+  }
 
+  // If none of the previous conditions were met, it must be global.
+  // ...check if recombination must be with organisms of the same length
+  else if (cConfig::GetSameLengthSex() != 0) {
+    old_entry = FindSexSizeWaiting(child_genome, parent);
+  }
+
+  // ...check if we have mate selection
+  else if (parent_phenotype.MateSelectID() >= 0) {
+    old_entry = FindSexMateSelectWaiting(child_genome, parent);
+  }
+
+  // If everything failed until this point, use default global.
+  else {
+    old_entry = FindSexGlobalWaiting(child_genome, parent);
+  }
+
   // If we couldn't find a waiting entry, this one was saved -- stop here!
   if (old_entry == NULL) {
     return false;
@@ -542,7 +579,7 @@
 			   child_array, merit_array);
   }
 
-  // RECOMBINATION will happen!
+  // If we made it this far, RECOMBINATION will happen!
   cCPUMemory genome0 = old_entry->genome;
   cCPUMemory genome1 = child_genome;
   double merit0 = old_entry->merit.GetDouble();

Modified: branches/brysonda/source/main/birth_chamber.hh
===================================================================
--- branches/brysonda/source/main/birth_chamber.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/birth_chamber.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -48,6 +48,7 @@
   tArray<cBirthEntry> local_wait_entry;
   tArray<cBirthEntry> deme_wait_entry;
   tArray<cBirthEntry> size_wait_entry;
+  tArray<cBirthEntry> mate_select_wait_entry;
 
   // mark whether that instruction has already been swapped 
   // between two genomes; used in modular recombination
@@ -72,14 +73,16 @@
 		       cOrganism & parent,
 		       tArray<cOrganism *> & child_array,
 		       tArray<cMerit> & merit_array);
-  cBirthEntry * FindSexSizeWaiting(const cGenome & child_genome,
-				    cOrganism & parent);
   cBirthEntry * FindSexLocalWaiting(const cGenome & child_genome,
 				    cOrganism & parent);
+  cBirthEntry * FindSexDemeWaiting(const cGenome & child_genome,
+				   cOrganism & parent);
+  cBirthEntry * FindSexSizeWaiting(const cGenome & child_genome,
+				   cOrganism & parent);
+  cBirthEntry * FindSexMateSelectWaiting(const cGenome & child_genome,
+					 cOrganism & parent);
   cBirthEntry * FindSexGlobalWaiting(const cGenome & child_genome,
 				     cOrganism & parent);
-  cBirthEntry * FindSexDemeWaiting(const cGenome & child_genome,
-				     cOrganism & parent);
 
   void DoBasicRecombination(cCPUMemory & genome0, cCPUMemory & genome1, 
 			    double & merit0, double & merit1);

Modified: branches/brysonda/source/main/config.cc
===================================================================
--- branches/brysonda/source/main/config.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/config.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -8,7 +8,9 @@
 #include "config.hh"
 
 #include "defs.hh"
+#include "event_factory_manager.hh"
 #include "genesis.hh"
+#include "population_event_factory.hh"
 #include "tools.hh"
 
 using namespace std;
@@ -583,13 +585,15 @@
   // Then scan through and process the rest of the args.
   
   while (arg_num < argc || genesis.IsOpen() == false) {
-    cString cur_arg = genesis.IsOpen() ? static_cast<cString>( args[arg_num] )
-    : static_cast<cString>( "--help" );
+    cString cur_arg = genesis.IsOpen() ? static_cast<cString>( args[arg_num] ) : static_cast<cString>( "--help" );
     
     // Test against the possible inputs.
     if (cur_arg == "-events" || cur_arg == "-e") {
       cout << "Known events:" << endl;
-      // DDD - Should print out events here
+      // @DMB - A cleaner way of constructing the cEventFactoryManager should be created
+      cEventFactoryManager event_manager;
+      event_manager.AddFactory(new cPopulationEventFactory(NULL));
+      event_manager.PrintAllEventDescriptions();
       exit(0);
     }
     else if (cur_arg == "--help" || cur_arg == "-help" ||

Modified: branches/brysonda/source/main/genotype_control.cc
===================================================================
--- branches/brysonda/source/main/genotype_control.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/genotype_control.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -177,9 +177,9 @@
     prev_OK =true;
   }
 
-  if ((&in_genotype == best && next_OK) ||
-      (next_OK && prev_OK) ||
-      (&in_genotype == best->GetPrev() && prev_OK)) {
+  if ( (next_OK && prev_OK) ||
+       (&in_genotype == best && next_OK) ||
+       (&in_genotype == best->GetPrev() && prev_OK)) {
     return true;
   }
 
@@ -203,29 +203,28 @@
 
 bool cGenotypeControl::Adjust(cGenotype & in_genotype)
 {
-  if (in_genotype.GetDeferAdjust() == true) return true;
-
   cGenotype * cur_genotype = in_genotype.GetPrev();
 
   // Check to see if this genotype should be removed completely.
 
-  if (in_genotype.GetNumOrganisms() == 0) {
+  if (in_genotype.GetNumOrganisms() == 0 &&
+      in_genotype.GetDeferAdjust() == false) {
     genebank.RemoveGenotype(in_genotype);
     return false;
   }
 
-  // Do not adjust if this was and still is the best genotype, or is
-  // otherwise in the proper spot...
+  // 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;
   }
 
-  // Otherwise, remove it from the queue for just the moment.
+  // Otherwise, remove it from the queue (for just the moment).
 
   Remove(in_genotype);
 
-  // Also, if this genotype is the best, put it there.
+  // If this genotype is the best, put it there.
 
   if (in_genotype.GetNumOrganisms() > best->GetNumOrganisms()) {
     Insert(in_genotype, best->GetPrev());

Modified: branches/brysonda/source/main/phenotype.cc
===================================================================
--- branches/brysonda/source/main/phenotype.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/phenotype.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -150,6 +150,7 @@
   // Setup child info...
   copy_true          = false;
   divide_sex         = false;
+  mate_select_id     = -1;
   cross_num          = 0;
   last_child_fertile = is_fertile;
   child_fertile      = true;
@@ -227,7 +228,8 @@
   // Setup child info...
   copy_true         = false;
   divide_sex        = false;
-  cross_num        = 0;
+  mate_select_id    = 0;
+  cross_num         = 0;
   child_fertile     = true;
   last_child_fertile = true;
   child_copied_size = 0;
@@ -300,6 +302,7 @@
   // Reset child info...
   (void) copy_true;
   (void) divide_sex;
+  (void) mate_select_id;
   (void) cross_num;
   last_child_fertile = child_fertile;
   child_fertile     = true;
@@ -385,6 +388,7 @@
   // Reset child info...
   (void) copy_true;
   (void) divide_sex;
+  (void) mate_select_id;
   (void) cross_num;
   (void) child_fertile;
   (void) last_child_fertile;
@@ -471,6 +475,7 @@
   // Setup child info...
   copy_true          = false;
   divide_sex         = false;
+  mate_select_id     = 0;
   cross_num          = 0;
   last_child_fertile = is_fertile;
   child_fertile      = true;
@@ -619,7 +624,8 @@
 
   fp << copy_true           << " ";
   fp << divide_sex          << " ";
-  fp << cross_num          << " ";
+  fp << mate_select_id      << " ";
+  fp << cross_num           << " ";
   fp << child_fertile       << " ";
   fp << last_child_fertile  << " ";
 
@@ -693,6 +699,7 @@
 
   fp >> copy_true;
   fp >> divide_sex;
+  fp >> mate_select_id;
   fp >> cross_num;
   fp >> child_fertile;
   fp >> last_child_fertile;

Modified: branches/brysonda/source/main/phenotype.hh
===================================================================
--- branches/brysonda/source/main/phenotype.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/phenotype.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -118,7 +118,8 @@
   // 6. Child information...
   bool copy_true;        // Can this genome produce an exact copy of itself?
   bool divide_sex;       // Was this child created with a sexual divide?
-  int  cross_num  ;      // How many crossovers should this child do?
+  int mate_select_id;    // If divide sex, who to mate with?
+  int  cross_num  ;      // ...how many crossovers should this child do?
   bool child_fertile;    // Will this organism's next child be fertile?
   bool last_child_fertile;  // Was the child being born to be fertile?
   int child_copied_size; // Instruction copied into child.
@@ -256,6 +257,7 @@
 
   bool CopyTrue() const   { assert(initialized == true); return copy_true; }
   bool DivideSex() const  { assert(initialized == true); return divide_sex; }
+  int MateSelectID() const { assert(initialized == true); return mate_select_id; }
   int  CrossNum() const  { assert(initialized == true); return cross_num; }
   bool  ChildFertile() const
     { assert(initialized == true); return child_fertile;}
@@ -273,6 +275,7 @@
   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; }  
+  void SetMateSelectID(int _select_id) { mate_select_id = _select_id; }
   void SetCrossNum(int _cross_num) { cross_num = _cross_num; }
   void SetToDie() { to_die = true; }
   void SetToDelete() { to_delete = true; }
@@ -299,6 +302,7 @@
   int & ParentCrossNum()  { assert(initialized == true); return parent_cross_num; }
   bool & CopyTrue()   { assert(initialized == true); return copy_true; }
   bool & DivideSex()  { assert(initialized == true); return divide_sex; }
+  int & MateSelectID() { assert(initialized == true); return mate_select_id; }
   int & CrossNum()     { assert(initialized == true); return cross_num; }
   bool & ChildFertile() { assert(initialized == true); return child_fertile; }
   bool & IsMultiThread() { assert(initialized == true); return is_multi_thread; }

Modified: branches/brysonda/source/main/primitive.cc
===================================================================
--- branches/brysonda/source/main/primitive.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/main/primitive.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -42,6 +42,9 @@
 #ifndef HARDWARE_CPU_HH
 #include "hardware_cpu.hh"
 #endif
+#ifndef HARDWARE_SMT_H
+#include "hardware_smt.h"
+#endif
 #ifndef INST_LIB_CPU_HH
 #include "inst_lib_cpu.hh"
 #endif
@@ -78,7 +81,27 @@
   printf( "Avida %s\nCopyright (C) 1993-2003 California Institute of Technology.\n\n", AVIDA_VERSION );
   printf( "Avida comes with ABSOLUTELY NO WARRANTY.\n" );
   printf( "This is free software, and you are welcome to redistribute it\nunder certain conditions. See file COPYING for details.\n\n" );
-
+  
+  
+  cout << "cHardwareCPU InstLib -"
+    << " size: " << cHardwareCPU::GetInstLib()->GetSize()
+    << " num nops: " << cHardwareCPU::GetInstLib()->GetNumNops() 
+    << " last inst name: " << cHardwareCPU::GetInstLib()->GetName(cHardwareCPU::GetInstLib()->GetSize() - 1)
+    << endl;
+	  
+  cout << "cHardware4Stack InstLib -"
+    << " size: " << cHardware4Stack::GetInstLib()->GetSize()
+    << " num nops: " << cHardware4Stack::GetInstLib()->GetNumNops() 
+    << " last inst name: " << cHardware4Stack::GetInstLib()->GetName(cHardware4Stack::GetInstLib()->GetSize() - 1)
+    << endl;
+  
+  cout << "cHardwareSMT InstLib -"
+    << " size: " << cHardwareSMT::GetInstLib()->GetSize()
+    << " num nops: " << cHardwareSMT::GetInstLib()->GetNumNops() 
+    << " last name: " << cHardwareSMT::GetInstLib()->GetName(cHardwareSMT::GetInstLib()->GetSize() - 1)
+    << endl << endl;
+  
+  
   // Initialize the configuration data...
   cConfig::InitGroupList();
   cConfig::Setup(argc, argv);

Modified: branches/brysonda/source/support/genesis
===================================================================
--- branches/brysonda/source/support/genesis	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/support/genesis	2005-08-25 18:43:56 UTC (rev 290)
@@ -3,7 +3,7 @@
 # For more information, see doc/genesis.html
 #############################################################################
 
-VERSION_ID 2.3.0		# Do not change this value!
+VERSION_ID 2.3.1		# Do not change this value!
 
 ### Architecture Variables ###
 MAX_UPDATES  -1         # Maximum updates to run simulation (-1 = no limit)
@@ -36,10 +36,10 @@
 		  # 4 = Replace random from entire population (Mass Action)
 		  # 5 = Replace oldest in entire population (like Tierra)
 PREFER_EMPTY 1    # Are empty cells given preference in offspring placement?
-DEATH_METHOD 0    # 0 = Never die of old age.
+DEATH_METHOD 2    # 0 = Never die of old age.
 		  # 1 = Die when inst executed = AGE_LIMIT (with deviation)
 		  # 2 = Die when inst executed = length * AGE_LIMIT (+ dev.)
-AGE_LIMIT 5000    # Modifies DEATH_METHOD
+AGE_LIMIT 20      # Modifies DEATH_METHOD
 AGE_DEVIATION 0   # Modified DEATH_METHOD
 ALLOC_METHOD 0    # 0 = Allocated space is set to default instruction.
                   # 1 = Set to section of dead genome (Necrophilia)

Modified: branches/brysonda/source/testsuites/functional_testsuites/default.md5sum/genesis
===================================================================
--- branches/brysonda/source/testsuites/functional_testsuites/default.md5sum/genesis	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/testsuites/functional_testsuites/default.md5sum/genesis	2005-08-25 18:43:56 UTC (rev 290)
@@ -3,7 +3,7 @@
 # For more information, see doc/genesis.html
 #############################################################################
 
-VERSION_ID 2.3.0		# Do not change this value!
+VERSION_ID 2.3.1		# Do not change this value!
 
 ### Architecture Variables ###
 MAX_UPDATES  -1         # Maximum updates to run simulation (-1 = no limit)

Modified: branches/brysonda/source/testsuites/functional_testsuites/default.tail/genesis
===================================================================
--- branches/brysonda/source/testsuites/functional_testsuites/default.tail/genesis	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/testsuites/functional_testsuites/default.tail/genesis	2005-08-25 18:43:56 UTC (rev 290)
@@ -3,7 +3,7 @@
 # For more information, see doc/genesis.html
 #############################################################################
 
-VERSION_ID 2.3.0		# Do not change this value!
+VERSION_ID 2.3.1		# Do not change this value!
 
 ### Architecture Variables ###
 MAX_UPDATES  -1         # Maximum updates to run simulation (-1 = no limit)

Modified: branches/brysonda/source/testsuites/functional_testsuites/default.tail.disabled/genesis
===================================================================
--- branches/brysonda/source/testsuites/functional_testsuites/default.tail.disabled/genesis	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/testsuites/functional_testsuites/default.tail.disabled/genesis	2005-08-25 18:43:56 UTC (rev 290)
@@ -3,7 +3,7 @@
 # For more information, see doc/genesis.html
 #############################################################################
 
-VERSION_ID 2.3.0		# Do not change this value!
+VERSION_ID 2.3.1		# Do not change this value!
 
 ### Architecture Variables ###
 MAX_UPDATES  -1         # Maximum updates to run simulation (-1 = no limit)

Modified: branches/brysonda/source/testsuites/functional_testsuites/tedious.tail.disabled/genesis
===================================================================
--- branches/brysonda/source/testsuites/functional_testsuites/tedious.tail.disabled/genesis	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/testsuites/functional_testsuites/tedious.tail.disabled/genesis	2005-08-25 18:43:56 UTC (rev 290)
@@ -3,7 +3,7 @@
 # For more information, see doc/genesis.html
 #############################################################################
 
-VERSION_ID 2.3.0		# Do not change this value!
+VERSION_ID 2.3.1		# Do not change this value!
 
 ### Architecture Variables ###
 MAX_UPDATES  -1         # Maximum updates to run simulation (-1 = no limit)

Modified: branches/brysonda/source/tools/tDictionary.hh
===================================================================
--- branches/brysonda/source/tools/tDictionary.hh	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/tools/tDictionary.hh	2005-08-25 18:43:56 UTC (rev 290)
@@ -166,6 +166,7 @@
 
   int GetSize() { return dict_size; }
   
+  // This function is used to add a new entry...
   void Add(const cString & name, T data) {
     // Build the new entry...
     tDictEntry<T> * new_entry = new tDictEntry<T>;
@@ -189,6 +190,19 @@
     dict_size++;
   }
   
+
+  // This function will change the value of an entry that exists, or add it
+  // if it doesn't exist.
+  void SetValue(const cString & name, T data) {
+    tDictEntry<T> * cur_entry = FindEntry(name);
+    if (cur_entry == NULL) {
+      Add(name, data);
+      return;
+    }
+    cur_entry->data = data;
+  }
+
+
   bool HasEntry(const cString & name) {
     return FindEntry(name) != NULL;
   }

Modified: branches/brysonda/source/tools/tObjectFactory.h
===================================================================
--- branches/brysonda/source/tools/tObjectFactory.h	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/tools/tObjectFactory.h	2005-08-25 18:43:56 UTC (rev 290)
@@ -14,6 +14,10 @@
 #include "tDictionary.hh"
 #endif
 
+#ifndef TLIST_HH
+#include "tList.hh"
+#endif
+
 class cString;
 
 template<typename CtorSignature> class tObjectFactory;
@@ -83,6 +87,17 @@
     
     return NULL;
   }
+  
+  virtual void CreateAll(tList<BaseType>& objects)
+  {
+    tList<cString> names;
+    tList<CreateObjectFunction> funcs;
+    
+    m_create_funcs.AsLists(names, funcs);
+    
+    tListIterator<cString> names_it(names);
+    while (names_it.Next() != NULL) objects.Push(Create(*names_it.Get()));
+  }
 };
 
 template<typename BaseType, typename Arg1Type>

Modified: branches/brysonda/source/viewers/zoom_screen.cc
===================================================================
--- branches/brysonda/source/viewers/zoom_screen.cc	2005-08-25 03:22:34 UTC (rev 289)
+++ branches/brysonda/source/viewers/zoom_screen.cc	2005-08-25 18:43:56 UTC (rev 290)
@@ -435,6 +435,9 @@
 
 void cZoomScreen::Update()
 {
+  if (info.GetActiveCell() == NULL ||
+      info.GetActiveCell()->IsOccupied() == false) return;
+
   cHardwareBase & hardware = info.GetActiveCell()->GetOrganism()->GetHardware();
   if(mode == ZOOM_MODE_CPU) UpdateCPU(hardware);
   else if (mode == ZOOM_MODE_STATS) UpdateStats(hardware);




More information about the Avida-cvs mailing list