-
Notifications
You must be signed in to change notification settings - Fork 5
/
README.Rmd
211 lines (178 loc) · 7.71 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
---
output: github_document
################################################################################
# NOTE:
# Make sure you have added an executable pre-commit hook in your local checkout
# .git/hooks/pre-commit
# to prevent accidental commits of README.Rmd not re-knitted to README.md.
# You can copy the hook from inst/tools using R via
# usethis::use_git_hook("pre-commit", readLines("inst/tools/pre-commit", encoding="UTF-8"))
################################################################################
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%",
R.options = list(digits = 6, width = 60) # fit 5 elements per row
)
```
```{r, check-vignette, include = FALSE}
# make sure a vignette with a given name exists, you may have to run
# remotes::install_local(build_vignettes = TRUE) in case of errors
stop_if_no_vignette <- function(topic, package = "rTRNG") {
invisible( # prevents opening the vignette
withCallingHandlers(
vignette(topic, package),
warning = function(w) stop(w$message)
)
)
}
```
<img src="man/figures/rTRNG.svg" align="right" width="15%" height="15%"/>
# rTRNG: R package providing access and examples to TRNG C++ library
<!-- badges: start -->
[![CRAN status](http://www.r-pkg.org/badges/version/rTRNG)](https://cran.r-project.org/package=rTRNG)
[![R-CMD-check](https://github.com/miraisolutions/rTRNG/actions/workflows/ci.yaml/badge.svg)](https://github.com/miraisolutions/rTRNG/actions/workflows/ci.yaml) [![valgrind](https://github.com/miraisolutions/rTRNG/actions/workflows/valgrind.yaml/badge.svg)](https://github.com/miraisolutions/rTRNG/actions/workflows/valgrind.yaml)
[![Codecov coverage](https://codecov.io/gh/miraisolutions/rTRNG/branch/master/graph/badge.svg)](https://app.codecov.io/gh/miraisolutions/rTRNG/branch/master)
<!-- badges: end -->
**[TRNG](https://www.numbercrunch.de/trng/)** (Tina's Random Number Generator) is a
state-of-the-art C++ pseudo-random number generator library for sequential and
parallel Monte Carlo simulations. It provides a variety of random number engines
(pseudo-random number generators) and distributions. In particular, *parallel*
random number engines provided by TRNG can be manipulated by `jump` and `split`
operations. These allow to `jump` ahead by an arbitrary number of steps and to
`split` a sequence into any desired sub-sequence(s), thus enabling techniques
such as *block-splitting* and *leapfrogging* suitable to parallel algorithms.
Package **rTRNG** provides the R user with access to the functionality of the
underlying TRNG C++ library, both in R directly or more typically as part of
other projects combining R with C++.
An
[introduction to **rTRNG**](https://user2017.sched.com/event/Axpj/rtrng-advanced-parallel-random-number-generation-in-r)
[[pdf](http://schd.ws/hosted_files/user2017/93/Mirai.rTRNG.useR2017.pdf)]
was given at the useR!2017 conference, and is also available as package
vignette:
```{r check-vignettes, echo=FALSE}
stop_if_no_vignette("rTRNG.useR2017")
stop_if_no_vignette("mcMat")
```
```{r useR2017, eval = FALSE}
vignette("rTRNG.useR2017", "rTRNG")
```
The *sub-matrix simulation* vignette shows **rTRNG** in action for a flexible
*and* consistent (parallel) simulation of a matrix of Monte Carlo variates:
```{r mcMat, eval = FALSE}
vignette("mcMat", "rTRNG")
```
A full applied example of using **rTRNG** for the simulation of credit defaults
was presented at the
[R/Finance 2017](http://past.rinfinance.com/agenda/2017/talk/RiccardoPorreca.pdf)
conference. The underlying code and data are hosted on [GitHub](https://github.com/miraisolutions/PortfolioRiskMC),
as is the corresponding
[R Markdown output](https://rawgit.com/miraisolutions/PortfolioRiskMC/master/RinFinance2017/PortfolioSimAndRiskBig.html).
For more information and references, you can consult the package documentation
page via `help("rTRNG-package")`.
## Installation
You can install the package from CRAN:
```{r cran-install, eval = FALSE}
install.packages("rTRNG")
```
The development version of **rTRNG** can be installed from our
[GitHub repository](https://github.com/miraisolutions/rTRNG) with:
```{r gh-install, eval = FALSE}
# install.packages("remotes")
remotes::install_github("miraisolutions/rTRNG")
# in order to also build the vignettes, you'll have to run below instead
remotes::install_github("miraisolutions/rTRNG", build_vignettes = TRUE)
```
----
*Build note*
If you try to build the package yourself from source and run
`Rcpp::compileAttributes()` during the process, you need to use a version of
**Rcpp >= 0.12.11.2**. Earlier versions like 0.12.11 will not generate the
desired `_rcpp_module_boot_trng` symbol in *RcppExports.cpp*.
## Examples
### Use TRNG engines from R
Similar to base-R (`?Random`), **rTRNG** allows to select and manipulate a
*current* TRNG engine of a given *kind* (e.g. yarn2), and to draw from it using
any of the provided `r<dist>_trng` functions:
```{r ex-TRNG.Random}
library(rTRNG)
TRNGkind("yarn2")
TRNGseed(12358)
runif_trng(15)
```
The special `jump` and `split` operations can be applied to the current
engine in a similar way:
```{r ex-jump.split}
TRNGseed(12358)
TRNGjump(6) # advance by 6 the internal state
TRNGsplit(5, 3) # subsequence: one element every 5 starting from the 3rd
runif_trng(2)
# => compare to the full sequence above
```
TRNG engines can also be created and manipulated directly as *Reference Class*
objects, and passed as `engine` argument to `r<dist>_trng`:
```{r ex-TRNG.Engine}
rng <- yarn2$new()
rng$seed(12358)
rng$jump(6)
rng$split(5, 3)
runif_trng(2, engine = rng)
```
In addition, parallel generation of random variates can be enabled in
`r<dist>_trng` via `RcppParallel` using argument `parallelGrain > 0`:
```{r ex-parallelGrain}
TRNGseed(12358)
RcppParallel::setThreadOptions(numThreads = 2)
x_parallel <- rnorm_trng(1e5L, parallelGrain = 100L)
TRNGseed(12358)
x_serial <- rnorm_trng(1e5L)
identical(x_serial, x_parallel)
```
### Use TRNG from standalone C++
The TRNG C++ library is made available by **rTRNG** to standalone C++ code
compiled with `Rcpp::sourceCpp` thanks to the `Rcpp::depends` attribute, with
`Rcpp::plugins(cpp11)` enforcing the C++11 standard required by TRNG >= 4.22:
```{Rcpp ex-Rcpp}
// [[Rcpp::depends(rTRNG)]]
// TRNG >= 4.22 requires C++11
// [[Rcpp::plugins(cpp11)]]
#include <Rcpp.h>
#include <trng/yarn2.hpp>
#include <trng/uniform_dist.hpp>
// [[Rcpp::export]]
Rcpp::NumericVector exampleCpp() {
trng::yarn2 rng(12358);
rng.jump(6);
rng.split(5, 2); // 0-based index
Rcpp::NumericVector x(2);
trng::uniform_dist<>unif(0, 1);
for (unsigned int i = 0; i < 2; i++) {
x[i] = unif(rng);
}
return x;
}
```
```{r ex-Rcpp-R}
exampleCpp()
```
### Use TRNG from other R packages
Creating an R package with C++ code using the TRNG library and headers through
**rTRNG** is achieved by
- adding `Imports: rTRNG` and `LinkingTo: rTRNG` to the DESCRIPTION file
- importing one symbol in the NAMESPACE: `importFrom(rTRNG, TRNG.Version)`
- enforcing compilation using C++11 in Makevars[.win] via `CXX_STD = CXX11`
- setting the relevant linker flags in Makevars[.win] via `rTRNG::LdFlags()`
- Makevars: `PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "rTRNG::LdFlags()")`
- Makevars.win: `PKG_LIBS += $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" -e "rTRNG::LdFlags()")`
### Note about C++ code on macOS
C++ code using the TRNG library (sourced via `Rcpp::sourceCpp` or part of an R
package) might fail on certain systems due to issues with building and linking
against **rTRNG**. This is typically the case for **macOS**, and can generally
be checked by running
```{r check-linking, eval=FALSE}
rTRNG::check_rTRNG_linking()
```