[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