Skip to content

Commit

Permalink
Add verbose_on/off functions to lfmcmc to enable progress bar (#63)
Browse files Browse the repository at this point in the history
* Update with latest from C++ library

* Add verbose_on/off functions to lfmcmc to enable/disable progress bar
apulsipher authored Dec 12, 2024
1 parent 6c6568d commit 6c3beac
Showing 10 changed files with 121 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -83,7 +83,9 @@ S3method(set_param,epiworld_model)
S3method(size,epiworld_model)
S3method(summary,epiworld_model)
S3method(today,epiworld_model)
S3method(verbose_off,epiworld_lfmcmc)
S3method(verbose_off,epiworld_model)
S3method(verbose_on,epiworld_lfmcmc)
S3method(verbose_on,epiworld_model)
export(LFMCMC)
export(ModelDiffNet)
20 changes: 20 additions & 0 deletions R/LFMCMC.R
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@ stopifnot_lfmcmc <- function(x) {
#' epsil <- 1.0
#'
#' # Run the LFMCMC simulation
#' verbose_off(lfmcmc_model)
#' run_lfmcmc(
#' lfmcmc = lfmcmc_model,
#' params_init_ = par0,
@@ -382,3 +383,22 @@ get_n_samples <- function(lfmcmc) {
get_n_samples_cpp(lfmcmc)

}

#' @rdname LFMCMC
#' @export
#' @returns
#' - The `verbose_on` and `verbose_off` functions return the same model, however
#' `verbose_off` returns the model with no progress bar.
#' @details
#' The `verbose_on` and `verbose_off` functions activate and deactivate printing
#' progress on screen, respectively. Both functions return the model (`x`) invisibly.

#' @export
verbose_off.epiworld_lfmcmc <- function(x) {
invisible(verbose_off_lfmcmc_cpp(x))
}

#' @export
verbose_on.epiworld_lfmcmc <- function(x) {
invisible(verbose_on_lfmcmc_cpp(x))
}
8 changes: 8 additions & 0 deletions R/cpp11.R
Original file line number Diff line number Diff line change
@@ -300,6 +300,14 @@ get_n_params_cpp <- function(lfmcmc) {
.Call(`_epiworldR_get_n_params_cpp`, lfmcmc)
}

verbose_off_lfmcmc_cpp <- function(lfmcmc) {
.Call(`_epiworldR_verbose_off_lfmcmc_cpp`, lfmcmc)
}

verbose_on_lfmcmc_cpp <- function(lfmcmc) {
.Call(`_epiworldR_verbose_on_lfmcmc_cpp`, lfmcmc)
}

print_cpp <- function(m, lite) {
.Call(`_epiworldR_print_cpp`, m, lite)
}
7 changes: 7 additions & 0 deletions inst/include/epiworld/math/lfmcmc/lfmcmc-bones.hpp
Original file line number Diff line number Diff line change
@@ -170,6 +170,7 @@ class LFMCMC {
std::chrono::time_point<std::chrono::steady_clock> m_start_time;
std::chrono::time_point<std::chrono::steady_clock> m_end_time;

// Timing
// std::chrono::milliseconds
std::chrono::duration<epiworld_double,std::micro> m_elapsed_time =
std::chrono::duration<epiworld_double,std::micro>::zero();
@@ -183,6 +184,10 @@ class LFMCMC {

void chrono_start();
void chrono_end();

// Progress
bool verbose = true;
Progress progress_bar;

public:

@@ -254,6 +259,8 @@ class LFMCMC {
std::vector< epiworld_double > get_mean_stats();

// Printing
LFMCMC<TData> & verbose_off();
LFMCMC<TData> & verbose_on();
void print(size_t burnin = 0u) const;

};
24 changes: 24 additions & 0 deletions inst/include/epiworld/math/lfmcmc/lfmcmc-meat.hpp
Original file line number Diff line number Diff line change
@@ -263,6 +263,13 @@ inline void LFMCMC<TData>::run(
for (size_t k = 0u; k < m_n_params; ++k)
m_accepted_params[k] = m_initial_params[k];

// Init progress bar
progress_bar = Progress(m_n_samples, 80);
if (verbose) {
progress_bar.next();
}

// Run LFMCMC
for (size_t i = 1u; i < m_n_samples; ++i)
{
// Step 1: Generate a proposal and store it in m_current_params
@@ -319,6 +326,9 @@ inline void LFMCMC<TData>::run(
for (size_t k = 0u; k < m_n_params; ++k)
m_accepted_params[i * m_n_params + k] = m_previous_params[k];

if (verbose) {
progress_bar.next();
}
}

// End timing
@@ -544,4 +554,18 @@ inline std::vector< epiworld_double > LFMCMC<TData>::get_mean_stats()

}

template<typename TData>
inline LFMCMC<TData> & LFMCMC<TData>::verbose_off()
{
verbose = false;
return *this;
}

template<typename TData>
inline LFMCMC<TData> & LFMCMC<TData>::verbose_on()
{
verbose = true;
return *this;
}

#endif
13 changes: 13 additions & 0 deletions inst/tinytest/test-lfmcmc.R
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@ par0 <- c(0.1, 0.5)
n_samp <- 2000
epsil <- 1.0

expect_silent(verbose_off(lfmcmc_model))
expect_silent(run_lfmcmc(
lfmcmc = lfmcmc_model,
params_init_ = par0,
@@ -79,6 +80,17 @@ expect_error(print(lfmcmc_model, burnin = n_samp + 50), "burnin is greater than
expect_error(print(lfmcmc_model, burnin = -n_samp / 2), "argument must be a non-negative integer")
expect_error(print(lfmcmc_model, burnin = "n_samp"), "argument must be an integer")

# Check verbose_on -------------------------------------------------------------
expect_silent(verbose_on(lfmcmc_model))
expect_stdout(run_lfmcmc(
lfmcmc = lfmcmc_model,
params_init_ = par0,
n_samples_ = n_samp,
epsilon_ = epsil,
seed = model_seed
))
verbose_off(lfmcmc_model)

# Check LFMCMC getters ---------------------------------------------------------
expect_equal(get_n_samples(lfmcmc_model), n_samp)

@@ -196,6 +208,7 @@ lfmcmc_model <- LFMCMC() |>
set_observed_data(Y)

# Run LFMCMC
verbose_off(lfmcmc_model)
x <- run_lfmcmc(
lfmcmc = lfmcmc_model,
params_init_ = c(0, 1),
12 changes: 12 additions & 0 deletions man/LFMCMC.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions src/cpp11.cpp
Original file line number Diff line number Diff line change
@@ -530,6 +530,20 @@ extern "C" SEXP _epiworldR_get_n_params_cpp(SEXP lfmcmc) {
return cpp11::as_sexp(get_n_params_cpp(cpp11::as_cpp<cpp11::decay_t<SEXP>>(lfmcmc)));
END_CPP11
}
// lfmcmc.cpp
SEXP verbose_off_lfmcmc_cpp(SEXP lfmcmc);
extern "C" SEXP _epiworldR_verbose_off_lfmcmc_cpp(SEXP lfmcmc) {
BEGIN_CPP11
return cpp11::as_sexp(verbose_off_lfmcmc_cpp(cpp11::as_cpp<cpp11::decay_t<SEXP>>(lfmcmc)));
END_CPP11
}
// lfmcmc.cpp
SEXP verbose_on_lfmcmc_cpp(SEXP lfmcmc);
extern "C" SEXP _epiworldR_verbose_on_lfmcmc_cpp(SEXP lfmcmc) {
BEGIN_CPP11
return cpp11::as_sexp(verbose_on_lfmcmc_cpp(cpp11::as_cpp<cpp11::decay_t<SEXP>>(lfmcmc)));
END_CPP11
}
// model.cpp
SEXP print_cpp(SEXP m, bool lite);
extern "C" SEXP _epiworldR_print_cpp(SEXP m, SEXP lite) {
@@ -1212,7 +1226,9 @@ static const R_CallMethodDef CallEntries[] = {
{"_epiworldR_use_kernel_fun_gaussian_cpp", (DL_FUNC) &_epiworldR_use_kernel_fun_gaussian_cpp, 1},
{"_epiworldR_use_proposal_norm_reflective_cpp", (DL_FUNC) &_epiworldR_use_proposal_norm_reflective_cpp, 1},
{"_epiworldR_verbose_off_cpp", (DL_FUNC) &_epiworldR_verbose_off_cpp, 1},
{"_epiworldR_verbose_off_lfmcmc_cpp", (DL_FUNC) &_epiworldR_verbose_off_lfmcmc_cpp, 1},
{"_epiworldR_verbose_on_cpp", (DL_FUNC) &_epiworldR_verbose_on_cpp, 1},
{"_epiworldR_verbose_on_lfmcmc_cpp", (DL_FUNC) &_epiworldR_verbose_on_lfmcmc_cpp, 1},
{"_epiworldR_virus_cpp", (DL_FUNC) &_epiworldR_virus_cpp, 8},
{"_epiworldR_virus_fun_logit_cpp", (DL_FUNC) &_epiworldR_virus_fun_logit_cpp, 3},
{"_epiworldR_virus_set_state_cpp", (DL_FUNC) &_epiworldR_virus_set_state_cpp, 4},
18 changes: 18 additions & 0 deletions src/lfmcmc.cpp
Original file line number Diff line number Diff line change
@@ -305,4 +305,22 @@ int get_n_params_cpp(SEXP lfmcmc) {

}

[[cpp11::register]]
SEXP verbose_off_lfmcmc_cpp(SEXP lfmcmc) {

WrapLFMCMC(lfmcmc_ptr)(lfmcmc);
lfmcmc_ptr->verbose_off();
return lfmcmc;

}

[[cpp11::register]]
SEXP verbose_on_lfmcmc_cpp(SEXP lfmcmc) {

WrapLFMCMC(lfmcmc_ptr)(lfmcmc);
lfmcmc_ptr->verbose_on();
return lfmcmc;

}

#undef WrapLFMCMC
1 change: 1 addition & 0 deletions vignettes/likelihood-free-mcmc.Rmd
Original file line number Diff line number Diff line change
@@ -108,6 +108,7 @@ n_samp <- 2000
epsil <- 1.0
# Run the LFMCMC simulation
verbose_off(lfmcmc_model)
run_lfmcmc(
lfmcmc = lfmcmc_model,
params_init_ = par0,

0 comments on commit 6c3beac

Please sign in to comment.