From 7e638ac963e72906657a19587107a443ae274739 Mon Sep 17 00:00:00 2001 From: "George G. Vega Yon" Date: Sun, 3 Dec 2023 10:51:06 -0700 Subject: [PATCH] Adding clone method --- NAMESPACE | 1 + R/cpp11.R | 4 ++++ R/model-methods.R | 15 +++++++++++++++ man/epiworld-methods.Rd | 11 +++++++++++ src/cpp11.cpp | 8 ++++++++ src/model.cpp | 13 +++++++++++++ 6 files changed, 52 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index 8acbfbe6..2e23cdec 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -102,6 +102,7 @@ export(add_virus_n) export(agents_from_edgelist) export(agents_smallworld) export(change_state) +export(clone_model) export(get_agents) export(get_agents_data_ncols) export(get_agents_states) diff --git a/R/cpp11.R b/R/cpp11.R index ee345e3c..d799599d 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -260,6 +260,10 @@ initial_states_cpp <- function(model, proportions) { .Call(`_epiworldR_initial_states_cpp`, model, proportions) } +clone_model_cpp <- function(model) { + .Call(`_epiworldR_clone_model_cpp`, model) +} + tool_cpp <- function(name, susceptibility_reduction, transmission_reduction, recovery_enhancer, death_reduction) { .Call(`_epiworldR_tool_cpp`, name, susceptibility_reduction, transmission_reduction, recovery_enhancer, death_reduction) } diff --git a/R/model-methods.R b/R/model-methods.R index a4f27bbd..19991701 100644 --- a/R/model-methods.R +++ b/R/model-methods.R @@ -365,3 +365,18 @@ initial_states <- function(model, proportions) { } +#' @rdname epiworld-methods +#' @export +#' @details `epiworld_model` objects are pointers to an underlying C++ class +#' in `epiworld`. To generate a copy of a model, use `clone_model`, otherwise, +#' the assignment operator will only copy the pointer. +#' @return +#' - `clone_model` returns a copy of the model. +clone_model <- function(model) { + stopifnot_model(model) + structure( + clone_model_cpp(model), + class = class(model) + ) +} + diff --git a/man/epiworld-methods.Rd b/man/epiworld-methods.Rd index f0be4980..0f175377 100644 --- a/man/epiworld-methods.Rd +++ b/man/epiworld-methods.Rd @@ -24,6 +24,7 @@ \alias{get_virus} \alias{get_tool} \alias{initial_states} +\alias{clone_model} \title{Methods for epiworldR objects} \usage{ queuing_on(x) @@ -67,6 +68,8 @@ get_virus(model, virus_pos) get_tool(model, tool_pos) initial_states(model, proportions) + +clone_model(model) } \arguments{ \item{x}{An object of class \code{epiworld_model}.} @@ -174,6 +177,10 @@ of \code{epiworld_model}. \itemize{ \item \code{inital_states} returns the model with an updated initial state. } + +\itemize{ +\item \code{clone_model} returns a copy of the model. +} } \description{ The functions described in this section are methods for objects of class @@ -184,6 +191,10 @@ and running the simulation. \details{ The \code{verbose_on} and \code{verbose_off} functions activate and deactivate printing progress on screen, respectively. Both functions return the model (\code{x}) invisibly. + +\code{epiworld_model} objects are pointers to an underlying C++ class +in \code{epiworld}. To generate a copy of a model, use \code{clone_model}, otherwise, +the assignment operator will only copy the pointer. } \examples{ diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 2fe6ced3..fdf878a5 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -460,6 +460,13 @@ extern "C" SEXP _epiworldR_initial_states_cpp(SEXP model, SEXP proportions) { return cpp11::as_sexp(initial_states_cpp(cpp11::as_cpp>(model), cpp11::as_cpp>(proportions))); END_CPP11 } +// model.cpp +SEXP clone_model_cpp(const SEXP & model); +extern "C" SEXP _epiworldR_clone_model_cpp(SEXP model) { + BEGIN_CPP11 + return cpp11::as_sexp(clone_model_cpp(cpp11::as_cpp>(model))); + END_CPP11 +} // tool.cpp SEXP tool_cpp(std::string name, double susceptibility_reduction, double transmission_reduction, double recovery_enhancer, double death_reduction); extern "C" SEXP _epiworldR_tool_cpp(SEXP name, SEXP susceptibility_reduction, SEXP transmission_reduction, SEXP recovery_enhancer, SEXP death_reduction) { @@ -787,6 +794,7 @@ static const R_CallMethodDef CallEntries[] = { {"_epiworldR_agents_from_edgelist_cpp", (DL_FUNC) &_epiworldR_agents_from_edgelist_cpp, 5}, {"_epiworldR_agents_smallworld_cpp", (DL_FUNC) &_epiworldR_agents_smallworld_cpp, 5}, {"_epiworldR_change_state_cpp", (DL_FUNC) &_epiworldR_change_state_cpp, 4}, + {"_epiworldR_clone_model_cpp", (DL_FUNC) &_epiworldR_clone_model_cpp, 1}, {"_epiworldR_get_agent_cpp", (DL_FUNC) &_epiworldR_get_agent_cpp, 2}, {"_epiworldR_get_agents_cpp", (DL_FUNC) &_epiworldR_get_agents_cpp, 1}, {"_epiworldR_get_agents_data_ncols_cpp", (DL_FUNC) &_epiworldR_get_agents_data_ncols_cpp, 1}, diff --git a/src/model.cpp b/src/model.cpp index 80e80fe1..3a054d04 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -315,3 +315,16 @@ SEXP initial_states_cpp(SEXP model, cpp11::doubles proportions) { return model; } + +// Function for cloning a model +[[cpp11::register]] +SEXP clone_model_cpp(const SEXP & model) { + + external_pointer> modelptr(model); + + return external_pointer>( + new Model<>(*modelptr) + ); + +} +