[Avida-SVN] r1155 - in branches/coopcomm: Avida.xcodeproj source/actions source/cpu source/main source/tools

dknoester at myxo.css.msu.edu dknoester at myxo.css.msu.edu
Wed Dec 27 10:27:00 PST 2006


Author: dknoester
Date: 2006-12-27 13:26:59 -0500 (Wed, 27 Dec 2006)
New Revision: 1155

Added:
   branches/coopcomm/source/tools/cTopology.h
Modified:
   branches/coopcomm/Avida.xcodeproj/project.pbxproj
   branches/coopcomm/source/actions/PopulationActions.cc
   branches/coopcomm/source/actions/PrintActions.cc
   branches/coopcomm/source/cpu/cHardwareCPU.cc
   branches/coopcomm/source/cpu/cHardwareCPU.h
   branches/coopcomm/source/main/cPopulation.cc
   branches/coopcomm/source/main/cPopulation.h
   branches/coopcomm/source/main/cPopulationCell.cc
   branches/coopcomm/source/main/cStats.cc
   branches/coopcomm/source/main/cStats.h
   branches/coopcomm/source/main/cWorld.h
   branches/coopcomm/source/main/nGeometry.h
   branches/coopcomm/source/tools/tArray.h
Log:
- Refactored cPopulation::SetupDemes into the default cPopulation constructor, based on the observation that 0 demes == 1 deme == 1 population.  cPopulation::SetupDemes is now dead code, but left in Avida for reference (hopefully not for debugging).

- Refactored topology construction so that the topology (torus,grid,mesh) specified in the config file is also applied to each deme.

- Added a 'MESH' topology, where the population is completely connected.

- Added "lazy" message logging to cStats, where all messages sent during the previous logging period are logged to a file iff cStats::SetLazyLog has been called during that logging period.  This is designed to reduce the "noise" of a messaging log file.  For use with the PrintLazyMessageLog event.

- Added an accessor to cWorld to get at the event list, so that we can do things like dynamically capture a population detail based on a condition (eg, a high deme fitness).

- Added STL-style iterator typedefs to tArray (convenience only; removed unchecked accessor).



Modified: branches/coopcomm/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/coopcomm/Avida.xcodeproj/project.pbxproj	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/Avida.xcodeproj/project.pbxproj	2006-12-27 18:26:59 UTC (rev 1155)
@@ -357,6 +357,7 @@
 		70F7DE6D09296616009E311D /* cSpeciesControl.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70F7DE6A09296613009E311D /* cSpeciesControl.cc */; };
 		70F7DE7409296794009E311D /* cGenotype_BirthData.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70F7DE700929678E009E311D /* cGenotype_BirthData.cc */; };
 		DCC3166107628531008F7A48 /* avida.cc in Sources */ = {isa = PBXBuildFile; fileRef = DCC3109C0762539E008F7A48 /* avida.cc */; };
+		E08178BA0B3DCB9600B474B6 /* cTopology.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = E08178B90B3DCB9600B474B6 /* cTopology.h */; };
 		E626209E0A372C2A00C07685 /* SaveLoadActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708051A80A1F65FE00CBB8B6 /* SaveLoadActions.cc */; };
 /* End PBXBuildFile section */
 
@@ -390,6 +391,7 @@
 				7049F3710A66AD7E00640512 /* default-sex-classic.org in CopyFiles */,
 				7049F3720A66AD7E00640512 /* default-smt.org in CopyFiles */,
 				7049F3730A66AD7E00640512 /* default-transsmt.org in CopyFiles */,
+				E08178BA0B3DCB9600B474B6 /* cTopology.h in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -909,6 +911,7 @@
 		DCC315D0076253A5008F7A48 /* task_event_gen.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.cc; sourceTree = "<group>"; };
 		DCC315D1076253A5008F7A48 /* task_event_gen.old.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.old.cc; sourceTree = "<group>"; };
 		DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
+		E08178B90B3DCB9600B474B6 /* cTopology.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cTopology.h; path = source/tools/cTopology.h; sourceTree = SOURCE_ROOT; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -1354,6 +1357,7 @@
 		DCC310040762539D008F7A48 /* main */ = {
 			isa = PBXGroup;
 			children = (
+				E08178B90B3DCB9600B474B6 /* cTopology.h */,
 				708BF3010AB65DD300A923BF /* cEventList.h */,
 				708BF2FD0AB65DC700A923BF /* cEventList.cc */,
 				703CA36F0A5072B700AB4DB4 /* SConscript */,

Modified: branches/coopcomm/source/actions/PopulationActions.cc
===================================================================
--- branches/coopcomm/source/actions/PopulationActions.cc	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/actions/PopulationActions.cc	2006-12-27 18:26:59 UTC (rev 1155)
@@ -24,6 +24,7 @@
 #include "cOrgMessage.h"
 #include "cStats.h"
 #include "cWorld.h"
+#include "cEventList.h"
 
 
 /*
@@ -1011,17 +1012,30 @@
   tally up the votes, and remove the votes for a given set of IDs.
   
   The resulting fitness is (current_max_votes + num_previous_leaders*100)^2.
+  
+  \todo Change the hardcoded 0.95 parameter to a configurable value.
   */
   double operator()(cPopulation::t_CellIterator begin, cPopulation::t_CellIterator end) {
     vote_calculator vc = std::for_each(begin, end, vote_calculator());
     vc.remove_votes(m_previousLeaders.begin(), m_previousLeaders.end());
     std::pair<vote_calculator::vote_tally, max_vote> vt = vc.tally(max_vote());
-    if(vt.second.m_maxVote == 100) {
-      m_previousLeaders.push_back(vt.second.m_maxID);
+
+    //if(vt.second.m_maxVote == 100) {
+    if(vt.second.m_maxVote >= 0.95*m_world->GetPopulation().GetDemeSize()) {
+      // Ok, if we get here then we have elected a leader.  We need to know a few more details
+      // about what has actually happened, then.
       cPopulationCell* cell = cPopulationCell::GetRandomCellIDMap()[vt.second.m_maxID];
+      // Store the deme id, cell-random ID, and cell-sequential ID.
       m_world->GetStats().DemeElected(m_demeId, vt.second.m_maxID, cell->GetID());
+      // Dump the whole population.
+      m_world->GetEventList().AddEvent("SavePopulation","");
+      // And dump the genomes for this deme.
+      m_world->GetEventList().AddEvent("PrintDemeGenomes","");
+      // And log the responsible messages.
+      m_world->GetStats().SetLazyLog();
+      // Update the fitness function.
+      m_previousLeaders.push_back(vt.second.m_maxID);
       vt.second.m_maxVote = 0;
-      // and reset the leader ID
       cell->ResetRandomCellID();
     }
         

Modified: branches/coopcomm/source/actions/PrintActions.cc
===================================================================
--- branches/coopcomm/source/actions/PrintActions.cc	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/actions/PrintActions.cc	2006-12-27 18:26:59 UTC (rev 1155)
@@ -75,6 +75,7 @@
 STATS_OUT_FILE(PrintElectionRecord, election.dat);
 STATS_OUT_FILE(PrintIDChanges, id_changes.dat);
 STATS_OUT_FILE(PrintMessageLog, message_log.dat);
+STATS_OUT_FILE(PrintLazyMessageLog, message_log.dat);
 
 #define POP_OUT_FILE(METHOD, DEFAULT)                                                     /*  1 */ \
 class cAction ## METHOD : public cAction {                                                /*  2 */ \
@@ -1537,6 +1538,7 @@
   action_lib->Register<cActionPrintElectionRecord>("PrintElectionRecord");
   action_lib->Register<cActionPrintIDChanges>("PrintIDChanges");
   action_lib->Register<cActionPrintMessageLog>("PrintMessageLog");
+  action_lib->Register<cActionPrintLazyMessageLog>("PrintLazyMessageLog");
   
   
   

Modified: branches/coopcomm/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/coopcomm/source/cpu/cHardwareCPU.cc	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/cpu/cHardwareCPU.cc	2006-12-27 18:26:59 UTC (rev 1155)
@@ -370,7 +370,8 @@
     cInstEntryCPU("get-pos", &cHardwareCPU::Inst_GetPosition),
     cInstEntryCPU("get-facing", &cHardwareCPU::Inst_GetFacing),
     cInstEntryCPU("set-leader", &cHardwareCPU::Inst_SetLeader),
-    cInstEntryCPU("get-leader", &cHardwareCPU::Inst_GetLeader)
+    cInstEntryCPU("get-leader", &cHardwareCPU::Inst_GetLeader),
+    cInstEntryCPU("get-neighbor-id", &cHardwareCPU::Inst_GetNeighborID)
   };
   
   const int n_size = sizeof(s_n_array)/sizeof(cNOPEntryCPU);
@@ -3668,3 +3669,14 @@
   GetRegister(FindModifiedRegister(REG_BX)) = organism->GetPhenotype().GetAge();
   return true;
 }
+
+
+/*! Returns the cell-random ID of the organism that is currently faced.  It directly loads
+register ?BX? with this value, without utilizing messages in any way.
+*/
+bool cHardwareCPU::Inst_GetNeighborID(cAvidaContext& ctx)
+{
+  cPopulationCell* cell = organism->GetCell()->ConnectionList().GetFirst();
+  GetRegister(FindModifiedRegister(REG_BX)) = cell->GetRandomCellID();
+  return true;  
+}

Modified: branches/coopcomm/source/cpu/cHardwareCPU.h
===================================================================
--- branches/coopcomm/source/cpu/cHardwareCPU.h	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/cpu/cHardwareCPU.h	2006-12-27 18:26:59 UTC (rev 1155)
@@ -490,8 +490,8 @@
   bool Inst_GetFacing(cAvidaContext& ctx); //!< Retrieve this organism's facing.
   bool Inst_SetLeader(cAvidaContext& ctx); //!< Set the leader of this organism.
   bool Inst_GetLeader(cAvidaContext& ctx); //!< Retrieve the leader of this organism.
+  bool Inst_GetNeighborID(cAvidaContext& ctx); //!< One-shot retrieve of the ID of the faced organism.
 
-
   bool Inst_GetTimeUsed(cAvidaContext& ctx); //!< Retrieve the number of cycles that this organism has used.
   bool Inst_GetAge(cAvidaContext& ctx); //!< Return the number of updates that this organism has survived.    
 };

Modified: branches/coopcomm/source/main/cPopulation.cc
===================================================================
--- branches/coopcomm/source/main/cPopulation.cc	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/main/cPopulation.cc	2006-12-27 18:26:59 UTC (rev 1155)
@@ -36,6 +36,7 @@
 #include "cStats.h"
 #include "cTaskEntry.h"
 #include "cWorld.h"
+#include "cTopology.h"
 
 #include <fstream>
 #include <vector>
@@ -43,6 +44,7 @@
 #include <numeric>
 #include <set>
 #include <map>
+#include <functional>
 
 #include <float.h>
 #include <math.h>
@@ -56,101 +58,82 @@
 , resource_count(world->GetEnvironment().GetResourceLib().GetSize())
 , birth_chamber(world)
 , environment(world->GetEnvironment())
+, world_x(world->GetConfig().WORLD_X.Get())
+, world_y(world->GetConfig().WORLD_Y.Get())
 , num_organisms(0)
+, num_demes(m_world->GetConfig().NUM_DEMES.Get())
 , sync_events(false)
 {
-  // Avida specific information.
-  world_x = world->GetConfig().WORLD_X.Get();
-  world_y = world->GetConfig().WORLD_Y.Get();
-  int geometry = world->GetConfig().WORLD_GEOMETRY.Get();
+  const int geometry = world->GetConfig().WORLD_GEOMETRY.Get();
   const int num_cells = world_x * world_y;
-
-  // Print out world details
-  if (world->GetVerbosity() > VERBOSE_NORMAL) {
-    cout << "Building world " << world_x << "x" << world_y << " = " << num_cells << " organisms." << endl;
-    if (geometry == nGeometry::GRID) {
-      cout << "Geometry: Bounded grid" << endl;
-    } else if (geometry == nGeometry::TORUS) {
-      cout << "Geometry: Torus" << endl;
-    } else {
-      cout << "Geometry: Unknown" << endl;
-    }
-    cout << endl;
+  const int birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
+  
+  // Error checking for demes vs. non-demes setup.
+  if(num_demes > 0) {
+    assert(world_y % num_demes == 0);
+    assert(birth_method != POSITION_CHILD_FULL_SOUP_ELDEST);
+    assert(birth_method != POSITION_CHILD_FULL_SOUP_ELDEST);
+  } else {
+    assert(birth_method != POSITION_CHILD_DEME_RANDOM);
+    num_demes = 1; // One population == one deme.
   }
+
+  // Track birth counts...
+  deme_birth_count.Resize(num_demes);
+  deme_birth_count.SetAll(0);
   
+  const int deme_size_x = world_x;
+  const int deme_size_y = world_y / num_demes;
+  deme_size = deme_size_x * deme_size_y;
+  
   cell_array.Resize(num_cells);
   resource_count.ResizeSpatialGrids(world_x, world_y);
   market.Resize(MARKET_SIZE);
   
-  bool bottom_flag, top_flag, right_flag, left_flag;
-  for (int cell_id = 0; cell_id < num_cells; cell_id++) {
-    int x = cell_id % world_x;
-    int y = cell_id / world_x;
-    cell_array[cell_id].Setup(world, cell_id, environment.GetMutRates(), x, y);
-    
-    
-    if ((y == 0) && (geometry == nGeometry::GRID)) {
-      bottom_flag = false;
-    } else {
-      bottom_flag = true;
-    }
-    if ((y == world_y-1) && (geometry == nGeometry::GRID)) {
-      top_flag = false;
-    } else {
-      top_flag = true;
-    }
-    if ((x == 0) && (geometry == nGeometry::GRID)) {
-      left_flag = false;
-    } else {
-      left_flag = true;
-    }
-    if ((x == world_x-1) && (geometry == nGeometry::GRID)) {
-      right_flag = false;
-    } else {
-      right_flag = true;
-    }
- 
-    // Setup the connection list for each cell. (Clockwise from -1 to 1)
-    
-    tList<cPopulationCell> & conn_list=cell_array[cell_id].ConnectionList();
-    if (bottom_flag && left_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, -1, -1)]));
-    }
-    if (bottom_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y,  0, -1)]));
-    }
-    if (bottom_flag && right_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, +1, -1)]));
-    }
-    if (right_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, +1,  0)]));
-    }
-    if (top_flag && right_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, +1, +1)]));
-    }
-    if (top_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y,  0, +1)]));
-    }
-    if (top_flag && left_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, -1, +1)]));
-    }
-    if (left_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, -1,  0)]));
-    }
-
-    // Setup the reaper queue...
+  // Setup the cells.  Do things that are not dependent upon topology here.
+  for(int i=0; i<num_cells; ++i) {
+    cell_array[i].Setup(world, i, environment.GetMutRates(), i%world_x, i/world_x);
+    // Setup the reaper queue.
     if (world->GetConfig().BIRTH_METHOD.Get() == POSITION_CHILD_FULL_SOUP_ELDEST) {
-      reaper_queue.Push(&(cell_array[cell_id]));
+      reaper_queue.Push(&(cell_array[i]));
     }
+    // Set the deme ID for each cell.
+    cell_array[i].SetDemeID(i/deme_size);
+  }                         
+  
+  // Setup the topology.
+  // What we're doing here is chopping the cell_array up into num_demes pieces.
+  // Note that having 0 demes (one population) is the same as having 1 deme.  Then
+  // we send the cells that comprise each deme into the topology builder.
+  for(int i=0; i<num_cells; i+=deme_size) {
+    switch(geometry) {
+      // We're cheating here; we're using the random access nature of an iterator
+      // to index beyond the end of the cell_array.
+      case nGeometry::GRID: {
+        build_grid(&cell_array.begin()[i], &cell_array.begin()[i+deme_size], 
+                   deme_size_x, deme_size_y);
+        break;
+      }
+      case nGeometry::TORUS: {
+        build_torus(&cell_array.begin()[i], &cell_array.begin()[i+deme_size], 
+                    deme_size_x, deme_size_y);
+        break;
+      }
+      case nGeometry::MESH: {
+        build_mesh(&cell_array.begin()[i], &cell_array.begin()[i+deme_size], 
+                   deme_size_x, deme_size_y);
+        break;
+      }
+      default: {
+        assert(false);
+      }
+    }
+    // And let's save these ranges for easier use later on.
+    m_demeCellRanges.push_back(t_CellRange(&cell_array.begin()[i], &cell_array.begin()[i+deme_size]));
   }
   
   BuildTimeSlicer(0);
   
-  if (SetupDemes() == false) {
-    cerr << "Error: Failed to setup demes.  Exiting..." << endl;
-    exit(1);
-  }
-  
   // Setup the resources...
   const cResourceLib & resource_lib = environment.GetResourceLib();
   for (int i = 0; i < resource_lib.GetSize(); i++) {
@@ -264,15 +247,15 @@
   
   // And just for fun, let's make it a little easier to actually GET AT the list
   // of demes and associated cells.
-  for(int i=0; i<num_demes; ++i) {
-    m_demeCellRanges.push_back(t_CellRange(cell_array.GetPtr()+i*deme_size,
-                                           cell_array.GetPtr()+(i+1)*deme_size));
-  }
-  // Cells need to know which deme they're part of (for cStats).
-  for(int i=0,j=0; i<cell_array.GetSize(); ++i) {
-    j = i / num_demes;
-    cell_array[i].SetDemeID(j);
-  }
+//  for(int i=0; i<num_demes; ++i) {
+//    m_demeCellRanges.push_back(t_CellRange(cell_array.GetPtr()+i*deme_size,
+//                                           cell_array.GetPtr()+(i+1)*deme_size));
+//  }
+//  // Cells need to know which deme they're part of (for cStats).
+//  for(int i=0,j=0; i<cell_array.GetSize(); ++i) {
+//    j = i / num_demes;
+//    cell_array[i].SetDemeID(j);
+//  }
   return true;
 }
 
@@ -756,50 +739,7 @@
         total_fitness += deme_fitness[cur_deme];
       }
     }
-      break;
-    
-//    case 7:
-//    {
-//      // Competing demes based on the number of organisms that have agreed on a leader.
-//      //
-//      // For each deme, build up the number of organisms that have "elected"
-//      // leaders.  Total fitness is the sum of the deme_fitness; deme_fitness is
-//      // the max number of organisms that have agreed on a single leader.
-//      //
-//      for(int cur_deme=0; cur_deme<num_demes; ++cur_deme) {
-//        // for each deme...
-//        std::map<int, std::set<int> > votes;
-//        unsigned int max=0;
-//        unsigned int org_count=0;
-//        
-//        for (int i=0; i<deme_size; ++i) {
-//          // for each cell in the deme
-//          int cur_cell = cur_deme * deme_size + i;
-//          // ... that has an organism
-//          if (cell_array[cur_cell].IsOccupied() == false) continue;
-//          // ... record the vote:
-//          ++org_count;
-//          cOrganism* org = GetCell(cur_cell).GetOrganism();
-//          // Skip orgs that haven't set a leader.
-//          if(org->GetLeaderID() == 0) continue;
-//          // And skip orgs that didn't set an organism ID
-//          if(!cPopulationCell::IsRandomCellID(org->GetLeaderID())) continue;
-//          if(votes.find(org->GetLeaderID()) == votes.end()) {
-//            votes.insert(std::make_pair(org->GetLeaderID(), std::set<int>()));
-//          }
-//          votes[org->GetLeaderID()].insert(org->GetRandomCellID());
-//          // ... and keep track of the winning organism.
-//          if(votes[org->GetLeaderID()].size() > max) {
-//            max = votes[org->GetLeaderID()].size();
-//          }
-//        }
-//
-//        m_world->GetStats().Demes_Leadership(max, org_count);//(double)max/org_count);
-//        deme_fitness[cur_deme] = (double)max;///org_count;
-//        total_fitness += deme_fitness[cur_deme];
-//      } // end deme-loop.
-//      break;      
-//    } // end case.
+    break;
   } 
   
   // Pick which demes should be in the next generation.
@@ -877,6 +817,8 @@
 
 /*! Designed to be used with the adaptable compete demes framework defined in 
 PopulationActions.cc.
+
+\todo Refactor this and the other CompeteDemes to take two iterators.
 */
 void cPopulation::CompeteDemes(const std::vector<double>& deme_fitness) {
   double total_fitness = std::accumulate(deme_fitness.begin(), 
@@ -1872,12 +1814,12 @@
 }
 
 
-cPopulation::t_CellIterator cPopulation::CellBegin() {
-  return cell_array.GetPtr();
+cPopulation::t_CellArray::iterator cPopulation::CellBegin() {
+  return cell_array.begin();
 }
 
-cPopulation::t_CellIterator cPopulation::CellEnd() {
-  return cell_array.GetPtr() + cell_array.GetSize();
+cPopulation::t_CellArray::iterator cPopulation::CellEnd() {
+  return cell_array.end();
 }
 
 cPopulationCell& cPopulation::GetCell(int in_num)

Modified: branches/coopcomm/source/main/cPopulation.h
===================================================================
--- branches/coopcomm/source/main/cPopulation.h	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/main/cPopulation.h	2006-12-27 18:26:59 UTC (rev 1155)
@@ -60,6 +60,7 @@
 class cPopulation
 {
 public:
+  //! Typedef for the list of cells comprising this population.
   typedef tArray<cPopulationCell> t_CellArray;
   //! So we can iterate over ranges of cells.
   typedef cPopulationCell* t_CellIterator;
@@ -183,6 +184,7 @@
   int GetSize() { return cell_array.GetSize(); }
   int GetWorldX() { return world_x; }
   int GetWorldY() { return world_y; }
+  int GetDemeSize() { return deme_size; }
 
   t_CellArray& GetCellArray() { return cell_array; }
   t_CellIterator CellBegin();

Modified: branches/coopcomm/source/main/cPopulationCell.cc
===================================================================
--- branches/coopcomm/source/main/cPopulationCell.cc	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/main/cPopulationCell.cc	2006-12-27 18:26:59 UTC (rev 1155)
@@ -99,6 +99,9 @@
 #endif
   while (connection_list.GetFirst() != &new_facing) {
     connection_list.CircNext();
+    if(scan_count + 1 >= connection_list.GetSize()) {
+      connection_list.CircNext();
+    }
 #ifdef DEBUG
     assert(++scan_count < connection_list.GetSize());
 #endif

Modified: branches/coopcomm/source/main/cStats.cc
===================================================================
--- branches/coopcomm/source/main/cStats.cc	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/main/cStats.cc	2006-12-27 18:26:59 UTC (rev 1155)
@@ -99,6 +99,8 @@
   , m_data_is_id_and_grt_sender(0)
   , m_data_is_leader(0)
   , m_detailedMessageLog(false)
+  , m_lazyMessageLog(false)
+  , m_lazyLogging(false)
 {
   task_cur_count.Resize( m_world->GetNumTasks() );
   task_last_count.Resize( m_world->GetNumTasks() );
@@ -893,7 +895,7 @@
 */
 void cStats::SentMessage(cOrgMessage& msg)
 {
-  if(m_detailedMessageLog) {
+  if(m_detailedMessageLog || m_lazyMessageLog) {
     // Create a message record.
     m_messagesByDeme[msg.GetSender()->GetCell()->GetDemeID()].push_back(
       MessageRecord(m_update, msg.GetSender()->GetCellID(),
@@ -1004,6 +1006,16 @@
 }
 
 
+void cStats::PrintLazyMessageLog(const cString& filename)
+{
+  m_lazyMessageLog = true;
+  if(m_lazyLogging) {
+    PrintMessageLog(filename);
+    m_lazyLogging = false;
+  }
+}
+
+
 void cStats::PrintMessageLog(const cString& filename)
 {
   cDataFile& df = m_world->GetDataFile(filename);

Modified: branches/coopcomm/source/main/cStats.h
===================================================================
--- branches/coopcomm/source/main/cStats.h	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/main/cStats.h	2006-12-27 18:26:59 UTC (rev 1155)
@@ -318,6 +318,10 @@
     
   //! A flag to indicate if we should be recording all messages.
   bool m_detailedMessageLog;
+  //! Flag to indicate if lazy logging is active.
+  bool m_lazyMessageLog;
+  //! Flag to indicate if messages from the previous log period should be logged.
+  bool m_lazyLogging;
   
   cStats(); // @not_implemented
   cStats(const cStats&); // @not_implemented
@@ -677,6 +681,10 @@
   void CellIDChange(const cPopulationCell& cell, int old_id, int new_id);
   //! Print the change id records.
   void PrintIDChanges(const cString& filename);
+  //! Lazily prints the messages from the past logging period.
+  void PrintLazyMessageLog(const cString& filename);
+  //! Turns on lazy logging for the previous log period.
+  inline void SetLazyLog() { m_lazyLogging=true; }
   //! Prints a log of all messages sent.
   void PrintMessageLog(const cString& filename);
   //! Log cell-specific data.

Modified: branches/coopcomm/source/main/cWorld.h
===================================================================
--- branches/coopcomm/source/main/cWorld.h	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/main/cWorld.h	2006-12-27 18:26:59 UTC (rev 1155)
@@ -84,6 +84,7 @@
   cPopulation& GetPopulation() { return *m_pop; }
   cRandom& GetRandom() { return m_rng; }
   cStats& GetStats() { return *m_stats; }
+  cEventList& GetEventList() { return *m_event_list; }
   cWorldDriver& GetDriver() { return *m_driver; }
   
   // Access to Data File Manager

Modified: branches/coopcomm/source/main/nGeometry.h
===================================================================
--- branches/coopcomm/source/main/nGeometry.h	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/main/nGeometry.h	2006-12-27 18:26:59 UTC (rev 1155)
@@ -14,7 +14,8 @@
   enum {
     GLOBAL = 0,
     GRID,
-    TORUS
+    TORUS,
+    MESH
   };
 }
 

Added: branches/coopcomm/source/tools/cTopology.h
===================================================================
--- branches/coopcomm/source/tools/cTopology.h	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/tools/cTopology.h	2006-12-27 18:26:59 UTC (rev 1155)
@@ -0,0 +1,88 @@
+/*! Builds different topologies out of ranges of cells.
+
+Avida; cTopology.h
+Copyright 2005-2006 Michigan State University. All rights reserved.
+
+This file contains templated algorithms that create a particular cell
+topology out of a given range of cells.  In every case, the range of cells is 
+specified by a begin/end iterator pair.
+*/
+
+
+/*! Builds a torus topology out of the cells betwen the iterators.
+In a torus, each cell is connected to up to 8 neighbors (including diagonals), 
+and connections DO wrap around the logical edges of the torus.
+*/
+template< typename InputIterator >
+void build_torus(InputIterator begin, InputIterator end, unsigned int rowSize, unsigned int colSize) {
+  // Get the offset from the start of this range.  This is used to modify the 
+  // parameters and return for GridNeighbor.
+  int offset = begin->GetID();
+  
+  for(InputIterator i=begin; i!=end; ++i) {
+    // The majority of all connections.
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 0)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 0, 1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 0)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, -1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 0, -1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, -1)]);
+  }
+}
+
+
+/*! Builds a grid topology out of the cells betwen the iterators.
+In a grid, each cell is connected to up to 8 neighbors (including diagonals), 
+and connections do NOT wrap around the logical edges of the grid.
+*/
+template< typename InputIterator >
+void build_grid(InputIterator begin, InputIterator end, unsigned int rowSize, unsigned int colSize) {
+  // Start with a torus.
+  build_torus(begin, end, rowSize, colSize);
+  int offset = begin->GetID();
+
+  // And now remove the connections that wrap around.
+  for(InputIterator i=begin; i!=end; ++i) {
+    int id = i->GetID();
+    unsigned int x = (id-offset) % colSize;
+    unsigned int y = (id-offset) / colSize;
+    
+    if(x==0) {
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, -1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 0)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 1)]);
+    }
+    if(x==(colSize-1)) {
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, -1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 0)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 1)]);      
+    }
+    if(y==0) {
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, -1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 0, -1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, -1)]);      
+    }
+    if(y==(rowSize-1)) {
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 0, 1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 1)]);      
+    }
+  }
+}
+
+
+/*! Builds a mesh topology out of the cells betwen the iterators.
+In a mesh, each cell is connected to all other cells in the given range.
+*/
+template< typename InputIterator >
+void build_mesh(InputIterator begin, InputIterator end, unsigned int rowSize, unsigned int colSize) {
+  for(InputIterator i=begin; i!=end; ++i) {
+    for(InputIterator j=begin; j!=end; ++j) {
+      if(j!=i) {
+        i->ConnectionList().Push(j);
+      }
+    }
+  }
+}

Modified: branches/coopcomm/source/tools/tArray.h
===================================================================
--- branches/coopcomm/source/tools/tArray.h	2006-12-27 18:06:39 UTC (rev 1154)
+++ branches/coopcomm/source/tools/tArray.h	2006-12-27 18:26:59 UTC (rev 1155)
@@ -33,13 +33,20 @@
   int m_size; // Number of Elements
 
 public:
+  // STL-style iterators and accessor methods, based on std::vector.
+  // Iterators==pointers, so this is pretty easy.
+  typedef T* iterator;
+  typedef const T* const_iterator;
+  inline iterator begin() { return m_data; }
+  inline iterator end() { return m_data + m_size; }
+  inline const_iterator begin() const { return m_data; }
+  inline const_iterator end() const { return m_data + m_size; }  
+  
+    
   explicit tArray(const int size = 0) : m_data(NULL), m_size(0) { ResizeClear(size); }
   tArray(const tArray& rhs) : m_data(NULL), m_size(0) { this->operator=(rhs); }
 
   ~tArray() { delete [] m_data; }
-
-  //! For those cases where an unchecked pointer to the data is needed...
-  inline T* GetPtr() { return m_data; }
   
   tArray& operator=(const tArray& rhs) {
     if (m_size != rhs.GetSize())  ResizeClear(rhs.GetSize());




More information about the Avida-cvs mailing list