[Avida-cvs] [avida-svn] r782 - in development: Avida.xcodeproj source/actions source/analyze source/main source/platform/win32-pthread

brysonda@myxo.css.msu.edu brysonda at myxo.css.msu.edu
Tue Jun 27 19:07:36 PDT 2006


Author: brysonda
Date: 2006-06-27 22:07:36 -0400 (Tue, 27 Jun 2006)
New Revision: 782

Added:
   development/source/main/cMutationalNeighborhood.cc
   development/source/main/cMutationalNeighborhood.h
   development/source/main/cMutationalNeighborhoodResults.h
Modified:
   development/Avida.xcodeproj/project.pbxproj
   development/source/actions/LandscapeActions.cc
   development/source/analyze/cAnalyzeJobQueue.cc
   development/source/analyze/cAnalyzeJobQueue.h
   development/source/main/cLandscape.cc
   development/source/main/cLandscape.h
   development/source/platform/win32-pthread/pthread.h
Log:
Lay the basic foundation for Mutational Neighborhood calculation.  At the moment this is basically a per-site parallelized single-step full landscape.

Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj	2006-06-27 21:15:14 UTC (rev 781)
+++ development/Avida.xcodeproj/project.pbxproj	2006-06-28 02:07:36 UTC (rev 782)
@@ -191,6 +191,7 @@
 		70C054F80A4F704D002703C1 /* PopulationActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70C054C90A4F6E19002703C1 /* PopulationActions.cc */; };
 		70C054F90A4F704E002703C1 /* SaveLoadActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708051A80A1F65FE00CBB8B6 /* SaveLoadActions.cc */; };
 		70C054FA0A4F7053002703C1 /* PopulationActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70C054C90A4F6E19002703C1 /* PopulationActions.cc */; };
+		70C0557D0A50C587002703C1 /* cMutationalNeighborhood.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70C0557A0A50C57E002703C1 /* cMutationalNeighborhood.cc */; };
 		70C1EF4808C393BA00F50912 /* cCodeLabel.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70C1EF4608C393BA00F50912 /* cCodeLabel.cc */; };
 		70C1EF4A08C393BA00F50912 /* cCodeLabel.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70C1EF4608C393BA00F50912 /* cCodeLabel.cc */; };
 		70C1EF5908C3948C00F50912 /* cCPUMemory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70C1EF5808C3948C00F50912 /* cCPUMemory.cc */; };
@@ -447,7 +448,7 @@
 		700E12610A097A0800B604CD /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
 		700E12630A097A1700B604CD /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
 		700E28CF0859FFD700CF158A /* tObjectFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tObjectFactory.h; sourceTree = "<group>"; };
-		700E2B83085DE50C00CF158A /* avida-viewer */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = "avida-viewer"; sourceTree = BUILT_PRODUCTS_DIR; };
+		700E2B83085DE50C00CF158A /* avida-viewer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "avida-viewer"; sourceTree = BUILT_PRODUCTS_DIR; };
 		7013845F09028B3E0087ED2E /* cAvidaConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cAvidaConfig.h; sourceTree = "<group>"; };
 		7013846009028B3E0087ED2E /* cAvidaConfig.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cAvidaConfig.cc; sourceTree = "<group>"; };
 		701384A10902A16F0087ED2E /* defs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = defs.h; sourceTree = "<group>"; };
@@ -747,6 +748,9 @@
 		70C054F50A4F701B002703C1 /* SConscript */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SConscript; sourceTree = "<group>"; };
 		70C054F60A4F7030002703C1 /* SConscript */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SConscript; sourceTree = "<group>"; };
 		70C054F70A4F703D002703C1 /* SConscript */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SConscript; sourceTree = "<group>"; };
+		70C0557A0A50C57E002703C1 /* cMutationalNeighborhood.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cMutationalNeighborhood.cc; sourceTree = "<group>"; };
+		70C0557B0A50C57E002703C1 /* cMutationalNeighborhood.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cMutationalNeighborhood.h; sourceTree = "<group>"; };
+		70C0557C0A50C57E002703C1 /* cMutationalNeighborhoodResults.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cMutationalNeighborhoodResults.h; sourceTree = "<group>"; };
 		70C1EF4608C393BA00F50912 /* cCodeLabel.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cCodeLabel.cc; sourceTree = "<group>"; };
 		70C1EF4708C393BA00F50912 /* cCodeLabel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cCodeLabel.h; sourceTree = "<group>"; };
 		70C1EF5808C3948C00F50912 /* cCPUMemory.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cCPUMemory.cc; sourceTree = "<group>"; };
@@ -1375,6 +1379,9 @@
 		DCC310040762539D008F7A48 /* main */ = {
 			isa = PBXGroup;
 			children = (
+				70C0557A0A50C57E002703C1 /* cMutationalNeighborhood.cc */,
+				70C0557B0A50C57E002703C1 /* cMutationalNeighborhood.h */,
+				70C0557C0A50C57E002703C1 /* cMutationalNeighborhoodResults.h */,
 				703CA36F0A5072B700AB4DB4 /* SConscript */,
 				DCC3109C0762539E008F7A48 /* avida.cc */,
 				70B086BE08F5D86100FC65FE /* avida.h */,
@@ -2219,6 +2226,7 @@
 				708051B20A1F663100CBB8B6 /* SaveLoadActions.cc in Sources */,
 				708051BB0A1F66B400CBB8B6 /* cActionLibrary.cc in Sources */,
 				70C054ED0A4F6FD2002703C1 /* PopulationActions.cc in Sources */,
+				70C0557D0A50C587002703C1 /* cMutationalNeighborhood.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: development/source/actions/LandscapeActions.cc
===================================================================
--- development/source/actions/LandscapeActions.cc	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/actions/LandscapeActions.cc	2006-06-28 02:07:36 UTC (rev 782)
@@ -19,6 +19,8 @@
 #include "cGenotypeBatch.h"
 #include "cHardwareManager.h"
 #include "cLandscape.h"
+#include "cMutationalNeighborhood.h"
+#include "cMutationalNeighborhoodResults.h"
 #include "cStats.h"
 #include "cString.h"
 #include "cWorld.h"
@@ -214,7 +216,7 @@
       tListIterator<cAnalyzeGenotype> batch_it(m_world->GetAnalyze().GetCurrentBatch().List());
       cAnalyzeGenotype* genotype = NULL;
       while (genotype = batch_it.Next()) {
-        cLandscape* land = new cLandscape(m_world, genotype->GetGenome(), inst_set);
+        land = new cLandscape(m_world, genotype->GetGenome(), inst_set);
         land->SetDistance(m_dist);
         m_batch.PushRear(land);
         jobqueue.AddJob(new tAnalyzeJob<cLandscape>(land, &cLandscape::Process));
@@ -382,6 +384,73 @@
 };
 
 
+class cActionMutationalNeighborhood : public cAction
+{
+private:
+  cString m_filename;
+  tList<cMutationalNeighborhood> m_batch;
+  
+public:
+  cActionMutationalNeighborhood(cWorld* world, const cString& args)
+    : cAction(world, args), m_filename("mut-neighborhood.dat")
+  {
+      cString largs(args);
+      if (largs.GetSize()) m_filename = largs.PopWord();
+  }
+  
+  const cString GetDescription()
+  {
+    return "MutationalNeighborhood [filename='mut-neighborhood.dat']";
+  }
+  
+  void Process(cAvidaContext& ctx)
+  {
+    int update = -1;
+    cMutationalNeighborhood* mutn = NULL;
+    cInstSet& inst_set = m_world->GetHardwareManager().GetInstSet();
+    
+    if (ctx.GetAnalyzeMode()) {
+      if (m_world->GetConfig().VERBOSITY.Get() >= VERBOSE_ON) {
+        cString msg("Calculating Mutational Neighborhood for batch ");
+        msg += cStringUtil::Convert(m_world->GetAnalyze().GetCurrentBatchID());
+        m_world->GetDriver().NotifyComment(msg);
+      } else if (m_world->GetConfig().VERBOSITY.Get() > VERBOSE_SILENT) {
+        m_world->GetDriver().NotifyComment("Calculating Mutational Neighborhood...");
+      }
+
+      cAnalyzeJobQueue& jobqueue = m_world->GetAnalyze().GetJobQueue();
+      tListIterator<cAnalyzeGenotype> batch_it(m_world->GetAnalyze().GetCurrentBatch().List());
+      cAnalyzeGenotype* genotype = NULL;
+      while (genotype = batch_it.Next()) {
+        mutn = new cMutationalNeighborhood(m_world, genotype->GetGenome(), inst_set);
+        m_batch.PushRear(mutn);
+        jobqueue.AddJob(new tAnalyzeJob<cMutationalNeighborhood>(mutn, &cMutationalNeighborhood::Process));
+      }
+      jobqueue.Execute();
+    } else {
+      if (m_world->GetConfig().VERBOSITY.Get() >= VERBOSE_DETAILS)
+        m_world->GetDriver().NotifyComment("Full Landscaping...");
+      
+      const cGenome& best_genome = m_world->GetClassificationManager().GetBestGenotype()->GetGenome();
+      mutn = new cMutationalNeighborhood(m_world, best_genome, inst_set);
+
+      m_batch.PushRear(mutn);
+      mutn->Process(ctx);
+      update = m_world->GetStats().GetUpdate();      
+    }
+    
+    cMutationalNeighborhoodResults* results = NULL;
+    cDataFile& df = m_world->GetDataFile(m_filename);
+    while (mutn = m_batch.Pop()) {
+      results = new cMutationalNeighborhoodResults(mutn);
+      results->PrintStats(df, update);
+      delete results;
+      delete mutn;
+    }
+  }
+};
+
+
 void RegisterLandscapeActions(cActionLibrary* action_lib)
 {
   action_lib->Register<cActionAnalyzeLandscape>("AnalyzeLandscape");
@@ -389,4 +458,5 @@
   action_lib->Register<cActionFullLandscape>("FullLandscape");
   action_lib->Register<cActionRandomLandscape>("RandomLandscape");
   action_lib->Register<cActionSampleLandscape>("SampleLandscape");
+  action_lib->Register<cActionMutationalNeighborhood>("MutationalNeighborhood");
 }

Modified: development/source/analyze/cAnalyzeJobQueue.cc
===================================================================
--- development/source/analyze/cAnalyzeJobQueue.cc	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/analyze/cAnalyzeJobQueue.cc	2006-06-28 02:07:36 UTC (rev 782)
@@ -81,6 +81,15 @@
 }
 
 
+void cAnalyzeJobQueue::Start()
+{
+  if (m_world->GetConfig().VERBOSITY.Get() >= VERBOSE_DETAILS)
+    m_world->GetDriver().NotifyComment("waking worker threads...");
+
+  pthread_cond_broadcast(&m_cond);
+}
+
+
 void cAnalyzeJobQueue::Execute()
 {
   if (m_world->GetConfig().VERBOSITY.Get() >= VERBOSE_DETAILS)

Modified: development/source/analyze/cAnalyzeJobQueue.h
===================================================================
--- development/source/analyze/cAnalyzeJobQueue.h	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/analyze/cAnalyzeJobQueue.h	2006-06-28 02:07:36 UTC (rev 782)
@@ -63,6 +63,7 @@
   void AddJob(cAnalyzeJob* job);
   void AddJobImmediate(cAnalyzeJob* job);
 
+  void Start();
   void Execute();
   
   cRandom* GetRandom(int jobid) { return m_rng_pool[jobid & MT_RANDOM_INDEX_MASK]; } 

Modified: development/source/main/cLandscape.cc
===================================================================
--- development/source/main/cLandscape.cc	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/main/cLandscape.cc	2006-06-28 02:07:36 UTC (rev 782)
@@ -48,8 +48,6 @@
   total_fitness   = 0.0;
   total_sqr_fitness = 0.0;
   distance        = 0;
-  del_distance    = 0;
-  ins_distance    = 0;
   trials          = 0;
   
   total_count   = 0;
@@ -87,7 +85,7 @@
 {
   testcpu->TestGenome(ctx, test_info, in_genome);
   
-  test_fitness = test_info.GetColonyFitness();
+  double test_fitness = test_info.GetColonyFitness();
   
   total_fitness += test_fitness;
   total_sqr_fitness += test_fitness * test_fitness;

Modified: development/source/main/cLandscape.h
===================================================================
--- development/source/main/cLandscape.h	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/main/cLandscape.h	2006-06-28 02:07:36 UTC (rev 782)
@@ -46,8 +46,6 @@
   double total_sqr_fitness;
 
   int distance;
-  int del_distance;
-  int ins_distance;
 
   int trials;
   int m_min_found;
@@ -73,9 +71,6 @@
   double neg_epi_size; 
   double no_epi_size; 
 
-
-  double test_fitness;
-
   int * site_count;
 
   double total_entropy;

Added: development/source/main/cMutationalNeighborhood.cc
===================================================================
--- development/source/main/cMutationalNeighborhood.cc	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/main/cMutationalNeighborhood.cc	2006-06-28 02:07:36 UTC (rev 782)
@@ -0,0 +1,302 @@
+/*
+ *  cMutationalNeighborhood.cc
+ *  Avida
+ *
+ *  Created by David on 6/13/06.
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+#include "cMutationalNeighborhood.h"
+
+#include "cAnalyze.h"
+#include "cAnalyzeJobQueue.h"
+#include "cCPUTestInfo.h"
+#include "cCPUMemory.h"
+#include "cEnvironment.h"
+#include "cInstSet.h"
+#include "cHardwareManager.h"
+#include "cOrganism.h"
+#include "cPhenotype.h"
+#include "cStats.h"             // For GetUpdate in outputs...
+#include "cTestCPU.h"
+#include "cTestUtil.h"
+#include "cTools.h"
+#include "cWorld.h"
+#include "tAnalyzeJob.h"
+
+using namespace std;
+
+
+void cMutationalNeighborhood::Process(cAvidaContext& ctx)
+{
+  pthread_mutex_lock(&m_mutex);
+  if (m_initialized) {
+    int cur_site = m_cur_site++;
+    pthread_mutex_unlock(&m_mutex);
+
+    if (cur_site < m_base_genome.GetSize()) {
+      // Create test infrastructure
+      cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
+      cCPUTestInfo test_info;
+      
+      // Setup One Step Data
+      sOneStep& odata = m_onestep[cur_site];
+      odata.peak_fitness = m_base_fitness;
+      odata.peak_genome = m_base_genome;
+      odata.fitness.Resize(m_inst_set.GetSize(), 0.0);
+      odata.site_count.Resize(m_base_genome.GetSize(), 0);
+
+      // Setup Data Used in Two Step
+      sTwoStep& tdata = m_twostep[cur_site];
+      tdata.peak_fitness = m_base_fitness;
+      tdata.peak_genome = m_base_genome;
+      tdata.site_count.Resize(m_base_genome.GetSize(), 0);
+
+      // Do the processing, starting with One Step
+      ProcessOneStep(ctx, testcpu, test_info, cur_site);
+
+      // Cleanup
+      delete testcpu;
+    }
+  } else {
+    ProcessInitialize(ctx);
+    return;
+  }
+  
+  pthread_mutex_lock(&m_mutex);
+  if (++m_completed == m_base_genome.GetSize()) ProcessComplete(ctx); 
+  pthread_mutex_unlock(&m_mutex);
+}
+
+
+void cMutationalNeighborhood::ProcessInitialize(cAvidaContext& ctx)
+{
+  // Generate base information
+  cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
+  cCPUTestInfo test_info;
+  testcpu->TestGenome(ctx, test_info, m_base_genome);
+  
+  cPhenotype& phenotype = test_info.GetColonyOrganism()->GetPhenotype();
+  m_base_fitness = test_info.GetColonyFitness();
+  m_base_merit = phenotype.GetMerit().GetDouble();
+  m_base_gestation = phenotype.GetGestationTime();
+  m_base_tasks = phenotype.GetLastTaskCount();
+  
+  m_neut_min = m_base_fitness * nHardware::FITNESS_NEUTRAL_MIN;
+  m_neut_max = m_base_fitness * nHardware::FITNESS_NEUTRAL_MAX;
+  
+  delete testcpu;
+
+  // Setup state to begin processing
+  m_onestep.ResizeClear(m_base_genome.GetSize());
+  m_twostep.ResizeClear(m_base_genome.GetSize());
+  
+  m_cur_site = 0;
+  m_completed = 0;
+  m_initialized = true;
+  
+  // Unlock internal mutex (was locked on Process() entrance)
+  //  - will allow workers to begin processing if job queue already active
+  pthread_mutex_unlock(&m_mutex);
+  
+  // Load enough jobs to process all sites
+  cAnalyzeJobQueue& jobqueue = m_world->GetAnalyze().GetJobQueue();
+  for (int i = 0; i < m_base_genome.GetSize(); i++)
+    jobqueue.AddJob(new tAnalyzeJob<cMutationalNeighborhood>(this, &cMutationalNeighborhood::Process));
+  
+  jobqueue.Start();
+}
+
+
+void cMutationalNeighborhood::ProcessOneStep(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info, int cur_site)
+{
+  const int inst_size = m_inst_set.GetSize();
+  sOneStep& odata = m_onestep[cur_site];
+  
+  cGenome mod_genome(m_base_genome);
+  
+  // Loop through all the lines of genome, testing trying all combinations.
+  int cur_inst = mod_genome[cur_site].GetOp();
+  
+  // Loop through all instructions...
+  for (int inst_num = 0; inst_num < inst_size; inst_num++) {
+    if (cur_inst == inst_num) continue;
+    
+    mod_genome[cur_site].SetOp(inst_num);
+    testcpu->TestGenome(ctx, test_info, mod_genome);
+    
+    double test_fitness = test_info.GetColonyFitness();
+    
+    odata.total_fitness += test_fitness;
+    odata.total_sqr_fitness += test_fitness * test_fitness;
+    odata.total++;
+    if (test_fitness == 0.0) {
+      odata.dead++;
+    } else if (test_fitness < m_neut_min) {
+      odata.neg++;
+      odata.size_neg += test_fitness;
+    } else if (test_fitness <= m_neut_max) {
+      odata.neut++;
+    } else {
+      odata.pos++;
+      odata.size_pos += test_fitness;
+      if (test_fitness > odata.peak_fitness) {
+        odata.peak_fitness = test_fitness;
+        odata.peak_genome = mod_genome;
+      }
+    }
+    
+    if (test_fitness >= m_neut_min) odata.site_count[cur_site]++;
+    
+    odata.fitness[cur_inst] = test_fitness;
+    odata.cur_tasks = test_info.GetColonyOrganism()->GetPhenotype().GetLastTaskCount();
+    
+    // @TODO - calculate task values
+
+    //ProcessTwoStep(ctx, testcpu, test_info, cur_site, mod_genome);
+  }
+}
+
+void cMutationalNeighborhood::ProcessTwoStep(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info, int cur_site, cGenome& mod_genome)
+{
+  const int inst_size = m_inst_set.GetSize();
+  sOneStep& odata = m_onestep[cur_site];
+  sTwoStep& tdata = m_twostep[cur_site];
+
+  // Loop through remaining lines of genome, testing trying all combinations.
+  for (int line_num = cur_site + 1; line_num < m_base_genome.GetSize(); line_num++) {
+    int cur_inst = mod_genome[line_num].GetOp();
+    
+    // Loop through all instructions...
+    for (int inst_num = 0; inst_num < inst_size; inst_num++) {
+      if (cur_inst == inst_num) continue;
+      
+      mod_genome[line_num].SetOp(inst_num);
+      testcpu->TestGenome(ctx, test_info, mod_genome);
+      
+      double test_fitness = test_info.GetColonyFitness();
+      
+      tdata.total_fitness += test_fitness;
+      tdata.total_sqr_fitness += test_fitness * test_fitness;
+      tdata.total++;
+      if (test_fitness == 0.0) {
+        tdata.dead++;
+      } else if (test_fitness < m_neut_min) {
+        tdata.neg++;
+        tdata.size_neg += test_fitness;
+      } else if (test_fitness <= m_neut_max) {
+        tdata.neut++;
+      } else {
+        tdata.pos++;
+        tdata.size_pos += test_fitness;
+        if (test_fitness > tdata.peak_fitness) {
+          tdata.peak_fitness = test_fitness;
+          tdata.peak_genome = mod_genome;
+        }
+      }
+      
+      if (test_fitness >= m_neut_min) tdata.site_count[line_num]++;
+      
+      // @TODO - calculate task values
+    }
+    
+    mod_genome[line_num].SetOp(cur_inst);
+  }
+}
+
+
+void cMutationalNeighborhood::ProcessComplete(cAvidaContext& ctx)
+{
+  // Initialize values
+  m_total = 0;
+  m_total_sqr_fitness = 0.0;
+  m_dead = 0;
+  m_neg = 0;
+  m_neut = 0;
+  m_pos = 0;
+  m_size_pos = 0.0;
+  m_size_neg = 0.0;
+  m_peak_fitness = m_base_fitness;
+  m_peak_genome = m_base_genome;  
+  m_site_count.Resize(m_base_genome.GetSize(), 0);
+
+  for (int i = 0; i < m_onestep.GetSize(); i++) {
+    sOneStep& odata = m_onestep[i];
+    m_total += odata.total;
+    m_total_fitness += odata.total_fitness;
+    m_total_sqr_fitness += odata.total_sqr_fitness;
+    m_dead += odata.dead;
+    m_neg += odata.neg;
+    m_neut += odata.neut;
+    m_pos += odata.pos;
+    m_size_pos += odata.size_pos; 
+    m_size_neg += odata.size_neg; 
+  
+    if (odata.peak_fitness > m_peak_fitness) {
+      m_peak_genome = odata.peak_genome;
+      m_peak_fitness = odata.peak_fitness;
+    }
+  
+  
+    for (int j = 0; j < m_site_count.GetSize(); j++) {
+      m_site_count[j] += odata.site_count[j];
+    }
+      
+    // @TODO - aggregate task data
+  }
+  
+  double max_ent = log(static_cast<double>(m_inst_set.GetSize()));
+  m_total_entropy = 0;
+  for (int i = 0; i < m_base_genome.GetSize(); i++) {
+    // Per-site entropy is the log of the number of legal states for that
+    // site.  Add one to account for the unmutated state.
+    m_total_entropy += log(static_cast<double>(m_site_count[i] + 1)) / max_ent;
+  }
+  m_complexity = m_base_genome.GetSize() - m_total_entropy;
+  
+  
+  // @TODO - aggregate two step task data
+
+  
+  pthread_rwlock_unlock(&m_rwlock);
+}
+
+
+void cMutationalNeighborhood::PrintStats(cDataFile& df, int update)
+{
+  df.Write(update, "Update");
+  df.Write(m_base_fitness, "Base Fitness");
+  df.Write(m_base_merit, "Base Merit");
+  df.Write(m_base_gestation, "Base Gestation");
+  df.Write(m_total, "Total One Step Mutants");
+  df.Write(GetProbDead(), "One Step Probability Dead");
+  df.Write(GetProbNeg(), "One Step Probability Deleterious");
+  df.Write(GetProbNeut(), "One Step Probability Neutral");
+  df.Write(GetProbPos(), "One Step Probability Positive");
+  df.Write(GetAvPosSize(), "One Step Average Positive Size");
+  df.Write(GetAvNegSize(), "One Step Average Negative Size");
+  df.Write(m_peak_fitness, "One Step Peak Fitness");
+  df.Write(GetAveFitness(), "One Step Average Fitness");
+  df.Write(GetAveSqrFitness(), "One Step Average Square Fitness");
+  df.Write(m_total_entropy, "One Step Total Entropy");
+  df.Write(m_complexity, "One Step Total Complexity");
+  df.Endl();
+}
+
+void cMutationalNeighborhood::PrintEntropy(cDataFile& df)
+{
+  double max_ent = log(static_cast<double>(m_inst_set.GetSize()));
+  for (int j = 0; j < m_base_genome.GetSize(); j++) {
+    df.Write(log(static_cast<double>(m_site_count[j] + 1)) / max_ent, " ");
+  }
+  df.Endl();
+}
+
+void cMutationalNeighborhood::PrintSiteCount(cDataFile& df)
+{
+  for (int j = 0; j < m_base_genome.GetSize(); j++) {
+    df.Write(m_site_count[j], " ");
+  }
+  df.Endl();
+}

Added: development/source/main/cMutationalNeighborhood.h
===================================================================
--- development/source/main/cMutationalNeighborhood.h	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/main/cMutationalNeighborhood.h	2006-06-28 02:07:36 UTC (rev 782)
@@ -0,0 +1,250 @@
+/*
+ *  cMutationalNeighborhood.h
+ *  Avida
+ *
+ *  Created by David on 6/13/06.
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+#ifndef cMutationalNeighborhood_h
+#define cMutationalNeighborhood_h
+
+#ifndef cGenome_h
+#include "cGenome.h"
+#endif
+#ifndef cString_h
+#include "cString.h"
+#endif
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+#include <pthread.h>
+
+class cAvidaContext;
+class cCPUTestInfo;
+class cDataFile;
+class cInstSet;
+class cInstruction;
+class cTestCPU;
+class cWorld;
+
+
+class cMutationalNeighborhood
+{
+  friend class cMutationalNeighborhoodResults;
+  
+private:
+  cWorld* m_world;
+  
+  // Internal state information
+  // --------------------------------------------------------------------------
+  pthread_rwlock_t m_rwlock;
+  pthread_mutex_t m_mutex;
+  
+  bool m_initialized;
+  int m_cur_site;
+  int m_completed;
+  
+  struct sOneStep
+  {
+    int total;
+    
+    double total_fitness;
+    double total_sqr_fitness;
+    cGenome peak_genome;
+    double peak_fitness;
+    
+    int dead;
+    int neg;
+    int neut;
+    int pos;
+    double size_pos;
+    double size_neg;
+    
+    tArray<int> site_count;
+    
+    int task_target;
+    int task_total;
+    int task_knockout;
+
+    // state used in two step calculations
+    tArray<double> fitness;
+    tArray<int> cur_tasks;
+    
+    sOneStep() : total(0), total_fitness(0.0), total_sqr_fitness(0.0), peak_fitness(0.0), dead(0), neg(0), neut(0), pos(0),
+      size_pos(0.0), size_neg(0.0), task_target(0), task_total(0), task_knockout(0) { ; }
+  };
+  tArray<sOneStep> m_onestep;
+  
+  struct sTwoStep
+  {
+    int total;
+    
+    double total_fitness;
+    double total_sqr_fitness;
+    cGenome peak_genome;
+    double peak_fitness;
+    
+    int dead;
+    int neg;
+    int neut;
+    int pos;
+    double size_pos;
+    double size_neg;
+    
+    tArray<int> site_count;
+    
+    int task_target;
+    int task_target_pos;
+    int task_target_neg;
+    int task_target_neut;
+    int task_target_dead;
+    int task_total;
+    int task_knockout;
+    
+    sTwoStep() : total(0), total_fitness(0.0), total_sqr_fitness(0.0), peak_fitness(0.0), dead(0), neg(0), neut(0), pos(0),
+      size_pos(0.0), size_neg(0.0), task_target(0), task_target_pos(0), task_target_neg(0), task_target_dead(0),
+      task_total(0), task_knockout(0) { ; }
+  };
+  tArray<sTwoStep> m_twostep;
+  
+  const cInstSet& m_inst_set;
+  
+  // Base data
+  // --------------------------------------------------------------------------
+  cGenome m_base_genome;
+  double m_base_fitness;
+  double m_base_merit;
+  double m_base_gestation;
+  tArray<int> m_base_tasks;
+  double m_neut_min;  // These two variables are a range around the base
+  double m_neut_max;  //   fitness to be counted as neutral mutations.
+  
+  // Aggregated data
+  // --------------------------------------------------------------------------
+  int m_total;
+
+  double m_total_fitness;
+  double m_total_sqr_fitness;
+  cGenome m_peak_genome;
+  double m_peak_fitness;
+  
+  int m_dead;
+  int m_neg;
+  int m_neut;
+  int m_pos;
+  double m_size_pos; 
+  double m_size_neg; 
+  
+  tArray<int> m_site_count;
+  
+  double m_total_entropy;
+  double m_complexity;
+  
+  // Single step task totals
+  int m_stask_target;
+  int m_stask_total;
+  int m_stask_knockout;
+  
+  // Two step task totals
+  int m_ttask_target;
+  int m_ttask_target_pos;
+  int m_ttask_target_neg;
+  int m_ttask_target_neut;
+  int m_ttask_target_dead;
+  int m_ttask_total;
+  int m_ttask_knockout;
+
+
+  void ProcessInitialize(cAvidaContext& ctx);
+  void ProcessOneStep(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info, int cur_site);
+  void ProcessTwoStep(cAvidaContext& ctx, cTestCPU* testcpu, cCPUTestInfo& test_info, int cur_site, cGenome& mod_genome);
+  void ProcessComplete(cAvidaContext& ctx);
+  
+  cMutationalNeighborhood(); // @not_implemented
+  cMutationalNeighborhood(const cMutationalNeighborhood&); // @not_implemented
+  cMutationalNeighborhood& operator=(const cMutationalNeighborhood&); // @not_implemented
+  
+public:
+  cMutationalNeighborhood(cWorld* world, const cGenome& genome, const cInstSet& inst_set)
+  : m_world(world), m_initialized(false), m_inst_set(inst_set), m_base_genome(genome)
+  {
+    pthread_rwlock_init(&m_rwlock, NULL);
+    pthread_mutex_init(&m_mutex, NULL);
+    
+    // Acquire write lock, to prevent any Results instances before computing
+    pthread_rwlock_wrlock(&m_rwlock);
+  }
+  ~cMutationalNeighborhood()
+  {
+    pthread_rwlock_destroy(&m_rwlock);
+    pthread_mutex_destroy(&m_mutex);
+  }
+  
+  void Process(cAvidaContext& ctx);
+
+  
+// These methods can only be accessed via a cMutationalNeighborhoodResults object
+private:
+  void PrintStats(cDataFile& df, int update = -1);
+  void PrintEntropy(cDataFile& df);
+  void PrintSiteCount(cDataFile& df);
+  
+  inline const cGenome& GetBaseGenome() const { return m_base_genome; }
+  inline double GetBaseFitness() const { return m_base_fitness; }
+  
+  inline int GetTotal() const { return m_total; }
+  
+  inline double GetAveFitness() const { return m_total_fitness / m_total; }
+  inline double GetAveSqrFitness() const { return m_total_sqr_fitness / m_total; }
+  inline const cGenome& GetPeakGenome() const { return m_peak_genome; }
+  inline double GetPeakFitness() const { return m_peak_fitness; }
+  
+  inline double GetProbDead() const { return static_cast<double>(m_dead) / m_total; }
+  inline double GetProbNeg()  const { return static_cast<double>(m_neg) / m_total; }
+  inline double GetProbNeut() const { return static_cast<double>(m_neut) / m_total; }
+  inline double GetProbPos()  const { return static_cast<double>(m_pos) / m_total; }
+  inline double GetAvPosSize() const { if (m_pos == 0) return 0.0; else return m_size_pos / m_pos; }
+  inline double GetAvNegSize() const { if (m_neg == 0) return 0.0; else return m_size_neg / m_neg; }
+  
+  inline double GetTotalEntropy() const { return m_total_entropy; }
+  inline double GetComplexity() const { return m_complexity; }
+  
+  inline int GetSingleTargetTask() const { return m_stask_target; }
+  inline double GetProbSingleTargetTask() const { return static_cast<double>(m_stask_target) / m_total; }
+  inline int GetSingleTask() const { return m_stask_total; }
+  inline double GetProbSingleTask() const { return static_cast<double>(m_stask_total) / m_total; }
+  inline int GetSingleKnockout() const { return m_stask_knockout; }
+  inline double GetProbSingleKnockout() const { return static_cast<double>(m_stask_knockout) / m_total; }
+
+  inline int GetDoubleTargetTask() const { return m_ttask_target; }
+  inline double GetProbDoubleTargetTask() const { return static_cast<double>(m_ttask_target) / m_total; }
+  inline int GetDoubleTargetTaskPos() const { return m_ttask_target_pos; }
+  inline double GetProbDoubleTargetTaskPos() const { return static_cast<double>(m_ttask_target_pos) / m_total; }
+  inline int GetDoubleTargetTaskNeg() const { return m_ttask_target_neg; }
+  inline double GetProbDoubleTargetTaskNeg() const { return static_cast<double>(m_ttask_target_neg) / m_total; }
+  inline int GetDoubleTargetTaskNeut() const { return m_ttask_target_neut; }
+  inline double GetProbDoubleTargetTaskNeut() const { return static_cast<double>(m_ttask_target_neut) / m_total; }
+  inline int GetDoubleTargetTaskDead() const { return m_ttask_target_dead; }
+  inline double GetProbDoubleTargetTaskDead() const { return static_cast<double>(m_ttask_target_dead) / m_total; }
+  inline int GetDoubleTask() const { return m_stask_total; }
+  inline double GetProbDoubleTask() const { return static_cast<double>(m_stask_total) / m_total; }
+  inline int GetDoubleKnockout() const { return m_stask_knockout; }
+  inline double GetProbDoubleKnockout() const { return static_cast<double>(m_stask_knockout) / m_total; }
+};
+
+
+#ifdef ENABLE_UNIT_TESTS
+namespace nMutationalNeighborhood {
+  /**
+  * Run unit tests
+   *
+   * @param full Run full test suite; if false, just the fast tests.
+   **/
+  void UnitTests(bool full = false);
+}
+#endif  
+
+#endif

Added: development/source/main/cMutationalNeighborhoodResults.h
===================================================================
--- development/source/main/cMutationalNeighborhoodResults.h	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/main/cMutationalNeighborhoodResults.h	2006-06-28 02:07:36 UTC (rev 782)
@@ -0,0 +1,88 @@
+/*
+ *  cMutationalNeighborhoodResults.h
+ *  Avida
+ *
+ *  Created by David Bryson on 6/21/06.
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+#ifndef cMutationalNeighborhoodResults_h
+#define cMutationalNeighborhoodResults_h
+
+#ifndef cMutationalNeighborhood_h
+#include "cMutationalNeighborhood.h"
+#endif
+
+class cMutationalNeighborhoodResults
+{
+private:
+  cMutationalNeighborhood& m_src;
+
+  cMutationalNeighborhoodResults(); // @not_implemented
+  cMutationalNeighborhoodResults(const cMutationalNeighborhood&); // @not_implemented
+  cMutationalNeighborhoodResults& operator=(const cMutationalNeighborhoodResults&); // @not_implemented
+  
+public:
+  cMutationalNeighborhoodResults(cMutationalNeighborhood& src) : m_src(src)
+  {
+    pthread_rwlock_rdlock(&m_src.m_rwlock);
+  }
+  cMutationalNeighborhoodResults(cMutationalNeighborhood* src) : m_src(*src)
+  {
+    pthread_rwlock_rdlock(&m_src.m_rwlock);
+  }
+  
+  ~cMutationalNeighborhoodResults()
+  {
+    pthread_rwlock_unlock(&m_src.m_rwlock);
+  }
+  
+  inline void PrintStats(cDataFile& df, int update = -1) const { m_src.PrintStats(df, update); }
+  inline void PrintEntropy(cDataFile& df) const { m_src.PrintEntropy(df); }
+  inline void PrintSiteCount(cDataFile& df) const { m_src.PrintSiteCount(df); }
+  
+  inline const cGenome& GetBaseGenome() const { return m_src.GetBaseGenome(); }
+  inline double GetBaseFitness() const { return m_src.GetBaseFitness(); }
+  
+  inline int GetTotal() const { return m_src.GetTotal(); }
+  
+  inline double GetAveFitness() const { return m_src.GetAveFitness(); }
+  inline double GetAveSqrFitness() const { return m_src.GetAveSqrFitness(); }
+  inline const cGenome& GetPeakGenome() const { return m_src.GetPeakGenome(); }
+  inline double GetPeakFitness() const { return m_src.GetPeakFitness(); }
+
+  inline double GetProbDead() const { return m_src.GetProbDead(); }
+  inline double GetProbNeg() const { return m_src.GetProbNeg(); }
+  inline double GetProbNeut() const { return m_src.GetProbNeut(); }
+  inline double GetProbPos() const { return m_src.GetProbPos(); }
+  inline double GetAvPosSize() const { return m_src.GetAvPosSize(); }
+  inline double GetAvNegSize() const { return m_src.GetAvNegSize(); }
+
+  inline double GetTotalEntropy() const { return m_src.GetTotalEntropy(); }
+  inline double GetComplexity() const { return m_src.GetComplexity(); }
+
+  inline int GetSingleTargetTask() const { return m_src.GetSingleTargetTask(); }
+  inline double GetProbSingleTargetTask() const { return m_src.GetProbSingleTargetTask(); }
+  inline int GetSingleTask() const { return m_src.GetProbSingleTask(); }
+  inline double GetProbSingleTask() const { return m_src.GetProbSingleTask(); }
+  inline int GetSingleKnockout() const { return m_src.GetSingleKnockout(); }
+  inline double GetProbSingleKnockout() const { return m_src.GetProbSingleKnockout(); }
+
+  inline int GetDoubleTargetTask() const { return m_src.GetDoubleTargetTask(); }
+  inline double GetProbDoubleTargetTask() const { return m_src.GetProbDoubleTargetTask(); }
+  inline int GetDoubleTargetTaskPos() const { return m_src.GetDoubleTargetTaskPos(); }
+  inline double GetProbDoubleTargetTaskPos() const { return m_src.GetProbDoubleTargetTaskPos(); }
+  inline int GetDoubleTargetTaskNeg() const { return m_src.GetDoubleTargetTaskNeg(); }
+  inline double GetProbDoubleTargetTaskNeg() const { return m_src.GetProbDoubleTargetTaskNeg(); }
+  inline int GetDoubleTargetTaskNeut() const { return m_src.GetDoubleTargetTaskNeut(); }
+  inline double GetProbDoubleTargetTaskNeut() const { return m_src.GetProbDoubleTargetTaskNeut(); }
+  inline int GetDoubleTargetTaskDead() const { return m_src.GetDoubleTargetTaskDead(); }
+  inline double GetProbDoubleTargetTaskDead() const { return m_src.GetProbDoubleTargetTaskDead(); }
+  inline int GetDoubleTask() const { return m_src.GetProbDoubleTask(); }
+  inline double GetProbDoubleTask() const { return m_src.GetProbDoubleTask(); }
+  inline int GetDoubleKnockout() const { return m_src.GetDoubleKnockout(); }
+  inline double GetProbDoubleKnockout() const { return m_src.GetProbDoubleKnockout(); }  
+};
+
+#endif

Modified: development/source/platform/win32-pthread/pthread.h
===================================================================
--- development/source/platform/win32-pthread/pthread.h	2006-06-27 21:15:14 UTC (rev 781)
+++ development/source/platform/win32-pthread/pthread.h	2006-06-28 02:07:36 UTC (rev 782)
@@ -28,6 +28,14 @@
 #define pthread_cond_broadcast(x)
 #define pthread_cond_destroy(x)
 
+// Just define away rwlock support
+#define pthread_rwlock_t int
+#define pthread_rwlock_init(x, y)
+#define pthread_rwlock_rdlock(x)
+#define pthread_rwlock_wrlock(x)
+#define pthread_rwlock_unlock(x)
+#define pthread_rwlock_destroy(x)
+
 // Define away pthread support
 #define pthread_t int
 #define pthread_exit(x)




More information about the Avida-cvs mailing list