-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
103 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#ifndef TOOL_DISTRIBUTE_MEAT_HPP | ||
#define TOOL_DISTRIBUTE_MEAT_HPP | ||
|
||
/** | ||
* @brief Distributes a tool to a set of agents. | ||
* | ||
* This function takes a vector of agent IDs and returns a lambda function that | ||
* distributes a tool to each agent in the set. | ||
* | ||
* The lambda function takes a reference to a Tool object and a pointer to a | ||
* Model object as parameters. It iterates over the agent IDs and adds the tool | ||
* to each agent using the add_tool() method of the Model object. | ||
* | ||
* @tparam TSeq The sequence type used in the Tool and Model objects. | ||
* @param agents_ids A vector of agent IDs representing the set of agents to | ||
* distribute the tool to. | ||
* @return A lambda function that distributes the tool to the set of agents. | ||
*/ | ||
template<typename TSeq = EPI_DEFAULT_TSEQ> | ||
inline ToolToAgentFun<TSeq> distribute_tool_to_set( | ||
std::vector< size_t > agents_ids | ||
) { | ||
|
||
return [agents_ids]( | ||
Tool<TSeq> & tool, Model<TSeq> * model | ||
) -> void | ||
{ | ||
// Adding action | ||
for (auto i: agents_ids) | ||
{ | ||
model->get_agent(i).add_tool( | ||
tool, | ||
const_cast<Model<TSeq> * >(model) | ||
); | ||
} | ||
}; | ||
|
||
} | ||
|
||
/** | ||
* Function template to distribute a tool randomly to agents in a model. | ||
* | ||
* @tparam TSeq The sequence type used in the model. | ||
* @param prevalence The prevalence of the tool in the population. | ||
* @param as_proportion Flag indicating whether the prevalence is given as a | ||
* proportion or an absolute value. | ||
* @return A lambda function that distributes the tool randomly to agents in | ||
* the model. | ||
*/ | ||
template<typename TSeq = EPI_DEFAULT_TSEQ> | ||
inline ToolToAgentFun<TSeq> distribute_tool_randomly( | ||
epiworld_double prevalence, | ||
bool as_proportion = true | ||
) { | ||
|
||
return [prevalence, as_proportion]( | ||
Tool<TSeq> & tool, Model<TSeq> * model | ||
) -> void { | ||
|
||
// Picking how many | ||
int n_to_distribute; | ||
int n = model->size(); | ||
if (as_proportion) | ||
{ | ||
n_to_distribute = static_cast<int>(std::floor(prevalence * n)); | ||
|
||
if (n_to_distribute == n) | ||
n_to_distribute--; | ||
} | ||
else | ||
{ | ||
n_to_distribute = static_cast<int>(prevalence); | ||
} | ||
|
||
if (n_to_distribute > n) | ||
throw std::range_error("There are only " + std::to_string(n) + | ||
" individuals in the population. Cannot add the tool to " + std::to_string(n_to_distribute)); | ||
|
||
std::vector< int > idx(n); | ||
std::iota(idx.begin(), idx.end(), 0); | ||
auto & population = model->get_agents(); | ||
for (int i = 0u; i < n_to_distribute; ++i) | ||
{ | ||
int loc = static_cast<epiworld_fast_uint>( | ||
floor(model->runif() * n--) | ||
); | ||
|
||
if ((loc > 0) && (loc == n)) | ||
loc--; | ||
|
||
population[idx[loc]].add_tool( | ||
tool, | ||
const_cast< Model<TSeq> * >(model) | ||
); | ||
|
||
std::swap(idx[loc], idx[n]); | ||
|
||
} | ||
|
||
}; | ||
|
||
} | ||
#endif |