diff --git a/404.html b/404.html index 4cb8071..543b257 100644 --- a/404.html +++ b/404.html @@ -18,7 +18,7 @@ - +
@@ -47,7 +47,7 @@
- +
@@ -109,16 +109,16 @@

Page not found (404)

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/articles/cpp-api.html b/articles/cpp-api.html index 628abbb..556e369 100644 --- a/articles/cpp-api.html +++ b/articles/cpp-api.html @@ -12,14 +12,13 @@ - - +
@@ -48,7 +47,7 @@
- +
@@ -91,9 +90,9 @@

C++ API

Ralf Stubner

-

2024-05-28

+

2024-09-06

- Source: vignettes/cpp-api.Rmd + Source: vignettes/cpp-api.Rmd
@@ -337,9 +336,7 @@

Accessing the global RNG - -

+
@@ -352,16 +349,16 @@

Accessing the global RNG

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/articles/dqrng.html b/articles/dqrng.html index bc132e7..f1a144a 100644 --- a/articles/dqrng.html +++ b/articles/dqrng.html @@ -12,14 +12,13 @@ - - +
@@ -48,7 +47,7 @@
- +
@@ -91,9 +90,9 @@

Fast Pseudo Random Number Generators for R

Ralf Stubner

-

2024-05-28

+

2024-09-06

- Source: vignettes/dqrng.Rmd + Source: vignettes/dqrng.Rmd
@@ -149,12 +148,14 @@

Usage from R\(\pi\) via simulation. The basic idea is to -generate a large number of random points within the unit square. An -approximation for \(\pi\) can then be -calculated from the ratio of points within the unit circle to the total -number of points. A vectorized implementation in R where we can switch -the RNG might look like this:

+

Let’s look at the classical example of calculating +π\pi +via simulation. The basic idea is to generate a large number of random +points within the unit square. An approximation for +π\pi +can then be calculated from the ratio of points within the unit circle +to the total number of points. A vectorized implementation in R where we +can switch the RNG might look like this:

 N <- 1e7
 piR <- function(n, rng = stats::runif) {
@@ -166,7 +167,7 @@ 

Usage from Rsystem.time(cat("pi ~= ", piR(N), "\n")) #> pi ~= 3.140899 #> user system elapsed -#> 0.419 0.024 0.443

+#> 0.368 0.041 0.409

Using dqrng is about three times faster:

 library(dqrng)
@@ -174,85 +175,71 @@ 

Usage from Rsystem.time(cat("pi ~= ", piR(N, rng = dqrng::dqrunif), "\n")) #> pi ~= 3.141457 #> user system elapsed -#> 0.205 0.016 0.221

+#> 0.183 0.020 0.204

Since the calculations add a constant off-set, the speed-up for the RNGs alone has to be even greater:

 system.time(stats::runif(N))
 #>    user  system elapsed 
-#>   0.082   0.007   0.089
-
-system.time(dqrng::dqrunif(N))
+#>   0.084   0.004   0.088
+system.time(dqrng::dqrunif(N))
 #>    user  system elapsed 
-#>   0.021   0.011   0.032
+#> 0.021 0.008 0.028

Similar for the exponential distribution:

-
+
 system.time(stats::rexp(N))
 #>    user  system elapsed 
-#>   0.326   0.016   0.342
-
-system.time(dqrng::dqrexp(N))
+#>   0.328   0.008   0.335
+system.time(dqrng::dqrexp(N))
 #>    user  system elapsed 
-#>   0.036   0.011   0.048
+#> 0.046 0.000 0.047

And for the normal distribution:

-
+
 system.time(stats::rnorm(N))
 #>    user  system elapsed 
-#>   0.366   0.001   0.367
-
-system.time(dqrng::dqrnorm(N))
+#>   0.357   0.008   0.365
+system.time(dqrng::dqrnorm(N))
 #>    user  system elapsed 
 #>   0.067   0.004   0.071

As well as for sampling with and without replacement:

-
+
 system.time(for (i in 1:100)   sample.int(N, N/100, replace = TRUE))
 #>    user  system elapsed 
-#>   0.583   0.003   0.586
-
-system.time(for (i in 1:100) dqsample.int(N, N/100, replace = TRUE))
+#>   0.577   0.008   0.585
+system.time(for (i in 1:100) dqsample.int(N, N/100, replace = TRUE))
 #>    user  system elapsed 
-#>   0.021   0.016   0.037
-
-system.time(for (i in 1:100)   sample.int(N, N/100))
+#>   0.029   0.009   0.037
+system.time(for (i in 1:100)   sample.int(N, N/100))
 #>    user  system elapsed 
-#>   1.929   0.368   2.297
-
-system.time(for (i in 1:100) dqsample.int(N, N/100))
+#>   1.820   0.319   2.140
+system.time(for (i in 1:100) dqsample.int(N, N/100))
 #>    user  system elapsed 
-#>   0.061   0.000   0.062
+#> 0.058 0.008 0.065

It is also possible to register the supplied generators as user-supplied RNGs. This way set.seed() and dqset.seed() influence both (dq)runif and (dq)rnorm in the same way. This is also true for other r<dist> functions, but note that rexp and dqrexp still give different results:

-
+
 register_methods()
 set.seed(4711);   stats::runif(5)
-#> [1] 0.3143534 0.7835753 0.1443660 0.1109871 0.6433407
-
-set.seed(4711);   dqrng::dqrunif(5)
-#> [1] 0.3143534 0.7835753 0.1443660 0.1109871 0.6433407
-
-dqset.seed(4711); stats::rnorm(5)
-#> [1] -0.3618122  0.8199887 -0.4075635  0.2073972 -0.8038326
-
-dqset.seed(4711); dqrng::dqrnorm(5)
-#> [1] -0.3618122  0.8199887 -0.4075635  0.2073972 -0.8038326
-
-set.seed(4711);   stats::rt(5, 10)
-#> [1] -0.3196113 -0.4095873 -1.2928241  0.2399470 -0.1068945
-
-dqset.seed(4711); stats::rt(5, 10)
-#> [1] -0.3196113 -0.4095873 -1.2928241  0.2399470 -0.1068945
-
-set.seed(4711);   stats::rexp(5, 10)
-#> [1] 0.0950560698 0.0567150561 0.1541222748 0.2512966671 0.0002175758
-
-set.seed(4711);   dqrng::dqrexp(5, 10)
-#> [1] 0.03254731 0.06855303 0.06977124 0.02579004 0.07629535
- +#> [1] 0.3143534 0.7835753 0.1443660 0.1109871 0.6433407 +set.seed(4711); dqrng::dqrunif(5) +#> [1] 0.3143534 0.7835753 0.1443660 0.1109871 0.6433407 +dqset.seed(4711); stats::rnorm(5) +#> [1] -0.3618122 0.8199887 -0.4075635 0.2073972 -0.8038326 +dqset.seed(4711); dqrng::dqrnorm(5) +#> [1] -0.3618122 0.8199887 -0.4075635 0.2073972 -0.8038326 +set.seed(4711); stats::rt(5, 10) +#> [1] -0.3196113 -0.4095873 -1.2928241 0.2399470 -0.1068945 +dqset.seed(4711); stats::rt(5, 10) +#> [1] -0.3196113 -0.4095873 -1.2928241 0.2399470 -0.1068945 +set.seed(4711); stats::rexp(5, 10) +#> [1] 0.0950560698 0.0567150561 0.1541222748 0.2512966671 0.0002175758 +set.seed(4711); dqrng::dqrexp(5, 10) +#> [1] 0.03254731 0.06855303 0.06977124 0.02579004 0.07629535 +restore_methods()

You can automatically register these methods when loading this package by setting the option dqrng.register_methods to TRUE, e.g. with @@ -261,14 +248,12 @@

Usage from Rdqrng_get_state() and dqrng_set_state() can be used for this task:

-
+
 (state <- dqrng_get_state())
-#> [1] "default"             "7442421893577288217" "2933090096537006399"
-
-dqrunif(5)
-#> [1] 0.850198175 0.184318214 0.003138956 0.071103977 0.430195275
-
-# many other operations, that could even change the used RNG type
+#> [1] "default"             "7442421893577288217" "2933090096537006399"
+dqrunif(5)
+#> [1] 0.850198175 0.184318214 0.003138956 0.071103977 0.430195275
+# many other operations, that could even change the used RNG type
 dqrng_set_state(state)
 dqrunif(5)
 #> [1] 0.850198175 0.184318214 0.003138956 0.071103977 0.430195275
@@ -300,48 +285,49 @@

Using the compiled library functio functions. These functions are also available at the C++ level if you include dqrng.h. The full list of functions is available with vignette("cpp-api", package = "dqrng"). Revisiting the -example of approximating \(\pi\) we can -use:

-
// [[Rcpp::depends(dqrng)]]
-#include <Rcpp.h>
-#include <dqrng.h>
-
-using Rcpp::IntegerVector;
-using Rcpp::NumericVector;
-using Rcpp::sqrt;
-using Rcpp::sum;
-using dqrng::dqrunif;
-
-// [[Rcpp::export]]
-double piCpp(const int n) {
-  dqrng::dqset_seed(IntegerVector::create(42));
-  NumericVector x = dqrunif(n);
-  NumericVector y = dqrunif(n);
-  NumericVector d = sqrt(x*x + y*y);
-  return 4.0 * sum(d < 1.0) / n;
-}
-/*** R
-system.time(cat("pi ~= ", piCpp(1e7), "\n"))
-*/
+example of approximating +π\pi +we can use:

+
// [[Rcpp::depends(dqrng)]]
+#include <Rcpp.h>
+#include <dqrng.h>
+
+using Rcpp::IntegerVector;
+using Rcpp::NumericVector;
+using Rcpp::sqrt;
+using Rcpp::sum;
+using dqrng::dqrunif;
+
+// [[Rcpp::export]]
+double piCpp(const int n) {
+  dqrng::dqset_seed(IntegerVector::create(42));
+  NumericVector x = dqrunif(n);
+  NumericVector y = dqrunif(n);
+  NumericVector d = sqrt(x*x + y*y);
+  return 4.0 * sum(d < 1.0) / n;
+}
+/*** R
+system.time(cat("pi ~= ", piCpp(1e7), "\n"))
+*/

Note that in C++ you have to use dqrng::dqset_seed(), whereas the analogue function in the R interface is called dqrng::dqset.seed(). For sampling with and without replacement dqrng::dqsample_int() and dqrng::dqsample_num() are the analogue of dqrng::dqsample.int() in the R interface:

-
// [[Rcpp::depends(dqrng)]]
-#include <Rcpp.h>
-#include <dqrng.h>
-
-// [[Rcpp::export]]
-void sampleCpp(const int n) {
-  dqrng::dqset_seed(Rcpp::IntegerVector::create(42));
-  Rcpp::IntegerVector sample = dqrng::dqsample_int(n, n/100, true);
-  Rcpp::Rcout << sample << std::endl;
-}
-/*** R
-sampleCpp(1000)
-*/
+
// [[Rcpp::depends(dqrng)]]
+#include <Rcpp.h>
+#include <dqrng.h>
+
+// [[Rcpp::export]]
+void sampleCpp(const int n) {
+  dqrng::dqset_seed(Rcpp::IntegerVector::create(42));
+  Rcpp::IntegerVector sample = dqrng::dqsample_int(n, n/100, true);
+  Rcpp::Rcout << sample << std::endl;
+}
+/*** R
+sampleCpp(1000)
+*/

Using the header only library @@ -354,68 +340,68 @@

Using the header only librarySplitMix generator is used together with dqrng::normal_distribution:

-
#include <Rcpp.h>
-// [[Rcpp::depends(dqrng, BH)]]
-#include <dqrng_distribution.h>
-
-class SplitMix {
-public:
-  typedef uint64_t result_type;
-  SplitMix (result_type seed) : state(seed) {};
-  result_type operator() () {
-    result_type z = (state += 0x9e3779b97f4a7c15ULL);
-    z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
-    z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
-    return z ^ (z >> 31);
-  }
-  void seed(result_type seed) {state = seed;}
-  static constexpr result_type min() {return 0;};
-  static constexpr result_type max() {return UINT64_MAX;};
-
-private:
-  result_type state;
-
-public:  
-  friend std::ostream& operator<<(std::ostream& ost, const SplitMix& e) {
-    return ost << e.state;
-  }
-  friend std::istream& operator>>(std::istream& ist, SplitMix& e) {
-    return ist >> e.state;
-  }
-};
-
-// [[Rcpp::export]]
-Rcpp::NumericVector splitmix_rnorm(const int n, const double mean = 0.0, const double sd = 1.0) {
-  auto rng = dqrng::generator<SplitMix>(42);
-  Rcpp::NumericVector result(n);
-  rng->generate<dqrng::normal_distribution>(result, mean, sd);
-  return result;
-}
-/*** R
-splitmix_rnorm(10)
-system.time(splitmix_rnorm(1e7))
-*/
+
#include <Rcpp.h>
+// [[Rcpp::depends(dqrng, BH)]]
+#include <dqrng_distribution.h>
+
+class SplitMix {
+public:
+  typedef uint64_t result_type;
+  SplitMix (result_type seed) : state(seed) {};
+  result_type operator() () {
+    result_type z = (state += 0x9e3779b97f4a7c15ULL);
+    z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
+    z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
+    return z ^ (z >> 31);
+  }
+  void seed(result_type seed) {state = seed;}
+  static constexpr result_type min() {return 0;};
+  static constexpr result_type max() {return UINT64_MAX;};
+
+private:
+  result_type state;
+
+public:  
+  friend std::ostream& operator<<(std::ostream& ost, const SplitMix& e) {
+    return ost << e.state;
+  }
+  friend std::istream& operator>>(std::istream& ist, SplitMix& e) {
+    return ist >> e.state;
+  }
+};
+
+// [[Rcpp::export]]
+Rcpp::NumericVector splitmix_rnorm(const int n, const double mean = 0.0, const double sd = 1.0) {
+  auto rng = dqrng::generator<SplitMix>(42);
+  Rcpp::NumericVector result(n);
+  rng->generate<dqrng::normal_distribution>(result, mean, sd);
+  return result;
+}
+/*** R
+splitmix_rnorm(10)
+system.time(splitmix_rnorm(1e7))
+*/

Since SplitMix is a very fast RNG, the speed of this function is comparable to dqrnorm. Generally speaking you can use any C++11 compliant RNG with 64 bit output size. For example, here the 64 bit Threefry engine with 13 rounds from package sitmo is used:

-
#include <Rcpp.h>
-// [[Rcpp::depends(dqrng, BH, sitmo)]]
-#include <dqrng_distribution.h>
-#include <threefry.h>
-
-// [[Rcpp::export]]
-Rcpp::NumericVector threefry_rnorm(const int n, const double mean = 0.0, const double sd = 1.0) {
-  auto rng = dqrng::generator<sitmo::threefry_13_64>(42);
-  Rcpp::NumericVector result(n);
-  rng->generate<dqrng::normal_distribution>(result, mean, sd);
-  return result;
-}
-
-/*** R
-threefry_rnorm(10)
-system.time(threefry_rnorm(1e7))
-*/
+
#include <Rcpp.h>
+// [[Rcpp::depends(dqrng, BH, sitmo)]]
+#include <dqrng_distribution.h>
+#include <threefry.h>
+
+// [[Rcpp::export]]
+Rcpp::NumericVector threefry_rnorm(const int n, const double mean = 0.0, const double sd = 1.0) {
+  auto rng = dqrng::generator<sitmo::threefry_13_64>(42);
+  Rcpp::NumericVector result(n);
+  rng->generate<dqrng::normal_distribution>(result, mean, sd);
+  return result;
+}
+
+/*** R
+threefry_rnorm(10)
+system.time(threefry_rnorm(1e7))
+*/

Note that for the (recommended) Threefry engine with 20 rounds some additional integration is provided in the dqrng_threefry.h header file.

@@ -423,24 +409,24 @@

Using the header only library
#include <random>
-#include <Rcpp.h>
-// [[Rcpp::depends(dqrng)]]
-#include <dqrng_generator.h>
-#include <xoshiro.h>
-
-// [[Rcpp::export]]
-Rcpp::NumericVector std_rnorm(const int n, const double mean = 0.0, const double sd = 1.0) {
-  auto rng = dqrng::generator<dqrng::xoroshiro128plusplus>(42);
-  Rcpp::NumericVector result(n);
-  rng->generate<std::normal_distribution>(result, mean, sd);
-  return result;
-}
-
-/*** R
-std_rnorm(10)
-system.time(std_rnorm(1e7))
-*/

+
#include <random>
+#include <Rcpp.h>
+// [[Rcpp::depends(dqrng)]]
+#include <dqrng_generator.h>
+#include <xoshiro.h>
+
+// [[Rcpp::export]]
+Rcpp::NumericVector std_rnorm(const int n, const double mean = 0.0, const double sd = 1.0) {
+  auto rng = dqrng::generator<dqrng::xoroshiro128plusplus>(42);
+  Rcpp::NumericVector result(n);
+  rng->generate<std::normal_distribution>(result, mean, sd);
+  return result;
+}
+
+/*** R
+std_rnorm(10)
+system.time(std_rnorm(1e7))
+*/

Typically this is not as fast as dqrnorm, but the technique is useful to support distributions not (yet) included in dqrng. Note however, that the algorithms used for the distributions from @@ -449,24 +435,24 @@

Using the header only library
#include <Rcpp.h>
-// [[Rcpp::depends(dqrng, BH)]]
-#include <pcg_random.hpp>
-#include <boost/random/normal_distribution.hpp>
-
-// [[Rcpp::plugins(cpp11)]]   
-// [[Rcpp::export]]
-Rcpp::NumericVector boost_pcg_rnorm(const int n, const double mean = 0.0, const double sd = 1.0) {
-  pcg32 rng(42);
-  boost::random::normal_distribution<double> dist(mean, sd);
-  Rcpp::NumericVector result(n);
-  std::generate(result.begin(), result.end(), [&dist, &rng](){return dist(rng);});
-  return result;
-}
-/*** R
-boost_pcg_rnorm(10)
-system.time(boost_pcg_rnorm(1e7))
-*/

+
#include <Rcpp.h>
+// [[Rcpp::depends(dqrng, BH)]]
+#include <pcg_random.hpp>
+#include <boost/random/normal_distribution.hpp>
+
+// [[Rcpp::plugins(cpp11)]]   
+// [[Rcpp::export]]
+Rcpp::NumericVector boost_pcg_rnorm(const int n, const double mean = 0.0, const double sd = 1.0) {
+  pcg32 rng(42);
+  boost::random::normal_distribution<double> dist(mean, sd);
+  Rcpp::NumericVector result(n);
+  std::generate(result.begin(), result.end(), [&dist, &rng](){return dist(rng);});
+  return result;
+}
+/*** R
+boost_pcg_rnorm(10)
+system.time(boost_pcg_rnorm(1e7))
+*/

This is quite fast since boost::random::normal_distribution uses the fast Ziggurat algorithm. For some applications it is necessary to draw random numbers @@ -475,29 +461,29 @@

Using the header only library
#include <Rcpp.h>
-// [[Rcpp::depends(dqrng, BH)]]
-#include <boost/random/binomial_distribution.hpp>
-#include <dqrng_distribution.h>
-
-// [[Rcpp::export]]
-Rcpp::NumericMatrix multiple_distributions(int n) {
-  auto rng = dqrng::generator<dqrng::xoshiro256plusplus>(42);
-  Rcpp::NumericMatrix out(n, 3);
-  double p = 0.0;
-  for (int i = 0; i < n; ++i) {
-    p = double(i) / double(n);
-    out(i,0) = rng->variate<boost::random::binomial_distribution<int>>(1, p);
-    out(i,1) = rng->variate<dqrng::normal_distribution>(p, 1.0);
-    out(i,2) = rng->variate<dqrng::normal_distribution>(4.0, 3.0 - p);
-  }
-  Rcpp::colnames(out) = Rcpp::CharacterVector::create("Bernoulli", "Normal1", "Normal2");
-  return out;
-}
-
-/*** R
-multiple_distributions(5)
-*/
+
#include <Rcpp.h>
+// [[Rcpp::depends(dqrng, BH)]]
+#include <boost/random/binomial_distribution.hpp>
+#include <dqrng_distribution.h>
+
+// [[Rcpp::export]]
+Rcpp::NumericMatrix multiple_distributions(int n) {
+  auto rng = dqrng::generator<dqrng::xoshiro256plusplus>(42);
+  Rcpp::NumericMatrix out(n, 3);
+  double p = 0.0;
+  for (int i = 0; i < n; ++i) {
+    p = double(i) / double(n);
+    out(i,0) = rng->variate<boost::random::binomial_distribution<int>>(1, p);
+    out(i,1) = rng->variate<dqrng::normal_distribution>(p, 1.0);
+    out(i,2) = rng->variate<dqrng::normal_distribution>(4.0, 3.0 - p);
+  }
+  Rcpp::colnames(out) = Rcpp::CharacterVector::create("Bernoulli", "Normal1", "Normal2");
+  return out;
+}
+
+/*** R
+multiple_distributions(5)
+*/
@@ -508,40 +494,38 @@

Accessing the global RNGdqRNGkind is called. You therefore should use this calls only within functions:

-
#include <Rcpp.h>
-// [[Rcpp::depends(dqrng, BH)]]
-#include <boost/random/binomial_distribution.hpp>
-#include <dqrng.h>
-#include <dqrng_distribution.h>
-
-// [[Rcpp::export]]
-Rcpp::NumericMatrix multiple_distributions(int n) {
-  auto rng = dqrng::random_64bit_accessor{};
-  Rcpp::NumericMatrix out(n, 3);
-  double p = 0.0;
-  for (int i = 0; i < n; ++i) {
-    p = double(i) / double(n);
-    out(i,0) = rng.variate<boost::random::binomial_distribution<int>>(1, p);
-    out(i,1) = rng.variate<dqrng::normal_distribution>(p, 1.0);
-    out(i,2) = rng.variate<dqrng::normal_distribution>(4.0, 3.0 - p);
-  }
-  Rcpp::colnames(out) = Rcpp::CharacterVector::create("Bernoulli", "Normal1", "Normal2");
-  return out;
-}
-
-/*** R
-dqRNGkind("Xoshiro256++")
-dqset.seed(42)
-multiple_distributions(5)
-*/
+
#include <Rcpp.h>
+// [[Rcpp::depends(dqrng, BH)]]
+#include <boost/random/binomial_distribution.hpp>
+#include <dqrng.h>
+#include <dqrng_distribution.h>
+
+// [[Rcpp::export]]
+Rcpp::NumericMatrix multiple_distributions(int n) {
+  auto rng = dqrng::random_64bit_accessor{};
+  Rcpp::NumericMatrix out(n, 3);
+  double p = 0.0;
+  for (int i = 0; i < n; ++i) {
+    p = double(i) / double(n);
+    out(i,0) = rng.variate<boost::random::binomial_distribution<int>>(1, p);
+    out(i,1) = rng.variate<dqrng::normal_distribution>(p, 1.0);
+    out(i,2) = rng.variate<dqrng::normal_distribution>(4.0, 3.0 - p);
+  }
+  Rcpp::colnames(out) = Rcpp::CharacterVector::create("Bernoulli", "Normal1", "Normal2");
+  return out;
+}
+
+/*** R
+dqRNGkind("Xoshiro256++")
+dqset.seed(42)
+multiple_distributions(5)
+*/

+ @@ -554,16 +538,16 @@

Accessing the global RNG

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/articles/index.html b/articles/index.html index a7861f2..299828d 100644 --- a/articles/index.html +++ b/articles/index.html @@ -3,7 +3,7 @@ - +
@@ -31,7 +31,7 @@
- +
@@ -87,15 +87,15 @@

All vignettes

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/articles/parallel.html b/articles/parallel.html index 8cae3a0..81d629a 100644 --- a/articles/parallel.html +++ b/articles/parallel.html @@ -12,14 +12,13 @@ - - +
@@ -48,7 +47,7 @@
- +
@@ -91,9 +90,9 @@

Parallel RNG usage

Ralf Stubner

-

2024-05-28

+

2024-09-06

- Source: vignettes/parallel.Rmd + Source: vignettes/parallel.Rmd
@@ -119,13 +118,18 @@

2024-05-28

Threefry: usage from R

-

The Threefry engine uses internally a counter with \(2^{256}\) possible states, which can be -split into different substreams. When used from R or C++ with the two -argument dqset.seed or dqset_seed this counter -space is split into \(2^{64}\) streams -with \(2^{192}\) possible states each. -This is equivalent to \(2^{64}\) -streams with a period of \(2^{194}\) +

The Threefry engine uses internally a counter with +22562^{256} +possible states, which can be split into different substreams. When used +from R or C++ with the two argument dqset.seed or +dqset_seed this counter space is split into +2642^{64} +streams with +21922^{192} +possible states each. This is equivalent to +2642^{64} +streams with a period of +21942^{194} each.

In the following example a matrix with random numbers is generated in parallel using the parallel package. The resulting correlation matrix @@ -163,17 +167,39 @@

Threefry: usage from R

Xo(ro)shiro: jump ahead with OpenMP

-

The Xoshiro256+/++/** generators has a period of \(2^{256} -1\) and offers \(2^{128}\) sub-sequences that are \(2^{128}\) random draws apart as well as -\(2^{64}\) streams that are \(2^{192}\) random draws apart. The -Xoroshiro128+/++/** generators has a period of \(2^{128} -1\) and offers \(2^{64}\) sub-sequences that are \(2^{64}\) random draws apart as well as -\(2^{32}\) streams that are \(2^{98}\) random draws apart. You can go -from one sub-sequence to the next using the jump() or -long_jump() method and the convenience wrapper -jump(int n) or long_jump(int n), which -advances to the nth sub-sequence. When used from R or C++ -with the two argument dqset.seed and -dqset_seed you get \(2^{64}\) streams that are \(2^{192}\) and \(2^{64}\) random draws apart for -Xoshiro256+/++/** and Xoroshiro128+/++/**, respectively.

+

The Xoshiro256+/++/** generators has a period of +225612^{256} -1 +and offers +21282^{128} +sub-sequences that are +21282^{128} +random draws apart as well as +2642^{64} +streams that are +21922^{192} +random draws apart. The Xoroshiro128+/++/** generators has a period of +212812^{128} -1 +and offers +2642^{64} +sub-sequences that are +2642^{64} +random draws apart as well as +2322^{32} +streams that are +2982^{98} +random draws apart. You can go from one sub-sequence to the next using +the jump() or long_jump() method and the +convenience wrapper jump(int n) or +long_jump(int n), which advances to the nth +sub-sequence. When used from R or C++ with the two argument +dqset.seed and dqset_seed you get +2642^{64} +streams that are +21922^{192} +and +2642^{64} +random draws apart for Xoshiro256+/++/** and Xoroshiro128+/++/**, +respectively.

As an example using C++ we draw and sum a large number of uniformly distributed numbers. This is done several times sequentially as well as using OpenMP for parallelisation. Care has been taken to keep the global @@ -245,14 +271,24 @@

Xo(ro)shiro: jump ahead with OpenMPPCG: multiple streams with RcppParallel

From the PCG family we will look at pcg64, a 64-bit generator with a -period of \(2^{128}\). It offers the -function advance(int n), -which is equivalent to n random draws but scales as \(O(ln(n))\) instead of \(O(n)\). In addition, it offers \(2^{127}\) separate streams that can be -enabled via the function set_stream(int n) +period of +21282^{128}. +It offers the function advance(int n), +which is equivalent to n random draws but scales as +O(ln(n))O(ln(n)) +instead of +O(n)O(n). +In addition, it offers +21272^{127} +separate streams that can be enabled via the function set_stream(int n) or the two argument constructor with seed and stream. When used from R or C++ with the two argument dqset.seed -and dqset_seed you get \(2^{64}\) streams out of the possible \(2^{127}\) separate streams.

+and dqset_seed you get +2642^{64} +streams out of the possible +21272^{127} +separate streams.

In the following example a matrix with random numbers is generated in parallel using RcppParallel. Instead of using the more traditional approach of generating the random numbers from a certain distribution, @@ -545,9 +581,7 @@

Using the global RNG - -

+
@@ -560,16 +594,16 @@

Using the global RNG

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/articles/sample.html b/articles/sample.html index 95d5445..95084c0 100644 --- a/articles/sample.html +++ b/articles/sample.html @@ -12,14 +12,13 @@ - - +
@@ -48,7 +47,7 @@
- +
@@ -91,9 +90,9 @@

Fast sampling methods

Ralf Stubner

-

2024-05-28

+

2024-09-06

- Source: vignettes/sample.Rmd + Source: vignettes/sample.Rmd
@@ -403,9 +402,7 @@

Technicalities - -

+ @@ -418,16 +415,16 @@

Technicalities

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/authors.html b/authors.html index d915f94..a697001 100644 --- a/authors.html +++ b/authors.html @@ -3,7 +3,7 @@ - +
@@ -31,7 +31,7 @@
- +
@@ -66,37 +66,37 @@

Authors and Citation

- +
  • Ralf Stubner. Author, maintainer.

  • -

    daqana GmbH. Copyright holder. +

    daqana GmbH. Copyright holder.

  • -

    David Blackman. Copyright holder. +

    David Blackman. Copyright holder.
    Xoroshiro / Xoshiro family

  • -

    Melissa O'Neill. Copyright holder. +

    Melissa O'Neill. Copyright holder.
    PCG family

  • -

    Sebastiano Vigna. Copyright holder. +

    Sebastiano Vigna. Copyright holder.
    Xoroshiro / Xoshiro family

  • -

    Aaron Lun. Contributor. +

    Aaron Lun. Contributor.

  • -

    Kyle Butts. Contributor. +

    Kyle Butts. Contributor.

  • -

    Henrik Sloot. Contributor. +

    Henrik Sloot. Contributor.

  • @@ -107,20 +107,20 @@

    Authors and Citation

    Citation

    - Source: DESCRIPTION + Source: DESCRIPTION

    Stubner R (2024). dqrng: Fast Pseudo Random Number Generators. -R package version 0.4.1, https://github.com/daqana/dqrng, https://daqana.github.io/dqrng/. +R package version 0.4.1.1, https://github.com/daqana/dqrng, https://daqana.github.io/dqrng/.

    @Manual{,
       title = {dqrng: Fast Pseudo Random Number Generators},
       author = {Ralf Stubner},
       year = {2024},
    -  note = {R package version 0.4.1, https://github.com/daqana/dqrng},
    +  note = {R package version 0.4.1.1, https://github.com/daqana/dqrng},
       url = {https://daqana.github.io/dqrng/},
     }
    @@ -135,15 +135,15 @@

    Citation

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/index.html b/index.html index 364d826..0bfa5a2 100644 --- a/index.html +++ b/index.html @@ -19,7 +19,7 @@ - +
@@ -48,7 +48,7 @@
- +
@@ -258,16 +258,16 @@

Dev status

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/news/index.html b/news/index.html index 9059772..53f0a5e 100644 --- a/news/index.html +++ b/news/index.html @@ -3,7 +3,7 @@ - +
@@ -31,7 +31,7 @@
- +
- +
  • Fix an UBSAN error found by CRAN (#90 fixing #89)
  • Fix a compilation error when the compiler does not provide a 128bit integer type (#90 fixing #88)
  • Disable PCG64 on MacOS PowerPC (#91 fixing #88)
  • @@ -197,15 +197,15 @@
- - + + diff --git a/pkgdown.yml b/pkgdown.yml index 534aae8..b30f66b 100644 --- a/pkgdown.yml +++ b/pkgdown.yml @@ -1,10 +1,9 @@ pandoc: 3.1.11 -pkgdown: 2.0.9 +pkgdown: 2.1.0 pkgdown_sha: ~ articles: cpp-api: cpp-api.html dqrng: dqrng.html parallel: parallel.html sample: sample.html -last_built: 2024-05-28T11:54Z - +last_built: 2024-09-06T18:43Z diff --git a/reference/dqrmv-1.png b/reference/dqrmv-1.png index b77594c..87f0ff0 100644 Binary files a/reference/dqrmv-1.png and b/reference/dqrmv-1.png differ diff --git a/reference/dqrmv.html b/reference/dqrmv.html index 9a8d7fe..b1a0c6d 100644 --- a/reference/dqrmv.html +++ b/reference/dqrmv.html @@ -3,7 +3,7 @@ - +
@@ -31,7 +31,7 @@
- +
@@ -77,19 +77,19 @@

Multivariate Distributions

Arguments

-
n
+ + +
n

number of observations

-
...
+
...

forwarded to rmvnorm

Value

- - -

numeric matrix of multivariate normal distributed variables

+

numeric matrix of multivariate normal distributed variables

See also

@@ -101,11 +101,11 @@

Examples

sigma <- matrix(c(4,2,2,3), ncol=2)
 x <- dqrmvnorm(n=500, mean=c(1,2), sigma=sigma)
 colMeans(x)
-#> [1] 1.093079 1.874458
+#> [1] 0.893133 2.029687
 var(x)
 #>          [,1]     [,2]
-#> [1,] 3.757546 1.801775
-#> [2,] 1.801775 2.792292
+#> [1,] 4.325769 2.020718
+#> [2,] 2.020718 2.888071
 plot(x)
 
 
@@ -122,15 +122,15 @@

Examples

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/reference/dqrng-functions.html b/reference/dqrng-functions.html index df8062f..9af5e12 100644 --- a/reference/dqrng-functions.html +++ b/reference/dqrng-functions.html @@ -17,7 +17,7 @@ - +
@@ -45,7 +45,7 @@
- +
@@ -119,58 +119,57 @@

R interface

Arguments

-
kind
+ + +
kind

string specifying the RNG (see details)

-
normal_kind
+
normal_kind

ignored; included for compatibility with RNGkind

-
state
+
state

character vector representation of the RNG's internal state

-
n
+
n

number of observations

-
min
+
min

lower limit of the uniform distribution

-
max
+
max

upper limit of the uniform distribution

-
mean
+
mean

mean value of the normal distribution

-
sd
+
sd

standard deviation of the normal distribution

-
rate
+
rate

rate of the exponential distribution

-
seed
+
seed

integer scalar to seed the random number generator, or an integer vector of length 2 representing a 64-bit seed. Maybe NULL, see details.

-
stream
+
stream

integer used for selecting the RNG stream; either a scalar or a vector of length 2

Value

- - -

dqrunif, dqrnorm, and dqrexp return a numeric vector - of length n. dqrrademacher returns an integer vector of length n.

-

-

dqrng_get_state returns a character vector representation of the RNG's internal state.

+

dqrunif, dqrnorm, and dqrexp return a numeric vector + of length n. dqrrademacher returns an integer vector of length n. + dqrng_get_state returns a character vector representation of the RNG's internal state.

Details

@@ -256,15 +255,15 @@

Examples

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/reference/dqrng-package.html b/reference/dqrng-package.html index f0bd258..2d05c1b 100644 --- a/reference/dqrng-package.html +++ b/reference/dqrng-package.html @@ -6,7 +6,7 @@ - +
@@ -34,7 +34,7 @@
- +
@@ -110,15 +110,15 @@

Author

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/reference/dqsample.html b/reference/dqsample.html index 6746fbc..546f409 100644 --- a/reference/dqsample.html +++ b/reference/dqsample.html @@ -3,7 +3,7 @@ - +
@@ -31,7 +31,7 @@
- +
@@ -79,23 +79,25 @@

Unbiased Random Samples and Permutations

Arguments

-
x
+ + +
x

either a vector of one or more elements from which to choose, or a positive integer.

-
size
+
size

a non-negative integer giving the number of items to choose.

-
replace
+
replace

should sampling be with replacement?

-
prob
+
prob

a vector of probability weights for obtaining the elements of the vector being sampled.

-
n
+
n

a positive number, the number of items to choose from.

@@ -116,15 +118,15 @@

See also

-

Site built with pkgdown 2.0.9.

+

Site built with pkgdown 2.1.0.

- - + + diff --git a/reference/generateSeedVectors.html b/reference/generateSeedVectors.html index 056e7ed..b90e1f5 100644 --- a/reference/generateSeedVectors.html +++ b/reference/generateSeedVectors.html @@ -3,7 +3,7 @@ - +
@@ -31,7 +31,7 @@
- +
@@ -77,19 +77,19 @@

Generate seed as a integer vector

Arguments

-
nseeds
+ + +
nseeds

Integer scalar, number of seeds to generate.

-
nwords
+
nwords

Integer scalar, number of words to generate per seed.

Value

- - -

A list of length n, where each element is an integer vector that +

A list of length n, where each element is an integer vector that contains nwords words (i.e., 32*nwords bits) of randomness.

@@ -100,13 +100,13 @@

Details

  • Add the first value of the vector.

  • Left-shift the sum by 32.

  • Add the next value of the vector, and repeat.

  • -

    The aim is to facilitate R-level generation of seeds with sufficient -randomness to cover the entire state space of pseudo-random number -generators that require more than the ~32 bits available in an +

    The aim is to facilitate R-level generation of seeds with sufficient +randomness to cover the entire state space of pseudo-random number +generators that require more than the ~32 bits available in an int. It also preserves the integer nature of the seed, thus avoiding problems with casting double-precision numbers to integers.

    It is possible for the seed vector to contain NA_integer_ -values. This should not be cause for alarm, as R uses -INT_MAX +values. This should not be cause for alarm, as R uses -INT_MAX to encode missing values in integer vectors.

    @@ -179,15 +179,15 @@

    Examples

    -

    Site built with pkgdown 2.0.9.

    +

    Site built with pkgdown 2.1.0.

    - - + + diff --git a/reference/index.html b/reference/index.html index b6d1db1..3f6f10f 100644 --- a/reference/index.html +++ b/reference/index.html @@ -1,9 +1,9 @@ -Function reference • dqrngPackage index • dqrng - +
    @@ -31,7 +31,7 @@
    - +
    @@ -106,15 +106,15 @@

    All functions
    -

    Site built with pkgdown 2.0.9.

    +

    Site built with pkgdown 2.1.0.

    - - + + diff --git a/reference/user-supplied-rng.html b/reference/user-supplied-rng.html index 31fe029..fdd7855 100644 --- a/reference/user-supplied-rng.html +++ b/reference/user-supplied-rng.html @@ -5,7 +5,7 @@ - +
    @@ -33,7 +33,7 @@
    - +
    @@ -83,15 +83,15 @@

    Registering as user-supplied RNG

    Arguments

    -
    kind
    + + +
    kind

    Which methods should be registered? Either "both" or "rng".

    Value

    - - -

    Invisibly returns a three-element character vector of the RNG, normal +

    Invisibly returns a three-element character vector of the RNG, normal and sample kinds before the call.

    @@ -165,15 +165,15 @@

    Examples

    -

    Site built with pkgdown 2.0.9.

    +

    Site built with pkgdown 2.1.0.

    - - + + diff --git a/sitemap.xml b/sitemap.xml index c49fb45..4c91e27 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1,51 +1,19 @@ - - - - /404.html - - - /articles/cpp-api.html - - - /articles/dqrng.html - - - /articles/index.html - - - /articles/parallel.html - - - /articles/sample.html - - - /authors.html - - - /index.html - - - /news/index.html - - - /reference/dqrmv.html - - - /reference/dqrng-functions.html - - - /reference/dqrng-package.html - - - /reference/dqsample.html - - - /reference/generateSeedVectors.html - - - /reference/index.html - - - /reference/user-supplied-rng.html - + +/404.html +/articles/cpp-api.html +/articles/dqrng.html +/articles/index.html +/articles/parallel.html +/articles/sample.html +/authors.html +/index.html +/news/index.html +/reference/dqrmv.html +/reference/dqrng-functions.html +/reference/dqrng-package.html +/reference/dqsample.html +/reference/generateSeedVectors.html +/reference/index.html +/reference/user-supplied-rng.html +