[Avida-SVN] r3364 - in development/source: actions cpu main
connel42 at myxo.css.msu.edu
connel42 at myxo.css.msu.edu
Wed Aug 12 07:09:27 PDT 2009
Author: connel42
Date: 2009-08-12 10:09:27 -0400 (Wed, 12 Aug 2009)
New Revision: 3364
Modified:
development/source/actions/EnvironmentActions.cc
development/source/actions/PopulationActions.cc
development/source/cpu/cHardwareCPU.cc
development/source/cpu/cHardwareCPU.h
development/source/main/cAvidaConfig.h
development/source/main/cDeme.h
Log:
Added new generic sense and donate resource instructions, actions to set per-deme resource inflow and outflow, action to migrate members of a deme to another if the level of some resource is above some threshold
Modified: development/source/actions/EnvironmentActions.cc
===================================================================
--- development/source/actions/EnvironmentActions.cc 2009-08-11 12:54:54 UTC (rev 3363)
+++ development/source/actions/EnvironmentActions.cc 2009-08-12 14:09:27 UTC (rev 3364)
@@ -438,6 +438,46 @@
}
};
+/* Set the inflow of a given deme. Currently only works for global (deme) resources.
+
+ Parameters:
+ deme id - the deme whose resource to set
+ name - the name of the resource
+ inflow - value to set as amount of resource added
+
+ */
+
+class cActionSetDemeResourceInflow : public cAction
+ {
+ private:
+ int m_demeid;
+ cString m_name;
+ double m_inflow;
+
+ public:
+ cActionSetDemeResourceInflow(cWorld* world, const cString& args) : cAction(world, args), m_demeid(-1), m_name(""), m_inflow(0.0)
+ {
+ cString largs(args);
+ if (largs.GetSize()) m_demeid = largs.PopWord().AsInt();
+ if (largs.GetSize()) m_name = largs.PopWord();
+ if (largs.GetSize()) m_inflow = largs.PopWord().AsDouble();
+
+ assert(m_inflow >= 0);
+ assert(m_demeid >= 0);
+
+ }
+
+ static const cString GetDescription() { return "Arguments: <int deme id> <string resource_name> <int inflow>"; }
+
+ void Process(cAvidaContext& ctx)
+ {
+ m_world->GetEnvironment().SetResourceInflow(m_name, m_inflow);
+ //This doesn't actually update the rate in the population, so...
+ m_world->GetPopulation().GetDeme(m_demeid).GetDemeResources().SetInflow(m_name, m_inflow);
+ }
+ };
+
+
class cActionSetResourceOutflow : public cAction
{
private:
@@ -464,6 +504,46 @@
}
};
+/* Set the outflow (decay) of a given deme. Currently only works for global (deme) resources.
+
+Parameters:
+ deme id - the deme whose resource to set
+ name - the name of the resource
+ outflow - value to set as percentage of the resource decayed continuously
+
+*/
+
+class cActionSetDemeResourceOutflow : public cAction
+ {
+ private:
+ int m_demeid;
+ cString m_name;
+ double m_outflow;
+
+ public:
+ cActionSetDemeResourceOutflow(cWorld* world, const cString& args) : cAction(world, args), m_demeid(-1), m_name(""), m_outflow(0.0)
+ {
+ cString largs(args);
+ if (largs.GetSize()) m_demeid = largs.PopWord().AsInt();
+ if (largs.GetSize()) m_name = largs.PopWord();
+ if (largs.GetSize()) m_outflow = largs.PopWord().AsDouble();
+ assert(m_demeid >= 0);
+ assert(m_outflow <= 1.0);
+ assert(m_outflow >= 0.0);
+ }
+
+ static const cString GetDescription() { return "Arguments: <int deme id> <string resource_name> <int outflow>"; }
+
+ void Process(cAvidaContext& ctx)
+ {
+ m_world->GetEnvironment().SetResourceOutflow(m_name, m_outflow);
+ //This doesn't actually update the rate in the population, so...
+ m_world->GetPopulation().GetDeme(m_demeid).GetDemeResources().SetDecay(m_name, 1-m_outflow);
+
+ }
+ };
+
+
class cActionSetEnvironmentInputs : public cAction
{
private:
@@ -1025,6 +1105,8 @@
action_lib->Register<cActionSetResourceInflow>("SetResourceInflow");
action_lib->Register<cActionSetResourceOutflow>("SetResourceOutflow");
+ action_lib->Register<cActionSetDemeResourceInflow>("SetDemeResourceInflow");
+ action_lib->Register<cActionSetDemeResourceOutflow>("SetDemeResourceOutflow");
action_lib->Register<cActionSetEnvironmentInputs>("SetEnvironmentInputs");
action_lib->Register<cActionSetEnvironmentRandomMask>("SetEnvironmentRandomMask");
Modified: development/source/actions/PopulationActions.cc
===================================================================
--- development/source/actions/PopulationActions.cc 2009-08-11 12:54:54 UTC (rev 3363)
+++ development/source/actions/PopulationActions.cc 2009-08-12 14:09:27 UTC (rev 3364)
@@ -3441,6 +3441,106 @@
};
+/* This action migrates a configurable number of organisms from one deme to another if
+ the level of some global (deme) resource is above the configured threshold.
+
+Parameters: 3
+ - name of the resource. This must be a deme-level global resource.
+ - threshold level for resource. above this, organisms are migrated.
+ - number of organisms to migrate to a randomly-chosen deme.
+
+*/
+
+class cActionMigrateDemes : public cAction
+{
+ private:
+ cString m_res;
+ double m_thresh;
+ int m_numorgs;
+ public:
+ static const cString GetDescription() { return "Arguments: <string resource name><double failure_percent>"; }
+
+ cActionMigrateDemes(cWorld* world, const cString& args) : cAction(world, args), m_thresh(0), m_numorgs(0)
+ {
+ cString largs(args);
+ if (largs.GetSize()) m_res = largs.PopWord();
+ if (largs.GetSize()) m_thresh = largs.PopWord().AsDouble();
+ if (largs.GetSize()) m_numorgs = largs.PopWord().AsInt();
+
+ assert(m_thresh >= 0);
+ assert(m_numorgs >= 0);
+
+ assert(m_world->GetConfig().NUM_DEMES.Get() > 1);
+
+ //Speculative execution will not work since we are moving organisms around.
+ assert(m_world->GetConfig().SPECULATIVE.Get() == 0);
+ }
+
+ void Process(cAvidaContext& ctx)
+ {
+ int src_cellid, dest_cellid;
+
+ for (int d = 0; d < m_world->GetPopulation().GetNumDemes(); d++) {
+ cDeme& deme = m_world->GetPopulation().GetDeme(d);
+ int deme_size = deme.GetWidth() * deme.GetHeight();
+
+ const cResourceCount &res = deme.GetDemeResourceCount();
+ const int resid = res.GetResourceByName(m_res);
+
+ if(resid == -1) {
+ //Resource doesn't exist for this deme. This is a bad situation, but just go to next deme.
+ cerr << "Error: Resource \"" << m_res << "\" not defined for this deme" << endl;
+ continue;
+ }
+
+ if(res.Get(resid) >= m_thresh) {
+ //Set the resource to zero
+ deme.AdjustResource(resid, (-1 * res.Get(resid)));
+
+ //Pick a deme to move to
+ int target_demeid = m_world->GetRandom().GetInt(0, m_world->GetConfig().NUM_DEMES.Get()-1);
+ cDeme& target_deme = m_world->GetPopulation().GetDeme(target_demeid);
+ int target_deme_size = target_deme.GetWidth() * target_deme.GetHeight();
+
+ //Migrate up to m_numorgs orgs
+ for(int i = 0; i < m_numorgs; i++) {
+ src_cellid = -1;
+ dest_cellid = -1;
+
+ int counter = 0;
+ do {
+ src_cellid = m_world->GetRandom().GetInt(0, (deme.GetWidth() * deme.GetHeight())-1);
+ cout << ".";
+ counter++;
+ } while((counter < deme_size) && (!deme.GetCell(src_cellid).IsOccupied()));
+
+ counter = 0;
+ do {
+ dest_cellid = m_world->GetRandom().GetInt(0, target_deme_size - 1);
+ counter++;
+ } while((counter < target_deme_size) && (target_deme.GetCell(dest_cellid).IsOccupied()));
+
+ if( (src_cellid != -1) && (dest_cellid != -1) ) {
+
+ m_world->GetPopulation().SwapCells(deme.GetCell(src_cellid), target_deme.GetCell(dest_cellid));
+ m_world->GetPopulation().MoveOrganisms(ctx, deme.GetCell(src_cellid), target_deme.GetCell(dest_cellid));
+
+ deme.DecOrgCount();
+ target_deme.IncOrgCount();
+ }
+
+ //migrate the organism from src_cell to dest cell
+ }
+
+
+ }
+
+ } //End iterating through demes
+
+ }
+};
+
+
void RegisterPopulationActions(cActionLibrary* action_lib)
{
action_lib->Register<cActionInject>("Inject");
@@ -3561,4 +3661,5 @@
action_lib->Register<cActionSwapCells>("swap_cells");
action_lib->Register<cActionKillDemePercent>("KillDemePercent");
action_lib->Register<cActionSetDemeTreatmentAges>("SetDemeTreatmentAges");
+ action_lib->Register<cActionMigrateDemes>("MigrateDemes");
}
Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc 2009-08-11 12:54:54 UTC (rev 3363)
+++ development/source/cpu/cHardwareCPU.cc 2009-08-12 14:09:27 UTC (rev 3364)
@@ -229,6 +229,13 @@
tInstLibEntry<tMethod>("sense", &cHardwareCPU::Inst_SenseLog2, nInstFlag::STALL), // If you add more sense instructions
tInstLibEntry<tMethod>("sense-unit", &cHardwareCPU::Inst_SenseUnit, nInstFlag::STALL), // and want to keep stats, also add
tInstLibEntry<tMethod>("sense-m100", &cHardwareCPU::Inst_SenseMult100, nInstFlag::STALL), // the names to cStats::cStats() @JEB
+
+ tInstLibEntry<tMethod>("sense-resource0", &cHardwareCPU::Inst_SenseResource0, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("sense-resource1", &cHardwareCPU::Inst_SenseResource1, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("sense-resource2", &cHardwareCPU::Inst_SenseResource2, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("sense-faced-resource0", &cHardwareCPU::Inst_SenseFacedResource0, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("sense-faced-resource1", &cHardwareCPU::Inst_SenseFacedResource1, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("sense-faced-resource2", &cHardwareCPU::Inst_SenseFacedResource2, nInstFlag::STALL),
tInstLibEntry<tMethod>("if-resources", &cHardwareCPU::Inst_IfResources, nInstFlag::STALL),
tInstLibEntry<tMethod>("collect", &cHardwareCPU::Inst_Collect, nInstFlag::STALL),
@@ -263,6 +270,9 @@
tInstLibEntry<tMethod>("request-energy-off", &cHardwareCPU::Inst_RequestEnergyFlagOff, nInstFlag::STALL),
tInstLibEntry<tMethod>("increase-energy-donation", &cHardwareCPU::Inst_IncreaseEnergyDonation, nInstFlag::STALL),
tInstLibEntry<tMethod>("decrease-energy-donation", &cHardwareCPU::Inst_DecreaseEnergyDonation, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("donate-resource0", &cHardwareCPU::Inst_DonateResource0, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("donate-resource1", &cHardwareCPU::Inst_DonateResource1, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("donate-resource2", &cHardwareCPU::Inst_DonateResource2, nInstFlag::STALL),
tInstLibEntry<tMethod>("IObuf-add1", &cHardwareCPU::Inst_IOBufAdd1, nInstFlag::STALL),
tInstLibEntry<tMethod>("IObuf-add0", &cHardwareCPU::Inst_IOBufAdd0, nInstFlag::STALL),
@@ -3510,6 +3520,57 @@
// Note that we are converting <double> resources to <int> register values
}
+
+bool cHardwareCPU::Inst_SenseResource0(cAvidaContext& ctx)
+{
+ return DoSenseResourceX(REG_BX, m_organism->GetCellID(), 0);
+}
+
+bool cHardwareCPU::Inst_SenseResource1(cAvidaContext& ctx)
+{
+ return DoSenseResourceX(REG_BX, m_organism->GetCellID(), 1);
+}
+
+bool cHardwareCPU::Inst_SenseResource2(cAvidaContext& ctx)
+{
+ return DoSenseResourceX(REG_BX, m_organism->GetCellID(), 2);
+}
+
+bool cHardwareCPU::Inst_SenseFacedResource0(cAvidaContext& ctx)
+{
+ return DoSenseResourceX(REG_BX, m_world->GetPopulation().GetCell(m_organism->GetCellID()).GetCellFaced().GetID(), 0);
+}
+
+bool cHardwareCPU::Inst_SenseFacedResource1(cAvidaContext& ctx)
+{
+ return DoSenseResourceX(REG_BX, m_world->GetPopulation().GetCell(m_organism->GetCellID()).GetCellFaced().GetID(), 1);
+}
+
+bool cHardwareCPU::Inst_SenseFacedResource2(cAvidaContext& ctx)
+{
+ return DoSenseResourceX(REG_BX, m_world->GetPopulation().GetCell(m_organism->GetCellID()).GetCellFaced().GetID(), 2);
+}
+
+
+bool cHardwareCPU::DoSenseResourceX(int reg_to_set, int cell_id, int resid)
+{
+ assert(resid >= 0);
+
+ cPopulation& pop = m_world->GetPopulation();
+
+ const tArray<double> & res_count = pop.GetCellResources(cell_id) +
+ pop.GetDemeCellResources(pop.GetCell(cell_id).GetDemeID(), cell_id);
+
+ // Make sure we have the resource requested
+ if (resid >= res_count.GetSize()) return false;
+
+ GetRegister(reg_to_set) = (int) res_count[resid];
+
+ return true;
+
+}
+
+
/* Convert modifying NOPs to the index of a resource. If there are fewer
* than the number of NOPs required to specify a resource, find the subset
* of resources. (Motivation: can evolve to be more specific if there is
@@ -3789,7 +3850,7 @@
// energy may be lost in transfer
void cHardwareCPU::DoEnergyDonateAmount(cOrganism* to_org, const double amount)
{
- double losspct = m_world->GetConfig().ENERGY_SHARING_LOSS.Get();
+ double losspct = m_world->GetConfig().RESOURCE_SHARING_LOSS.Get();
assert(to_org != NULL);
assert(amount >= 0);
@@ -4962,6 +5023,110 @@
} //End Inst_DecreaseEnergyDonation()
+// Move a fraction of the given resource present at the current cell to the specified cell.
+// Note: This function doesn't work with deme-level resources.
+void cHardwareCPU::DoResourceDonatePercent(const int to_cell, const int resource_id, const double frac_resource_given)
+{
+ assert(to_cell >= 0);
+ assert(resource_id >= 0);
+ assert(frac_resource_given >= 0);
+ assert(frac_resource_given <= 1);
+
+ const tArray<double> &resources = m_organism->GetOrgInterface().GetResources();
+ if(resource_id >= resources.GetSize()) return;
+
+ const double amount = max(0.0, frac_resource_given * resources[resource_id]);
+
+ DoResourceDonateAmount(to_cell, resource_id, amount);
+
+} //End DoResourceDonatePercent()
+
+
+// Donate a portion of the given resource present at the current cell to the specified cell.
+// Note: This function doesn't work with deme-level resources.
+void cHardwareCPU::DoResourceDonateAmount(const int to_cell, const int resource_id, const double amount)
+{
+ assert(to_cell >= 0);
+ assert(amount >= 0);
+ assert(resource_id >= 0);
+
+ const tArray<double> &src_resources = m_organism->GetOrgInterface().GetResources();
+ const tArray<double> &dest_resources = m_world->GetPopulation().GetCellResources(to_cell);
+
+ assert(resource_id < src_resources.GetSize());
+ assert(resource_id < dest_resources.GetSize());
+
+ const double donation = min(amount, src_resources[resource_id]);
+ const double decay = m_world->GetConfig().RESOURCE_SHARING_LOSS.Get();
+
+ assert(decay >= 0);
+ assert(decay <= 1);
+
+ tArray<double> src_change;
+ tArray<double> dest_change;
+
+ src_change.Resize(src_resources.GetSize(), 0);
+ dest_change.Resize(dest_resources.GetSize(), 0);
+
+ src_change[resource_id] = -1 * donation;
+ dest_change[resource_id] = (1 - decay) * donation;
+
+ m_organism->GetOrgInterface().UpdateResources(src_change);
+ m_world->GetPopulation().UpdateCellResources(dest_change, to_cell);
+
+} //End DoResourceDonateAmount()
+
+
+//Donate a fraction of nop-specified resource at organism's location to cell faced
+bool cHardwareCPU::DonateResourceX(cAvidaContext& ctx, const int res_id)
+{
+ assert(m_organism != 0);
+ assert(res_id >= 0);
+
+ const double pct = 0.1;
+
+ int current_cell, faced_cell;
+
+ current_cell = m_organism->GetCellID();
+
+ if(current_cell == -1) {
+ return false;
+ }
+
+ cPopulation& pop = m_world->GetPopulation();
+ faced_cell = pop.GetCell(current_cell).GetCellFaced().GetID();
+
+ if(faced_cell == -1) {
+ return false;
+ }
+
+ DoResourceDonatePercent(faced_cell, res_id, pct);
+
+ return true;
+
+} //End DonateResourceX()
+
+
+//Donate a fraction of nop-specified resource at organism's location to cell faced
+bool cHardwareCPU::Inst_DonateResource0(cAvidaContext& ctx)
+{
+ return DonateResourceX(ctx ,0);
+} //End Inst_DonateResource0()
+
+
+//Donate a fraction of nop-specified resource at organism's location to cell faced
+bool cHardwareCPU::Inst_DonateResource1(cAvidaContext& ctx)
+{
+ return DonateResourceX(ctx, 1);
+} //End Inst_DonateResource1()
+
+//Donate a fraction of nop-specified resource at organism's location to cell faced
+bool cHardwareCPU::Inst_DonateResource2(cAvidaContext& ctx)
+{
+ return DonateResourceX(ctx, 2);
+} //End Inst_DonateResource2()
+
+
bool cHardwareCPU::Inst_SearchF(cAvidaContext& ctx)
{
ReadLabel();
Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h 2009-08-11 12:54:54 UTC (rev 3363)
+++ development/source/cpu/cHardwareCPU.h 2009-08-12 14:09:27 UTC (rev 3364)
@@ -493,6 +493,13 @@
bool Inst_SenseUnit(cAvidaContext& ctx);
bool Inst_SenseMult100(cAvidaContext& ctx);
bool DoSense(cAvidaContext& ctx, int conversion_method, double base);
+ bool DoSenseResourceX(int reg_to_set, int cell_id, int resid);
+ bool Inst_SenseResource0(cAvidaContext& ctx);
+ bool Inst_SenseResource1(cAvidaContext& ctx);
+ bool Inst_SenseResource2(cAvidaContext& ctx);
+ bool Inst_SenseFacedResource0(cAvidaContext& ctx);
+ bool Inst_SenseFacedResource1(cAvidaContext& ctx);
+ bool Inst_SenseFacedResource2(cAvidaContext& ctx);
// Resources
bool FindModifiedResource(int& start_index, int& end_index, int& spec_id);
@@ -536,6 +543,13 @@
bool Inst_IncreaseEnergyDonation(cAvidaContext& ctx);
bool Inst_DecreaseEnergyDonation(cAvidaContext& ctx);
+ void DoResourceDonatePercent(const int to_cell, const int resource_id, const double frac_resource_given);
+ void DoResourceDonateAmount(const int to_cell, const int resource_id, const double amount);
+ bool DonateResourceX(cAvidaContext& ctx, const int res_id);
+ bool Inst_DonateResource0(cAvidaContext& ctx);
+ bool Inst_DonateResource1(cAvidaContext& ctx);
+ bool Inst_DonateResource2(cAvidaContext& ctx);
+
bool Inst_SearchF(cAvidaContext& ctx);
bool Inst_SearchB(cAvidaContext& ctx);
bool Inst_MemSize(cAvidaContext& ctx);
Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h 2009-08-11 12:54:54 UTC (rev 3363)
+++ development/source/main/cAvidaConfig.h 2009-08-12 14:09:27 UTC (rev 3364)
@@ -549,7 +549,7 @@
CONFIG_ADD_VAR(ENERGY_SHARING_METHOD, int, 0, "Method for sharing energy. 0=receiver must actively receive/request, 1=energy pushed on receiver");
CONFIG_ADD_VAR(ENERGY_SHARING_PCT, double, 0.0, "Percent of energy to share");
CONFIG_ADD_VAR(ENERGY_SHARING_INCREMENT, double, 0.01, "Amount to change percent energy shared");
- CONFIG_ADD_VAR(ENERGY_SHARING_LOSS, double, 0.0, "Percent of shared energy lost in transfer");
+ CONFIG_ADD_VAR(RESOURCE_SHARING_LOSS, double, 0.0, "Fraction of shared resource lost in transfer");
CONFIG_ADD_VAR(ENERGY_SHARING_UPDATE_METABOLIC, bool, 0, "0/1 (off/on) - Whether to update an organism's metabolic rate on donate or reception/application of energy");
CONFIG_ADD_VAR(LOG_ENERGY_SHARING, bool, 0, "Whether or not to log energy shares. 0/1 (off/on)");
Modified: development/source/main/cDeme.h
===================================================================
--- development/source/main/cDeme.h 2009-08-11 12:54:54 UTC (rev 3363)
+++ development/source/main/cDeme.h 2009-08-12 14:09:27 UTC (rev 3364)
@@ -260,6 +260,7 @@
void OrganismDeath(cPopulationCell& cell);
const cResourceCount& GetDemeResourceCount() const { return deme_resource_count; }
+ cResourceCount& GetDemeResources() { return deme_resource_count; }
void SetResource(int id, double new_level) { deme_resource_count.Set(id, new_level); }
double GetSpatialResource(int rel_cellid, int resource_id) const;
void AdjustSpatialResource(int rel_cellid, int resource_id, double amount);
More information about the Avida-cvs
mailing list