---
title: "C++ API"
author: "Ralf Stubner"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{C++ API}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

The RNGs and distributions functions can also be used from C++ at various levels of abstraction.
Technically there are three ways to make use of dqrng at the C++ level:

* use `// [[Rcpp::depends(dqrng)]]` together with `Rcpp::sourceCpp()`
* use `Rcpp::cppFunction(depends = "dqrng", ...)`
* use an R package with `LinkingTo: dqrng`

The following functions are also available if you include `dqrng.h`. Note that the scalar function `dqrng::runif`, `dqrng::rnorm`, and `dqrng::rexp` have been deprecated and will be removed in a future release. Please use the more flexible and faster `dqrng::random_64bit_accessor` together with `variate<Dist>()` instead.

## Setting seed and RNG type

```cpp
void dqrng::dqset_seed(Rcpp::IntegerVector seed, 
                       Rcpp::Nullable<Rcpp::IntegerVector> stream = R_NilValue)
void dqrng::dqRNGkind(std::string kind, const std::string& normal_kind = "ignored")
```

`seed`
:    seed for the RNG; length 1 or 2

`stream`
:    RNG stream to use; length 1 or 2

`kind`
:    string specifying the RNG, One of "pcg64", "Xoroshiro128+", "Xoroshiro128++", "Xoshiro256+", "Xoshiro256++" or "Threefry"

`normal-kind`
:    ignored; included for compatibility with `RNGkind`

## Random variates with uniform distribution

```cpp
Rcpp::NumericVector dqrng::dqrunif(size_t n, double min = 0.0, double max = 1.0)
DEPRECATED double dqrng::runif(double min = 0.0, double max = 1.0)
```
`n`	
:   number of observations

`min`
:   lower limit of the uniform distribution

`max`
:   upper limit of the uniform distribution

## Random variates with normal distribution

```cpp
Rcpp::NumericVector dqrng::dqrnorm(size_t n, double mean = 0.0, double sd = 1.0)
DEPRECATED double dqrng::rnorm(double mean = 0.0, double sd = 1.0)
```

`n`	
:   number of observations

`mean`
:   mean value of the normal distribution

`sd`
:   standard deviation of the normal distribution

## Random variates with exponential distribution

```cpp
Rcpp::NumericVector dqrng::dqrexp(size_t n, double rate = 1.0)
DEPRECATED double dqrng::rexp(double rate = 1.0)
```

`n`	
:   number of observations

`rate`
:   rate of the exponential distribution

## Random variates with Rademacher distribution

```cpp
Rcpp::IntegerVector dqrng::dqrrademacher(size_t n)
```

`n`	
:   number of observations

## Random sampling

```cpp
Rcpp::IntegerVector dqrng::dqsample_int(int n, int size, bool replace = false,
                                        Rcpp::Nullable<Rcpp::NumericVector> probs = R_NilValue,
                                        int offset = 0)
Rcpp::NumericVector dqrng::dqsample_num(double n, double size, bool replace = false,
                                        Rcpp::Nullable<Rcpp::NumericVector> probs = R_NilValue,
                                        int offset = 0)
```

`n`
:    a positive number, the number of items to choose from

`size`
:    a non-negative number giving the number of items to choose

`replace`
:    should sampling be with replacement?

`prob`
:    a vector of probability weights for obtaining the elements of the vector being sampled (currently ignored)

`offset`
:    sample from range `[offset, offset + m)`

The two functions are used for "normal" and "long-vector" support in R.

## Getting and setting the RNG state

```cpp
std::vector<std::string> dqrng::dqrng_get_state()
void dqrng::dqrng_set_state(std::vector<std::string> state)
```

`state`
:    a `std::vector<std::string>` as produced by `dqrng_get_state()`

## Accessing the global RNG

```cpp
Rcpp::XPtr<dqrng::random_64bit_generator> dqrng::get_rng()
```

Direct usage of this method is **discouraged**. The preferred way of accessing the global RNG is to instantiate `dqrng::random_64bit_accessor` within your function. Note that you MUST NOT delete the global RNG. Using `dqrng::random_64bit_accessor` makes this impossible. In addition, you SHOULD NOT store a reference to the RNG permanently, because it can be invalidated by calls to `dqRNGkind`. Therefore, instances of `dqrng::random_64bit_accessor` SHOULD be stored as (non-static) variables in functions.

Note that `dqrng::random_64bit_accessor` supports [UniformRandomBitGenerator](https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator) and can therefore be used together with any C++11 distribution function. In addition, the following functions are supported, since they are inherited from the abstract parent class `random_64bit_generator`: 

```cpp
// clone RNG and select a different stream
std::unique_ptr<random_64bit_generator> clone(uint64_t stream)
// uniform doubles in [0,1) and double-int-pairs
double uniform01()
std::pair<double, int> generate_double_8bit_pair()
// uniform integers in a range 
uint32_t operator() (uint32_t range)
uint64_t operator() (uint64_t range)
ResultType variate<ResultType, DistTmpl>(param1, ... paramN)
generate<DistTmpl>(container, param1, ... paramN)
generate<DistTmpl>(start, end, param1, ... paramN)
Dist::result_type variate<Dist>(param1, ... paramN)
generate<Dist>(container, param1, ... paramN)
generate<Dist>(start, end, param1, ... paramN)
```

`stream`
:    RNG stream to use for the cloned RNG

`range`
:    Integers are generated in closed interval `[0, range]`

`ResultType`
:    Expected result from the distribution template `DistTmpl`

`DistTmpl`
:    Distribution template like `std::uniform_distribution`. `DistTmpl<ResultType>` defines the full distribution.

`Dist`
:    Full distribution like `std::uniform_distribution<double>` or `dqrng::normal_distriubtion`.

`param1, ... paramN`
:    Necessary parameters to initialize the distribution.

`container`
:    A container that is to be filled with variates from the distribution function. Needs to support `std::begin` and `std::end`.

`start, end`
:   Forward iterators pointing to start and end of a range to be filled with variates from the distribution function.
