---
title: "Flexible and consistent simulation of a matrix of Monte Carlo variates"
author: "Riccardo Porreca, Roland Schmid"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Matrix MC simulation}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---


```{r setup, include=FALSE}
knitr::opts_chunk$set(collapse = TRUE)
options(digits = 5) # for kable
linking_ok <- rTRNG::check_rTRNG_linking()
```


```{r code, include=FALSE, cache=FALSE}
source("utils/read_chunk_wrap.R", echo = FALSE, print.eval = FALSE)
read_chunk_wrap("code/mcMat.R")
read_chunk_wrap("code/mcMat.cpp")
read_chunk_wrap("code/mcMatParallel.cpp")
if (linking_ok) {
  Rcpp::sourceCpp("code/mcMat.cpp", verbose = FALSE, embeddedR = FALSE)
  Rcpp::sourceCpp("code/mcMatParallel.cpp", verbose = FALSE, embeddedR = FALSE)
}
```

Consider the Monte Carlo simulation of a matrix of i.i.d. normal random
variables. We will show how **rTRNG** can be used to perform a consistent
(*fair-playing*) simulation of a subset of the variables and simulations.

![](figures/mcMat.png){ width=85% }

## Consistent simulation in R

We rely on the TRNG engines exposed to R as reference classes by **rTRNG**.
```{r}
library(rTRNG)
```
The `mcMatR` function below performs the full sequential Monte Carlo simulation of `nrow`
normal i.i.d. samples of `ncol` variables using the `yarn2` generator.
```{r mcMatR}
```
A second function `mcSubMatR` relies on `jump` and `split` operations to perform
only a chunk [`startRow`, `endRow`] of simulations for a subset `subCols` of the
variables.
```{r mcSubMatR}
```
The parallel nature of the `yarn2` generator ensures the sub-simulation obtained
via `mcSubMatR` is consistent with the full sequential simulation.
```{r subMatExampleR}
```
```{r, echo=FALSE}
knitr::kable(cbind.data.frame(M = M, S = S), row.names = TRUE)
```


## Consistent simulation with Rcpp

We now use **Rcpp** to define functions `mcMatRcpp` and `mcSubMatRcpp` for the
full sequential simulation and the sub-simulation, respectively. The
`Rcpp::depends` attribute makes sure the TRNG library and headers shipped with
**rTRNG** are available to the C++ code. Moreover, `Rcpp::plugins(cpp11)`
enforces the C++11 standard required by TRNG >= 4.22.

```{Rcpp depends-h-ns, eval=FALSE}
```
```{Rcpp mcMatRcpp, eval=FALSE}
```
```{Rcpp mcSubMatRcpp, eval=FALSE}
```
As seen above for the R case, consistency of the simulation obtained via
`mcSubMatRcpp` with the full sequential simulation is guaranteed.
```{r subMatExampleRcpp, eval=linking_ok}
```
```{r, echo=FALSE, eval=linking_ok}
knitr::kable(cbind.data.frame(M = M, S = S), row.names = TRUE)
```


## Consistent parallel simulation with RcppParallel

The same technique used for generating a sub-set of the simulations can be
exploited for performing a parallel simulation in C++. We can embed the body of
`mcSubMatRcpp` above into an `RcppParallel::Worker` for performing chunks of
Monte Carlo simulations in parallel, for any subset `subCols` of the variables.
```{Rcpp mcMatRcppParallel, eval=FALSE}
```
The parallel nature of the `yarn2` generator ensures the parallel simulation is
playing fair, i.e. is consistent with the sequential simulation.
```{r fullMatExampleRcppParallel, eval=linking_ok}
```
Similarly, we can achieve a consistent parallel simulation of a subset of the
variables only.
```{r subMatExampleRcppParallel, eval=linking_ok}
```
```{r, echo=FALSE, eval=linking_ok}
knitr::kable(cbind.data.frame(M = M, Sp = Sp), row.names = TRUE)
```
