[Avida-SVN] r1777 - in development: source/cpu source/main tests/_testrunner
welsberr at myxo.css.msu.edu
welsberr at myxo.css.msu.edu
Tue Jul 10 10:55:04 PDT 2007
Author: welsberr
Date: 2007-07-10 13:55:03 -0400 (Tue, 10 Jul 2007)
New Revision: 1777
Modified:
development/source/cpu/cHardwareCPU.cc
development/source/cpu/cHardwareCPU.h
development/source/main/cAvidaConfig.h
development/source/main/cBirthChamber.cc
development/source/main/cEnvironment.cc
development/source/main/cEnvironment.h
development/source/main/cPhenotype.cc
development/source/main/cPhenotype.h
development/source/main/cPopulation.cc
development/source/main/cPopulation.h
development/tests/_testrunner/testrunner.cfg
Log:
Changes to implement "tumble" and "move" instructions for Avidians, and add a
refractory period on completion of tasks that reduces the merit acquired on
completion of a task if it was already done recently.
Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/cpu/cHardwareCPU.cc 2007-07-10 17:55:03 UTC (rev 1777)
@@ -221,6 +221,9 @@
tInstLibEntry<tMethod>("set-cmut", &cHardwareCPU::Inst_SetCopyMut),
tInstLibEntry<tMethod>("mod-cmut", &cHardwareCPU::Inst_ModCopyMut),
+ // @WRE additions for movement
+ tInstLibEntry<tMethod>("tumble", &cHardwareCPU::Inst_Tumble),
+ tInstLibEntry<tMethod>("move", &cHardwareCPU::Inst_Move),
// Energy instruction
tInstLibEntry<tMethod>("recover", &cHardwareCPU::Inst_ZeroEnergyUsed),
@@ -3699,6 +3702,55 @@
return true;
}
+// @WRE addition for movement
+// Tumble sets the organism and cell to a new random facing
+//
+bool cHardwareCPU::Inst_Tumble(cAvidaContext& ctx)
+{
+ // Code taken from Inst_Inject
+ //cout << "Tumble: start" << endl;
+ const int num_neighbors = organism->GetNeighborhoodSize();
+ //cout << "Tumble: size = " << num_neighbors << endl;
+ organism->Rotate(ctx.GetRandom().GetUInt(num_neighbors));
+ return true;
+}
+
+// @WRE addition for movement
+// Move uses the cPopulation::SwapCells method to move an organism to a different cell
+// and the cPopulation::MoveOrganisms helper function to clean up after a move
+// The cell selected as a destination is the one faced
+bool cHardwareCPU::Inst_Move(cAvidaContext& ctx)
+{
+ // Declarations
+ int fromcellID, destcellID; //, actualNeighborhoodSize, fromFacing, destFacing, currentFacing;
+
+ // Get population
+ cPopulation& pop = m_world->GetPopulation();
+
+ // Get stepsize. Currently, all moves are one cell regardless of stepsize.
+ // This could be changed in the future.
+ const int stepsize = m_world->GetConfig().BIOMIMETIC_MOVEMENT_STEP.Get();
+
+ // Code
+ if (0 < stepsize) {
+ // Current cell
+ fromcellID = organism->GetCellID();
+ // With sanity check
+ if (-1 == fromcellID) return false;
+ // Destination cell
+ destcellID = pop.GetCell(fromcellID).GetCellFaced().GetID();
+ // Actually perform the move using SwapCells
+ //cout << "SwapCells: " << fromcellID << " to " << destcellID << endl;
+ pop.SwapCells(pop.GetCell(fromcellID),pop.GetCell(destcellID));
+ // Swap inputs and facings between cells using helper function
+ pop.MoveOrganisms(ctx, pop.GetCell(fromcellID), pop.GetCell(destcellID));
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
// Energy use
bool cHardwareCPU::Inst_ZeroEnergyUsed(cAvidaContext& ctx)
Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/cpu/cHardwareCPU.h 2007-07-10 17:55:03 UTC (rev 1777)
@@ -453,6 +453,9 @@
bool Inst_RotateLabel(cAvidaContext& ctx);
bool Inst_SetCopyMut(cAvidaContext& ctx);
bool Inst_ModCopyMut(cAvidaContext& ctx);
+ // @WRE additions for movement
+ bool Inst_Tumble(cAvidaContext& ctx);
+ bool Inst_Move(cAvidaContext& ctx);
// Energy use
Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cAvidaConfig.h 2007-07-10 17:55:03 UTC (rev 1777)
@@ -352,12 +352,12 @@
CONFIG_ADD_VAR(APPLY_ENERGY_METHOD, int, 0, "When should rewarded energy be applied to current energy?\n0 = on divide\n1 = on completion of task\n2 = on sleep");
CONFIG_ADD_VAR(ENERGY_VERBOSE, bool, 0, "Print energy and merit values. 0/1 (off/on)");
CONFIG_ADD_VAR(LOG_SLEEP_TIMES, bool, 0, "Log sleep start and end times. 0/1 (off/on)\nWARNING: may use lots of memory.");
-// CONFIG_ADD_VAR(FIX_METABOLIC_RATE, bool, 0, "When activated the metabolic rate of all orgiansims are equal. 0/1 (off/on)"); // TODO - check for correctness
+ // CONFIG_ADD_VAR(FIX_METABOLIC_RATE, bool, 0, "When activated the metabolic rate of all orgiansims are equal. 0/1 (off/on)"); // TODO - check for correctness
CONFIG_ADD_GROUP(SECOND_PASS_GROUP, "Tracking metrics known after the running experiment previously");
CONFIG_ADD_VAR(TRACK_CCLADES, int, 0, "Enable tracking of coalescence clades");
CONFIG_ADD_VAR(TRACK_CCLADES_IDS, cString, "coalescence.ids", "File storing coalescence IDs");
-
+
CONFIG_ADD_GROUP(GX_GROUP, "Gene Expression CPU Settings");
CONFIG_ADD_VAR(MAX_PROGRAMIDS, int, 16, "Maximum number of programids an organism can create.");
CONFIG_ADD_VAR(MAX_PROGRAMID_AGE, int, 2000, "Max number of CPU cycles a programid executes before it is removed.");
@@ -365,7 +365,7 @@
CONFIG_ADD_VAR(IMPLICIT_BG_PROMOTER_RATE, double, 0.0, "Relative rate of non-promoter sites creating programids.");
CONFIG_ADD_VAR(IMPLICIT_TURNOVER_RATE, double, 0.0, "Number of programids recycled per CPU cycle. 0 = OFF");
CONFIG_ADD_VAR(IMPLICIT_MAX_PROGRAMID_LENGTH, int, 0, "Creation of an executable programid terminates after this many instructions. 0 = disabled");
-// CONFIG_ADD_VAR(CLEAR_ON_OUTPUT, int, 0, "Reset input buffer every time output called?"); @JEB Not fully implemented
+ // CONFIG_ADD_VAR(CLEAR_ON_OUTPUT, int, 0, "Reset input buffer every time output called?"); @JEB Not fully implemented
CONFIG_ADD_GROUP(PROMOTER_GROUP, "Promoters");
CONFIG_ADD_VAR(PROMOTERS_ENABLED, int, 0, "Use the promoter/terminator execution scheme.\nCertain instructions must also be included.");
@@ -388,6 +388,12 @@
CONFIG_ADD_VAR(COLOR_MUT_NEG, cString, "FFFF00", "Color to flag stat that has changed since parent.");
CONFIG_ADD_VAR(COLOR_MUT_LETHAL, cString, "FF0000", "Color to flag stat that has changed since parent.");
+ // @WRE: Additions for approaching various features of biological organisms
+ CONFIG_ADD_GROUP(BIOMIMETIC_GROUP, "Biomimetic Features Settings");
+ CONFIG_ADD_VAR(BIOMIMETIC_REFRACTORY_PERIOD, double, 0.0, "Number of updates affected by refractory period");
+ CONFIG_ADD_VAR(BIOMIMETIC_MOVEMENT_STEP, int, 0, "Number of cells to move Avidian on move instruction");
+ CONFIG_ADD_VAR(BIOMIMETIC_K, int, 0, "Carrying capacity in number of organisms");
+
#endif
void Load(const cString& filename, const bool& crash_if_not_found);
Modified: development/source/main/cBirthChamber.cc
===================================================================
--- development/source/main/cBirthChamber.cc 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cBirthChamber.cc 2007-07-10 17:55:03 UTC (rev 1777)
@@ -39,8 +39,14 @@
cBirthChamber::cBirthChamber(cWorld* world) : m_world(world)
{
- const int num_orgs = m_world->GetConfig().WORLD_X.Get() * m_world->GetConfig().WORLD_Y.Get();
const int num_demes = m_world->GetConfig().NUM_DEMES.Get();
+ int num_orgs;
+
+ num_orgs = m_world->GetConfig().BIOMIMETIC_K.Get();
+ if (0 >= num_orgs) {
+ num_orgs = m_world->GetConfig().WORLD_X.Get() * m_world->GetConfig().WORLD_Y.Get();
+ }
+
local_wait_entry.Resize(num_orgs);
deme_wait_entry.Resize(num_demes);
}
Modified: development/source/main/cEnvironment.cc
===================================================================
--- development/source/main/cEnvironment.cc 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cEnvironment.cc 2007-07-10 17:55:03 UTC (rev 1777)
@@ -787,6 +787,17 @@
}
+void cEnvironment::SwapInputs(cAvidaContext& ctx, tArray<int>& src_input_array, tArray<int>& dest_input_array) const
+{
+ tArray<int>& tmp_input_array = dest_input_array;
+
+ // Just swap the pointers around.
+ dest_input_array = src_input_array;
+ src_input_array = tmp_input_array;
+
+}
+
+
bool cEnvironment::TestInput(cReactionResult& result, const tBuffer<int>& inputs,
const tBuffer<int>& outputs, const tArray<double>& resource_count) const
{
Modified: development/source/main/cEnvironment.h
===================================================================
--- development/source/main/cEnvironment.h 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cEnvironment.h 2007-07-10 17:55:03 UTC (rev 1777)
@@ -119,7 +119,9 @@
// Interaction with the organisms
void SetupInputs(cAvidaContext& ctx, tArray<int>& input_array, bool random = true) const;
+ void SwapInputs(cAvidaContext& ctx, tArray<int>& src_input_array, tArray<int>& dest_input_array) const;
+
bool TestInput(cReactionResult& result, const tBuffer<int>& inputs,
const tBuffer<int>& outputs, const tArray<double>& resource_count) const;
Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cPhenotype.cc 2007-07-10 17:55:03 UTC (rev 1777)
@@ -49,6 +49,7 @@
, cur_reaction_add_reward(m_world->GetEnvironment().GetReactionLib().GetSize())
, cur_inst_count(world->GetHardwareManager().GetInstSet().GetSize())
, cur_sense_count(m_world->GetStats().GetSenseSize())
+ , cur_task_time(m_world->GetEnvironment().GetNumTasks()) // Added for tracking time; WRE 03-18-07
, sensed_resources(m_world->GetEnvironment().GetResourceLib().GetSize())
, promoter_last_inst_terminated(false)
, last_task_count(m_world->GetEnvironment().GetNumTasks())
@@ -142,6 +143,7 @@
cur_reaction_add_reward.SetAll(0);
cur_inst_count.SetAll(0);
cur_sense_count.SetAll(0);
+ cur_task_time.SetAll(0.0); // Added for time tracking; WRE 03-18-07
for (int j = 0; j < sensed_resources.GetSize(); j++)
sensed_resources[j] = parent_phenotype.sensed_resources[j];
SetupPromoterWeights(_genome, true);
@@ -271,6 +273,7 @@
cur_inst_count.SetAll(0);
sensed_resources.SetAll(0);
cur_sense_count.SetAll(0);
+ cur_task_time.SetAll(0.0);
SetupPromoterWeights(_genome, true);
// Copy last values from parent
@@ -418,6 +421,7 @@
cur_reaction_add_reward.SetAll(0);
cur_inst_count.SetAll(0);
cur_sense_count.SetAll(0);
+ cur_task_time.SetAll(0.0);
// Setup other miscellaneous values...
num_divides++;
@@ -553,6 +557,7 @@
cur_reaction_add_reward.SetAll(0);
cur_inst_count.SetAll(0);
cur_sense_count.SetAll(0);
+ cur_task_time.SetAll(0.0);
sensed_resources.SetAll(-1.0);
SetupPromoterWeights(_genome, true);
@@ -666,6 +671,7 @@
cur_reaction_add_reward.SetAll(0);
cur_inst_count.SetAll(0);
cur_sense_count.SetAll(0);
+ cur_task_time.SetAll(0.0);
for (int j = 0; j < sensed_resources.GetSize(); j++)
sensed_resources[j] = clone_phenotype.sensed_resources[j];
//SetupPromoterWeights(_genome); Do we reset here?
@@ -778,6 +784,11 @@
const int num_tasks = env.GetNumTasks();
const int num_reactions = env.GetReactionLib().GetSize();
+ // For refractory period @WRE 03-20-07
+ const int cur_update_time = m_world->GetStats().GetUpdate();
+ const double biomimetic_refractory_period = m_world->GetConfig().BIOMIMETIC_REFRACTORY_PERIOD.Get();
+ double refract_factor;
+
cReactionResult result(num_resources, num_tasks, num_reactions);
// Run everything through the environment.
@@ -792,14 +803,25 @@
// Update the phenotype with the results...
// Start with updating task and reaction counters
for (int i = 0; i < num_tasks; i++) {
+ // Calculate refractory period factor @WRE
+ // Modify TaskQuality amount based on refractory period
+ // Logistic equation using refractory period
+ // in update units from configuration file. @WRE 03-20-07, 04-17-07
+ if (0.0 == biomimetic_refractory_period) {
+ refract_factor = 1.0;
+ } else {
+ refract_factor = 1.0 - (1.0 / (1.0 + exp((cur_update_time - cur_task_time[i])-biomimetic_refractory_period*0.5)));
+ }
if (result.TaskDone(i) == true)
{
cur_task_count[i]++;
eff_task_count[i]++;
}
- if (result.TaskQuality(i) > 0) cur_task_quality[i]+= result.TaskQuality(i);
- cur_task_value[i] = result.TaskValue(i);
+ if (result.TaskQuality(i) > 0) cur_task_quality[i]+= result.TaskQuality(i) * refract_factor;
+ cur_task_value[i] = result.TaskValue(i);
+ cur_task_time[i] = cur_update_time; // Find out time from context
}
+
for (int i = 0; i < num_reactions; i++) {
if (result.ReactionTriggered(i) == true) cur_reaction_count[i]++;
cur_reaction_add_reward[i] += result.GetReactionAddBonus(i);
Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cPhenotype.h 2007-07-10 17:55:03 UTC (rev 1777)
@@ -119,6 +119,7 @@
tArray<int> cur_inst_count; // Instruction exection counter
tArray<int> cur_sense_count; // Total times resource combinations have been sensed; @JEB
tArray<double> sensed_resources; // Resources which the organism has sensed; @JEB
+ tArray<double> cur_task_time; // Time at which each task was last performed; WRE 03-18-07
tArray<cCodeLabel> active_transposons; // Transposons that are active; @JEB
tArray<double> base_promoter_weights; // Baseline chance of starting execution from each position; @JEB
tArray<double> cur_promoter_weights; // Current of starting execution from each position, adjusted for regulation; @JEB
Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cPopulation.cc 2007-07-10 17:55:03 UTC (rev 1777)
@@ -473,6 +473,95 @@
}
+// @WRE 2007/07/05 Helper function to take care of side effects of Avidian
+// movement that cannot be directly handled in cHardwareCPU.cc
+void cPopulation::MoveOrganisms(cAvidaContext& ctx, cPopulationCell& src_cell, cPopulationCell& dest_cell)
+{
+ // Declarations
+ int actualNeighborhoodSize, fromFacing, destFacing, newFacing, success;
+#ifdef DEBBUG
+ int sID, dID, xx1, yy1, xx2, yy2;
+#endif
+
+ // Swap inputs between cells to fix bus error when Avidian moves into an unoccupied cell
+ environment.SwapInputs(ctx, src_cell.input_array, dest_cell.input_array);
+
+ // Find neighborhood size for facing
+ if (NULL != dest_cell.GetOrganism()) {
+ actualNeighborhoodSize = dest_cell.GetOrganism()->GetNeighborhoodSize();
+ } else {
+ if (NULL != src_cell.GetOrganism()) {
+ actualNeighborhoodSize = src_cell.GetOrganism()->GetNeighborhoodSize();
+ } else {
+ // Punt
+ actualNeighborhoodSize = 8;
+ }
+ }
+
+ // Swap cell facings between cells, so that if movement is directed, it continues to be associated with
+ // the same organism
+ // Determine absolute facing for each cell
+ fromFacing = src_cell.GetFacing();
+ destFacing = dest_cell.GetFacing();
+
+ // Set facing in source cell
+ success = 0;
+ newFacing = destFacing;
+ for(int i = 0; i < actualNeighborhoodSize; i++) {
+ if (src_cell.GetFacing() != newFacing) {
+ src_cell.ConnectionList().CircNext();
+ //cout << "MO: src_cell facing not yet at " << newFacing << endl;
+ } else {
+ //cout << "MO: src_cell facing successfully set to " << newFacing << endl;
+ success = 1;
+ break;
+ }
+ }
+#ifdef DEBUG
+ if (!success) {
+ sID = src_cell.GetID();
+ dID = dest_cell.GetID();
+ src_cell.GetPosition(xx1,yy1);
+ dest_cell.GetPosition(xx2,yy2);
+ //Conditional for examining only neighbor move without swap in facing
+ //if (1 == abs(xx2-xx1)+abs(yy2-yy1)) {
+ cout << "MO: src: " << sID << "@ (" << xx1 << "," << yy1 << ") dest: " << dID << "@ (" << xx2 << "," << yy2 << "), FAILED to set src_cell facing to " << newFacing << endl;
+ for (int j=0; j < actualNeighborhoodSize; j++) {
+ src_cell.ConnectionList().CircNext();
+ src_cell.GetCellFaced().GetPosition(xx2,yy2);
+ cout << "connlist for " << sID << ": facing " << src_cell.GetFacing() << " -> (" << xx2 << "," << yy2 << ")" << endl;
+ }
+ //}
+ }
+#endif
+
+ // Set facing in destinatiion cell
+ success = 0;
+ newFacing = fromFacing;
+ for(int i = 0; i < actualNeighborhoodSize; i++) {
+ if (dest_cell.GetFacing() != newFacing) {
+ dest_cell.ConnectionList().CircNext();
+ // cout << "MO: dest_cell facing not yet at " << newFacing << endl;
+ } else {
+ // cout << "MO: dest_cell facing successfully set to " << newFacing << endl;
+ success = 1;
+ break;
+ }
+ }
+#ifdef DEBUG
+ if (!success) {
+ sID = src_cell.GetID();
+ dID = dest_cell.GetID();
+ src_cell.GetPosition(xx1,yy1);
+ dest_cell.GetPosition(xx2,yy2);
+ if (1 == abs(xx2-xx1)+abs(yy2-yy1)) {
+ cout << "MO: src: " << sID << "@ (" << xx1 << "," << yy1 << ") dest: " << dID << "@ (" << xx2 << "," << yy2 << "), FAILED to set dest_cell facing to " << newFacing << endl;
+ }
+ }
+#endif
+
+}
+
void cPopulation::KillOrganism(cPopulationCell& in_cell)
{
// do we actually have something to kill?
@@ -659,24 +748,34 @@
void cPopulation::SwapCells(cPopulationCell & cell1, cPopulationCell & cell2)
{
+ // Sanity checks: Don't process if the cells are the same and
+ // don't bother trying to move when given a cell that isn't there
+ //cout << "SwapCells: testing if cell1 and cell2 are non-null" << endl;
+ //if (!(NULL != cell1) || !(NULL != cell2)) return;
+ if ((&cell1 == NULL) || (&cell2 == NULL)) return;
+ //cout << "SwapCells: testing if cell1 and cell2 are different" << endl;
+ if (cell1.GetID() == cell2.GetID()) return;
+ // Clear current contents of cells
+ //cout << "SwapCells: clearing cell contents" << endl;
cOrganism * org1 = cell1.RemoveOrganism();
cOrganism * org2 = cell2.RemoveOrganism();
+ //cout << "SwapCells: organism 2 is non-null, fix up source cell" << endl;
if (org2 != NULL) {
cell1.InsertOrganism(*org2);
schedule->Adjust(cell1.GetID(), org2->GetPhenotype().GetMerit());
} else {
schedule->Adjust(cell1.GetID(), cMerit(0));
}
-
+ //cout << "SwapCells: organism 1 is non-null, fix up dest cell" << endl;
if (org1 != NULL) {
cell2.InsertOrganism(*org1);
schedule->Adjust(cell2.GetID(), org1->GetPhenotype().GetMerit());
} else {
schedule->Adjust(cell2.GetID(), cMerit(0));
}
+ //cout << "SwapCells: Done." << endl;
}
-
// CompeteDemes probabilistically copies demes into the next generation
// based on their fitness. How deme fitness is estimated is specified by
// competition_type input argument as:
@@ -1638,6 +1737,12 @@
void cPopulation::UpdateOrganismStats()
{
+ // Carrying capacity @WRE 04-20-07
+ // Check for positive non-zero carrying capacity and apply it
+ if (0 < m_world->GetConfig().BIOMIMETIC_K.Get()) {
+ SerialTransfer(m_world->GetConfig().BIOMIMETIC_K.Get(),true);
+ }
+
// Loop through all the cells getting stats and doing calculations
// which must be done on a creature by creature basis.
Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/source/main/cPopulation.h 2007-07-10 17:55:03 UTC (rev 1777)
@@ -162,6 +162,10 @@
// Deactivate an organism in the population (required for deactivations)
void KillOrganism(cPopulationCell& in_cell);
+
+ // @WRE 2007/07/05 Helper function to take care of side effects of Avidian
+ // movement that cannot be directly handled in cHardwareCPU.cc
+ void MoveOrganisms(cAvidaContext& ctx, cPopulationCell& src_cell, cPopulationCell& dest_cell);
// Specialized functionality
void Kaboom(cPopulationCell& in_cell, int distance=0);
Modified: development/tests/_testrunner/testrunner.cfg
===================================================================
--- development/tests/_testrunner/testrunner.cfg 2007-07-10 17:27:15 UTC (rev 1776)
+++ development/tests/_testrunner/testrunner.cfg 2007-07-10 17:55:03 UTC (rev 1777)
@@ -1,5 +1,5 @@
[testrunner]
-builddir = cbuild
+builddir = .
mode = local
svn = svn
svnversion = svnversion
More information about the Avida-cvs
mailing list