| Title: | R Interface to Jump-Switch-Flow Simulation |
|---|---|
| Description: | An R interface to Jump-Switch-Flow (JSF), a hybrid simulation framework for compartmental reaction models that combines stochastic jump dynamics at low population sizes with deterministic flow dynamics at high population sizes. Simulations are performed using the 'jsf' backend for 'Python' through 'reticulate', with structured R outputs for inspection, summary, and plotting. The underlying methodology is described in Germano et al. (2026) <doi:10.1007/s00285-026-02409-y>. |
| Authors: | Thanh Long Vu [aut, cre, cph], Domenic Germano [aut], Michael Lydeamore [aut] |
| Maintainer: | Thanh Long Vu <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-10-15 20:48:44 UTC |
| Source: | https://github.com/cran/rjsf |
Convert a JSF output data frame to a JSFResult object
as_jsf_result( x, method = "operator-splitting", config = list(), species_names = NULL )as_jsf_result( x, method = "operator-splitting", config = list(), species_names = NULL )
x |
Data frame returned by |
method |
JSF simulation method used. |
config |
List of simulation configuration values. |
species_names |
Optional character vector of species columns to include. |
A JSFResult object.
df <- data.frame( time = c(0, 0.1, 0.2), S = c(990, 988, 985), I = c(10, 12, 15), R = c(0, 0, 0) ) result <- as_jsf_result( df, config = list(model = "SIR", dt = 0.1) ) result summary(result)df <- data.frame( time = c(0, 0.1, 0.2), S = c(990, 988, 985), I = c(10, 12, 15), R = c(0, 0, 0) ) result <- as_jsf_result( df, config = list(model = "SIR", dt = 0.1) ) result summary(result)
This function checks whether the Python jsf module can be found by
reticulate in the currently active Python environment.
jsf_available()jsf_available()
A single logical value. TRUE if jsf is available, otherwise FALSE.
if (reticulate::py_available(initialize = FALSE)) { jsf_available() }if (reticulate::py_available(initialize = FALSE)) { jsf_available() }
This function runs a simple Lotka-Volterra predator-prey model using the
Python jsf package through reticulate.
jsf_lotka_volterra( prey0 = 50, predator0 = 10, prey_birth = 2, predation = 0.05, predator_death = 1.5, t_max = 10, dt = 0.01, switching_threshold = 30 )jsf_lotka_volterra( prey0 = 50, predator0 = 10, prey_birth = 2, predation = 0.05, predator_death = 1.5, t_max = 10, dt = 0.01, switching_threshold = 30 )
prey0 |
Initial prey population. |
predator0 |
Initial predator population. |
prey_birth |
Prey birth rate. |
predation |
Predation rate. |
predator_death |
Predator death rate. |
t_max |
Final simulation time. |
dt |
Time step for the continuous/ODE part of JSF. |
switching_threshold |
Switching threshold for both species. |
A data frame with columns time, prey, and predator.
if (interactive() && jsf_available()) { result <- jsf_lotka_volterra( prey0 = 50, predator0 = 10, t_max = 1 ) head(result) }if (interactive() && jsf_available()) { result <- jsf_lotka_volterra( prey0 = 50, predator0 = 10, t_max = 1 ) head(result) }
This is a general R wrapper around the Python jsf simulator.
It accepts an initial state, a Python rate function, reactant and product
stoichiometry matrices, and JSF configuration options.
jsf_simulate( x0, rates, reactant, product, do_disc, t_max, dt, switching_threshold, tau_threshold = NULL, tau_epsilon = 0.03, critical_threshold = 10, tau_debug = FALSE, tau_debug_every = 20, tau_debug_max = 30, species_names = NULL, enforce_do = NULL, method = "operator-splitting", return_type = c("data.frame", "JSFResult") )jsf_simulate( x0, rates, reactant, product, do_disc, t_max, dt, switching_threshold, tau_threshold = NULL, tau_epsilon = 0.03, critical_threshold = 10, tau_debug = FALSE, tau_debug_every = 20, tau_debug_max = 30, species_names = NULL, enforce_do = NULL, method = "operator-splitting", return_type = c("data.frame", "JSFResult") )
x0 |
Numeric vector of initial states. |
rates |
Python callable rate function, usually created with
|
reactant |
Matrix where each row gives the reactants for one reaction. |
product |
Matrix where each row gives the products for one reaction. |
do_disc |
Integer vector indicating which species may be treated discretely/stochastically. |
t_max |
Final simulation time. |
dt |
Time step for the continuous/ODE part of JSF. |
switching_threshold |
Switching threshold. Can be a scalar or one value per species. |
tau_threshold |
Threshold controlling when species are handled by the
tau-leaping component. May be |
tau_epsilon |
Positive numeric scalar specifying the tau-leaping epsilon parameter passed to the Python JSF backend. |
critical_threshold |
Non-negative numeric scalar specifying the critical-reaction threshold passed to the Python JSF backend. |
tau_debug |
Logical. If |
tau_debug_every |
Integer controlling how often tau-leaping diagnostic information is printed. |
tau_debug_max |
Integer giving the maximum number of tau-leaping diagnostic messages to print. |
species_names |
Optional character vector of species names. |
enforce_do |
Integer vector controlling enforced discrete behaviour. Defaults to zero for all species. |
method |
JSF simulation method. Supported values include |
return_type |
Output type. Either |
If return_type = "data.frame", a data frame with a time column
and one column per species. If return_type = "JSFResult", a JSFResult
object.
if (interactive() && jsf_available()) { rates_lv <- reticulate::py_eval( "lambda x, t: [2.0 * x[0], 1.5 * x[1], 0.05 * x[0] * x[1]]" ) result <- jsf_simulate( x0 = c(prey = 50, predator = 10), rates = rates_lv, reactant = matrix( c( 1, 0, 0, 1, 1, 1 ), ncol = 2, byrow = TRUE ), product = matrix( c( 2, 0, 0, 0, 0, 2 ), ncol = 2, byrow = TRUE ), do_disc = c(1, 1), t_max = 1, dt = 0.01, switching_threshold = c(30, 30), species_names = c("prey", "predator"), return_type = "JSFResult" ) result summary(result) plot(result) }if (interactive() && jsf_available()) { rates_lv <- reticulate::py_eval( "lambda x, t: [2.0 * x[0], 1.5 * x[1], 0.05 * x[0] * x[1]]" ) result <- jsf_simulate( x0 = c(prey = 50, predator = 10), rates = rates_lv, reactant = matrix( c( 1, 0, 0, 1, 1, 1 ), ncol = 2, byrow = TRUE ), product = matrix( c( 2, 0, 0, 0, 0, 2 ), ncol = 2, byrow = TRUE ), do_disc = c(1, 1), t_max = 1, dt = 0.01, switching_threshold = c(30, 30), species_names = c("prey", "predator"), return_type = "JSFResult" ) result summary(result) plot(result) }
This function runs a simple SIR epidemic model using the Python jsf
package through reticulate.
jsf_sir( N = 1000, I0 = 10, beta = 0.5, gamma = 0.1, t_max = 60, dt = 0.1, switching_threshold_I = 10 )jsf_sir( N = 1000, I0 = 10, beta = 0.5, gamma = 0.1, t_max = 60, dt = 0.1, switching_threshold_I = 10 )
N |
Total population size. |
I0 |
Initial infectious population. |
beta |
Infection rate. |
gamma |
Recovery rate. |
t_max |
Final simulation time. |
dt |
Time step for the continuous/ODE part of JSF. |
switching_threshold_I |
Switching threshold for the infectious compartment. |
A data frame with columns time, S, I, and R.
if (interactive() && jsf_available()) { result <- jsf_sir( N = 1000, I0 = 10, beta = 0.5, gamma = 0.1, t_max = 1, dt = 0.1, switching_threshold_I = 10 ) head(result) }if (interactive() && jsf_available()) { result <- jsf_sir( N = 1000, I0 = 10, beta = 0.5, gamma = 0.1, t_max = 1, dt = 0.1, switching_threshold_I = 10 ) head(result) }
Create a JSFResult object
new_jsf_result( time, state, species_names = names(state), method = "operator-splitting", config = list() )new_jsf_result( time, state, species_names = names(state), method = "operator-splitting", config = list() )
time |
Numeric vector of simulation times. |
state |
Data frame of state trajectories. |
species_names |
Character vector of species names. Defaults to the
column names of |
method |
JSF simulation method used. |
config |
List of simulation configuration values. |
A JSFResult object.
state <- data.frame( prey = c(50, 51, 52), predator = c(10, 9, 9) ) result <- new_jsf_result( time = c(0, 0.1, 0.2), state = state, config = list(dt = 0.1) ) result summary(result)state <- data.frame( prey = c(50, 51, 52), predator = c(10, 9, 9) ) result <- new_jsf_result( time = c(0, 0.1, 0.2), state = state, config = list(dt = 0.1) ) result summary(result)