Skip to content

Commit

Permalink
Adding global actions for distributing the virus
Browse files Browse the repository at this point in the history
  • Loading branch information
gvegayon committed May 24, 2023
1 parent ef4cef6 commit 8e21244
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 2 deletions.
145 changes: 144 additions & 1 deletion epiworld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12728,8 +12728,10 @@ class Agent {

bool has_tool(epiworld_fast_uint t) const;
bool has_tool(std::string name) const;
bool has_tool(const Tool<TSeq> & t) const;
bool has_virus(epiworld_fast_uint t) const;
bool has_virus(std::string name) const;
bool has_virus(const Virus<TSeq> & v) const;

void print(Model<TSeq> * model, bool compressed = false) const;

Expand Down Expand Up @@ -13834,6 +13836,14 @@ inline bool Agent<TSeq>::has_tool(std::string name) const

}

template<typename TSeq>
inline bool Agent<TSeq>::has_tool(const Tool<TSeq> & tool) const
{

return has_tool(tool.get_id());

}

template<typename TSeq>
inline bool Agent<TSeq>::has_virus(epiworld_fast_uint t) const
{
Expand All @@ -13856,6 +13866,14 @@ inline bool Agent<TSeq>::has_virus(std::string name) const

}

template<typename TSeq>
inline bool Agent<TSeq>::has_virus(const Virus<TSeq> & virus) const
{

return has_virus(virus.get_id());

}

template<typename TSeq>
inline void Agent<TSeq>::print(
Model<TSeq> * model,
Expand Down Expand Up @@ -16143,7 +16161,9 @@ inline void ModelSEIRD<TSeq>::update_exposed(
) ? 100.0 : -100.0;


} else if (m->today() >= v->get_data()[0u])
}

if (m->today() >= v->get_data()[0u])
{
p->change_state(m, S::Infected, epiworld::Queue<TSeq>::Everyone);
return;
Expand Down Expand Up @@ -16633,6 +16653,129 @@ inline ModelSIRLogit<TSeq>::ModelSIRLogit(



// Including additional modules
/*//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Start of -include/epiworld/globalactions-meat.hpp-
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////*/


#ifndef GLOBALACTIONS_MEAT_HPP
#define GLOBALACTIONS_MEAT_HPP


// This function creates a global action that distributes a tool
// to agents with probability p.
/**
* @brief Global action that distributes a tool to agents with probability p.
*
* @tparam TSeq Sequence type (should match `TSeq` across the model)
* @param p Probability of distributing the tool.
* @param tool_fun Tool function.
* @return std::function<void(Model<TSeq>*)>
*/
template<typename TSeq>
inline std::function<void(Model<TSeq>*)> globalaction_tool(
double p,
ToolFun<TSeq> tool_fun
) {

std::function<void(Model<TSeq>*)> fun = [p,tool_fun](
Model<TSeq> * model
) -> void {

for (auto & agent : model->agents)
{

// Check if the agent has the tool_fun
if (agent.has_tool(tool_fun))
continue;

// Adding the tool
if (model->runif() < p)
agent.add_tool(tool_fun, model);


}

return;


};

return fun;

}

// Same function as above, but p is now a function of a vector of coefficients
// and a vector of variables.
/**
* @brief Global action that distributes a tool to agents with probability
* p = 1 / (1 + exp(-\sum_i coef_i * agent(vars_i))).
*
* @tparam TSeq Sequence type (should match `TSeq` across the model)
* @param coefs Vector of coefficients.
* @param vars Vector of variables.
* @param tool_fun Tool function.
* @return std::function<void(Model<TSeq>*)>
*/
template<typename TSeq>
inline std::function<void(Model<TSeq>*)> globalaction_tool_logit(
std::vector< epiworld_double > coefs,
std::vector< size_t > vars,
ToolFun<TSeq> tool_fun
) {

std::function<void(Model<TSeq>*)> fun = [coefs,vars,tool_fun](
Model<TSeq> * model
) -> void {

for (auto & agent : model->agents)
{

// Check if the agent has the tool_fun
if (agent.has_tool(tool_fun))
continue;

// Computing the probability using a logit. Uses OpenMP reduction
// to sum the coefficients.
#pragma omp parallel for reduction(+:p)
double p = 0.0;
for (size_t i = 0u; i < coefs.size(); ++i)
p += coefs.at(i) * agent(vars[i]);

p = 1.0 / (1.0 + std::exp(-p));

// Adding the tool
if (model->runif() < p)
agent.add_tool(tool_fun, model);


}

return;


};

return fun;

}

#endif
/*//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
End of -include/epiworld/globalactions-meat.hpp-
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////*/



}

#endif
2 changes: 2 additions & 0 deletions include/epiworld/agent-bones.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,10 @@ class Agent {

bool has_tool(epiworld_fast_uint t) const;
bool has_tool(std::string name) const;
bool has_tool(const Tool<TSeq> & t) const;
bool has_virus(epiworld_fast_uint t) const;
bool has_virus(std::string name) const;
bool has_virus(const Virus<TSeq> & v) const;

void print(Model<TSeq> * model, bool compressed = false) const;

Expand Down
16 changes: 16 additions & 0 deletions include/epiworld/agent-meat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,14 @@ inline bool Agent<TSeq>::has_tool(std::string name) const

}

template<typename TSeq>
inline bool Agent<TSeq>::has_tool(const Tool<TSeq> & tool) const
{

return has_tool(tool.get_id());

}

template<typename TSeq>
inline bool Agent<TSeq>::has_virus(epiworld_fast_uint t) const
{
Expand All @@ -790,6 +798,14 @@ inline bool Agent<TSeq>::has_virus(std::string name) const

}

template<typename TSeq>
inline bool Agent<TSeq>::has_virus(const Virus<TSeq> & virus) const
{

return has_virus(virus.get_id());

}

template<typename TSeq>
inline void Agent<TSeq>::print(
Model<TSeq> * model,
Expand Down
3 changes: 3 additions & 0 deletions include/epiworld/epiworld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ namespace epiworld {

#include "models/models.hpp"

// Including additional modules
#include "globalactions-meat.hpp"

}

#endif
103 changes: 103 additions & 0 deletions include/epiworld/globalactions-meat.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#ifndef GLOBALACTIONS_MEAT_HPP
#define GLOBALACTIONS_MEAT_HPP


// This function creates a global action that distributes a tool
// to agents with probability p.
/**
* @brief Global action that distributes a tool to agents with probability p.
*
* @tparam TSeq Sequence type (should match `TSeq` across the model)
* @param p Probability of distributing the tool.
* @param tool_fun Tool function.
* @return std::function<void(Model<TSeq>*)>
*/
template<typename TSeq>
inline std::function<void(Model<TSeq>*)> globalaction_tool(
double p,
ToolFun<TSeq> tool_fun
) {

std::function<void(Model<TSeq>*)> fun = [p,tool_fun](
Model<TSeq> * model
) -> void {

for (auto & agent : model->agents)
{

// Check if the agent has the tool_fun
if (agent.has_tool(tool_fun))
continue;

// Adding the tool
if (model->runif() < p)
agent.add_tool(tool_fun, model);


}

return;


};

return fun;

}

// Same function as above, but p is now a function of a vector of coefficients
// and a vector of variables.
/**
* @brief Global action that distributes a tool to agents with probability
* p = 1 / (1 + exp(-\sum_i coef_i * agent(vars_i))).
*
* @tparam TSeq Sequence type (should match `TSeq` across the model)
* @param coefs Vector of coefficients.
* @param vars Vector of variables.
* @param tool_fun Tool function.
* @return std::function<void(Model<TSeq>*)>
*/
template<typename TSeq>
inline std::function<void(Model<TSeq>*)> globalaction_tool_logit(
std::vector< epiworld_double > coefs,
std::vector< size_t > vars,
ToolFun<TSeq> tool_fun
) {

std::function<void(Model<TSeq>*)> fun = [coefs,vars,tool_fun](
Model<TSeq> * model
) -> void {

for (auto & agent : model->agents)
{

// Check if the agent has the tool_fun
if (agent.has_tool(tool_fun))
continue;

// Computing the probability using a logit. Uses OpenMP reduction
// to sum the coefficients.
#pragma omp parallel for reduction(+:p)
double p = 0.0;
for (size_t i = 0u; i < coefs.size(); ++i)
p += coefs.at(i) * agent(vars[i]);

p = 1.0 / (1.0 + std::exp(-p));

// Adding the tool
if (model->runif() < p)
agent.add_tool(tool_fun, model);


}

return;


};

return fun;

}

#endif
4 changes: 3 additions & 1 deletion include/epiworld/models/seird.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ inline void ModelSEIRD<TSeq>::update_exposed(
) ? 100.0 : -100.0;


} else if (m->today() >= v->get_data()[0u])
}

if (m->today() >= v->get_data()[0u])
{
p->change_state(m, S::Infected, epiworld::Queue<TSeq>::Everyone);
return;
Expand Down

0 comments on commit 8e21244

Please sign in to comment.