In this document, we report the time and memory usage of the examples shown in the main text. We use the bench::mark() function for this purpose. For single simulations, landscape constructions, and barrier calculations, we repeat the simulation 10 times, and for multiple simulations, we repeat the simulation 3 times.

The benchmarks are run on a university online workplace with the following specifications:

benchmarkme::get_cpu()
## $vendor_id
## [1] "GenuineIntel"
## 
## $model_name
## [1] "Intel(R) Xeon(R) Platinum 8358P CPU @ 2.60GHz"
## 
## $no_of_cores
## [1] 4
benchmarkme::get_ram()
## 68.7 GB
benchmarkme::get_platform_info()
## $OS.type
## [1] "windows"
## 
## $file.sep
## [1] "/"
## 
## $dynlib.ext
## [1] ".dll"
## 
## $GUI
## [1] "RTerm"
## 
## $endian
## [1] "little"
## 
## $pkgType
## [1] "win.binary"
## 
## $path.sep
## [1] ";"
## 
## $r_arch
## [1] "x64"

Example 1: Gene Expression

Single simulation

library(simlandr)

## simulation part
bench::mark(
  {
    b <- 1
    k <- 1
    S <- 0.5
    n <- 4
    lambda <- 0.01

    drift_gene <- c(
      rlang::expr(z * x^(!!n) / ((!!S)^(!!n) + x^(!!n)) + (!!b) * (!!S)^(!!n) / ((!!S)^(!!n) + y^(!!n)) - (!!k) * x),
      rlang::expr(z * y^(!!n) / ((!!S)^(!!n) + y^(!!n)) + (!!b) * (!!S)^(!!n) / ((!!S)^(!!n) + x^(!!n)) - (!!k) * y),
      rlang::expr(-(!!lambda) * z)
    ) |> as.expression()

    diffusion_gene <- expression(
      0.2,
      0.2,
      0.2
    )

    set.seed(1614)
    single_output_gene <- sim_SDE(drift = drift_gene, diffusion = diffusion_gene, N = 1e6, M = 10, Dt = 0.1, x0 = c(0, 0, 1), keep_full = FALSE)
  },
  iterations = 10
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 { b <- 1 k <- 1 S <- 0.5 n <- 4 lam~ 55.1s  56.4s    0.0175    1.72GB     4.00
## landscape construction part

if (!file.exists("data/single_output_gene.RDS")) {
  set.seed(1614)
  single_output_gene <- sim_SDE(drift = drift_gene, diffusion = diffusion_gene, N = 1e6, M = 10, Dt = 0.1, x0 = c(0, 0, 1), keep_full = FALSE)
  saveRDS(single_output_gene, "data/single_output_gene.RDS")
} else {
  single_output_gene <- readRDS("data/single_output_gene.RDS")
}

single_output_gene2 <- do.call(rbind, single_output_gene)
single_output_gene2 <- cbind(single_output_gene2[, "X"] - single_output_gene2[, "Y"], single_output_gene2[, "Z"])
colnames(single_output_gene2) <- c("delta_x", "a")

bench::mark(
  {
    l_single_gene_3d <-
      make_3d_single(single_output_gene2,
        x = "delta_x", y = "a",
        lims = c(-1.5, 1.5, 0, 1.5),
        Umax = 8
      )
  },
  iterations = 10
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 "{ l_single_gene_3d <- make_3d_sing~ 10.2s  10.5s    0.0953    6.76GB     1.12
## barrier calculation part

l_single_gene_3d <-
  make_3d_single(single_output_gene2,
    x = "delta_x", y = "a",
    lims = c(-1.5, 1.5, 0, 1.5),
    Umax = 8
  )

bench::mark(
  {
    b_single_gene_3d <- calculate_barrier(l_single_gene_3d,
      start_location_value = c(0, 1.2), end_location_value = c(1, 0.2),
      start_r = 0.3, end_r = 0.3
    )
  },
  iterations = 10
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 { b_single_gene_3d <- calculate_bar~ 4.91s  5.33s     0.190    3.75MB     2.09

Multiple simulations

# simulation part

bench::mark(
  {
    # Batch simulation for the gene expression model.

    # First, create the argument set for the batch simulation.
    # This specifies the parameters to be varied.

    batch_arg_set_gene <- new_arg_set()
    batch_arg_set_gene <- batch_arg_set_gene |>
      add_arg_ele(
        arg_name = "parameter", ele_name = "b",
        start = 0.5, end = 1.5, by = 0.5
      ) |>
      add_arg_ele(
        arg_name = "parameter", ele_name = "k",
        start = 0.5, end = 1.5, by = 0.5
      )
    batch_grid_gene <- make_arg_grid(batch_arg_set_gene)

    # Perform the batch simulation.
    # Use "bigmemory = TRUE" to save the memory.
    batch_output_gene <- batch_simulation(batch_grid_gene,
      sim_fun = function(parameter) {
        b <- parameter[["b"]]
        k <- parameter[["k"]]
        drift_gene <- c(
          rlang::expr(z * x^(!!n) / ((!!S)^(!!n) + x^(!!n)) + (!!b) * (!!S)^(!!n) / ((!!S)^(!!n) + y^(!!n)) - (!!k) * x),
          rlang::expr(z * y^(!!n) / ((!!S)^(!!n) + y^(!!n)) + (!!b) * (!!S)^(!!n) / ((!!S)^(!!n) + x^(!!n)) - (!!k) * y),
          rlang::expr(-(!!lambda) * z)
        ) |> as.expression()
        set.seed(1614)
        single_output_gene <- sim_SDE(drift = drift_gene, diffusion = diffusion_gene, N = 1e6, M = 10, Dt = 0.1, x0 = c(0, 0, 1), keep_full = FALSE)
        single_output_gene2 <- do.call(rbind, single_output_gene)
        single_output_gene2 <- cbind(single_output_gene2[, "X"] - single_output_gene2[, "Y"], single_output_gene2[, "Z"])
        colnames(single_output_gene2) <- c("delta_x", "a")
        single_output_gene2
      },
      bigmemory = TRUE
    )
  },
  iterations = 3
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 { batch_arg_set_gene <- new_arg_set~ 8.92m  8.94m   0.00186    25.2GB     2.16
## landscape construction part

if (file.exists("data/batch_output_gene.RDS")) {
  batch_output_gene <- readRDS("data/batch_output_gene.RDS") |> attach_all_matrices()
} else {
  batch_output_gene <- batch_simulation(batch_grid_gene,
    sim_fun = function(parameter) {
      b <- parameter[["b"]]
      k <- parameter[["k"]]
      drift_gene <- c(
        rlang::expr(z * x^(!!n) / ((!!S)^(!!n) + x^(!!n)) + (!!b) * (!!S)^(!!n) / ((!!S)^(!!n) + y^(!!n)) - (!!k) * x),
        rlang::expr(z * y^(!!n) / ((!!S)^(!!n) + y^(!!n)) + (!!b) * (!!S)^(!!n) / ((!!S)^(!!n) + x^(!!n)) - (!!k) * y),
        rlang::expr(-(!!lambda) * z)
      ) |> as.expression()
      set.seed(1614)
      single_output_gene <- sim_SDE(drift = drift_gene, diffusion = diffusion_gene, N = 1e6, M = 10, Dt = 0.1, x0 = c(0, 0, 1), keep_full = FALSE)
      single_output_gene2 <- do.call(rbind, single_output_gene)
      single_output_gene2 <- cbind(single_output_gene2[, "X"] - single_output_gene2[, "Y"], single_output_gene2[, "Z"])
      colnames(single_output_gene2) <- c("delta_x", "a")
      single_output_gene2
    },
    bigmemory = TRUE
  )
  saveRDS(batch_output_gene, "data/batch_output_gene.RDS")
}

bench::mark(
  {
    # Make the 3D matrix for the batch output.
    l_batch_gene_3d <- make_3d_matrix(batch_output_gene,
      x = "delta_x", y = "a", cols = "b", rows = "k",
      lims = c(-5, 5, -0.5, 2), h = 0.005,
      Umax = 8,
      kde_fun = "ks", individual_landscape = TRUE
    )
  },
  iterations = 10
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 "{ l_batch_gene_3d <- make_3d_matri~ 1.12m  1.21m    0.0139    56.8GB     1.41
## barrier calculation part

# Make the 3D matrix for the batch output.
l_batch_gene_3d <- make_3d_matrix(batch_output_gene,
  x = "delta_x", y = "a", cols = "b", rows = "k",
  lims = c(-5, 5, -0.5, 2), h = 0.005,
  Umax = 8,
  kde_fun = "ks", individual_landscape = TRUE
)

bench::mark(
  {
    bg_gene <- make_barrier_grid_3d(batch_grid_gene, df = structure(list(start_location_value = list(c(0, 1.5), c(0, 1.5), c(0, 1.5), c(0, 1.5), c(0, 1.5), c(0, 1.5), c(0, 1.5), c(0, 1.5), c(0, 1.5)), start_r = list(c(0.2, 1), c(0.2, 1), c(0.2, 1), c(0.2, 0.5), c(0.2, 0.5), c(0.2, 0.5), c(0.2, 0.3), c(0.2, 0.3), c(0.2, 0.3)), end_location_value = list(
      c(2, 0), c(2, 0), c(2, 0), c(1, 0), c(1, 0), c(1, 0), c(1, 0), c(1, 0), c(1, 0)
    ), end_r = list(
      c(1, 1), c(1, 1), c(1, 1), c(1, 1), c(1, 1), c(1, 1), c(1, 1), c(1, 1), c(1, 1)
    )), row.names = c(NA, -9L), class = c(
      "arg_grid",
      "data.frame"
    )))

    b_batch_gene_3d <- calculate_barrier(l_batch_gene_3d,
      bg = bg_gene
    )
  },
  iterations = 10
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 { bg_gene <- make_barrier_grid_3d(b~ 30.4s  32.3s    0.0313    23.6MB    0.996

Example 2: Panic Model

Single simulation

## simulation part
library(PanicModel)

# Create a function that performs a simulation using the `simPanic` function from `PanicModel`.
# Some default options are modified for the illustration.

sim_fun_panic <- function(x0, par) {
  # Change several default parameters
  pars <- pars_default
  # Increase the noise strength to improve sampling efficiency
  pars$N$lambda_N <- 200
  # Make S constant through the simulation
  pars$TS$r_S_a <- 0
  pars$TS$r_S_e <- 0

  # Specify the initial values of A and PT according to the format requirement by `multi_init_simulation()`, while the other variables use the default initial values.
  initial <- initial_default
  initial$A <- x0[1]
  initial$PT <- x0[2]

  # Specify the value of S according to the format requirement by `batch_simulation()`.
  initial$S <- par$S

  # Extract the simulation output from the result by simPanic(). Only keep the core variables.
  return(
    as.matrix(
      simPanic(1:5000, initial = initial, parameters = pars, pbar = FALSE)$outmat[, c("A", "PT", "E")]
    )
  )
}


bench::mark(
  {
    future::plan("multisession")
    set.seed(1614, kind = "L'Ecuyer-CMRG")
    single_output_panic <- multi_init_simulation(
      sim_fun = sim_fun_panic,
      range_x0 = c(0, 1, 0, 1),
      R = 4,
      par = list(S = 0.5)
    )
  },
  iterations = 10
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 "{ future::plan(\"multisession\") s~  7.8m  8.19m   0.00204    17.8MB  0.00916
## landscape construction part

if (!file.exists("data/single_output_panic.RDS")) {
  future::plan("multisession")
  set.seed(1614, kind = "L'Ecuyer-CMRG")
  single_output_panic <- multi_init_simulation(
    sim_fun = sim_fun_panic,
    range_x0 = c(0, 1, 0, 1),
    R = 4,
    par = list(S = 0.5)
  )
  saveRDS(single_output_panic, "data/single_output_panic.RDS")
} else {
  single_output_panic <- readRDS("data/single_output_panic.RDS")
}

bench::mark(
  {
    l_single_panic_3d <- make_3d_single(
      single_output_panic |> window(start = 100),
      x = "A", y = "PT", h = 0.005, lims = c(-1, 1.5, -0.5, 1.5)
    )
  },
  iterations = 10
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 { l_single_panic_3d <- make_3d_sing~ 175ms  208ms      3.52     144MB     7.40

Multiple Simulations

## simulation part
bench::mark(
  {
    batch_arg_grid_panic <- new_arg_set() |>
      add_arg_ele(arg_name = "par", ele_name = "S", start = 0, end = 1, by = 0.5) |>
      make_arg_grid()

    future::plan("multisession")
    set.seed(1614, kind = "L'Ecuyer-CMRG")
    batch_output_panic <- batch_simulation(
      batch_arg_grid_panic,
      sim_fun = function(par) {
        multi_init_simulation(
          sim_fun_panic,
          range_x0 = c(0, 1, 0, 1),
          R = 4,
          par = par
        ) |> window(start = 100)
      }
    )
  },
  iterations = 3
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 { batch_arg_grid_panic <- make_arg_~ 22.7m  22.9m  0.000721    49.8MB  0.00360
## landscape construction part

if (file.exists("data/batch_output_panic.RDS")) {
  batch_output_panic <- readRDS("data/batch_output_panic.RDS")
} else {
  future::plan("multisession")
  set.seed(1614, kind = "L'Ecuyer-CMRG")
  batch_output_panic <- batch_simulation(
    batch_arg_grid_panic,
    sim_fun = function(par) {
      multi_init_simulation(
        sim_fun_panic,
        range_x0 = c(0, 1, 0, 1),
        R = 4,
        par = par
      ) |> window(start = 100)
    }
  )
  saveRDS(batch_output_panic, "data/batch_output_panic.RDS")
}

bench::mark(
  {
    l_batch_panic_3d_1 <- make_3d_matrix(batch_output_panic, x = "A", y = "PT", cols = "S", h = 0.005, lims = c(-1, 1.5, -0.5, 1.5))
  },
  iterations = 10
)
## # A tibble: 1 x 6
##   expression                             min median `itr/sec` mem_alloc `gc/sec`
##   <bch:expr>                           <bch> <bch:>     <dbl> <bch:byt>    <dbl>
## 1 "{ l_batch_panic_3d_1 <- make_3d_ma~ 1.31s  1.56s     0.642     299MB     4.36