From b7719bda503425a8b6ade6fdead7fbf1f90471c3 Mon Sep 17 00:00:00 2001 From: "George G. Vega Yon" Date: Wed, 12 Jun 2024 07:41:15 -0600 Subject: [PATCH] Forgot dist header --- include/epiworld/tool-distribute-meat.hpp | 103 ++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 include/epiworld/tool-distribute-meat.hpp diff --git a/include/epiworld/tool-distribute-meat.hpp b/include/epiworld/tool-distribute-meat.hpp new file mode 100644 index 00000000..7044f615 --- /dev/null +++ b/include/epiworld/tool-distribute-meat.hpp @@ -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 +inline ToolToAgentFun distribute_tool_to_set( + std::vector< size_t > agents_ids +) { + + return [agents_ids]( + Tool & tool, Model * model + ) -> void + { + // Adding action + for (auto i: agents_ids) + { + model->get_agent(i).add_tool( + tool, + const_cast * >(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 +inline ToolToAgentFun distribute_tool_randomly( + epiworld_double prevalence, + bool as_proportion = true +) { + + return [prevalence, as_proportion]( + Tool & tool, Model * model + ) -> void { + + // Picking how many + int n_to_distribute; + int n = model->size(); + if (as_proportion) + { + n_to_distribute = static_cast(std::floor(prevalence * n)); + + if (n_to_distribute == n) + n_to_distribute--; + } + else + { + n_to_distribute = static_cast(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( + floor(model->runif() * n--) + ); + + if ((loc > 0) && (loc == n)) + loc--; + + population[idx[loc]].add_tool( + tool, + const_cast< Model * >(model) + ); + + std::swap(idx[loc], idx[n]); + + } + + }; + +} +#endif \ No newline at end of file