dqrng 与 Rcpp 用于从正态分布和二项分布中绘制

2024-03-25

我正在尝试学习如何从 Rcpp OpenMP 循环内的正态分布和二项式分布中抽取随机数。

我使用以下代码编写了R::rnorm and R::rbinom我理解这是一个不要那样做 https://stackoverflow.com/a/54717911/1800784.

#include <RcppArmadillo.h>
#include <omp.h>
#include <dqrng.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(dqrng)]]
// [[Rcpp::plugins(openmp)]]
using namespace Rcpp;

// [[Rcpp::export]]
arma::mat  my_matrix3(const arma::mat& A, 
                      const arma::mat& B) {

  dqrng::dqRNGkind("Xoroshiro128+");
  dqrng::dqset_seed(42);



  const int nObservations = A.n_cols;
  const int nDraws = B.n_rows;
  const int nRows = nObservations * nDraws;

  // Show initialization information
  Rcpp::Rcout << "nObservations: " << nObservations << std::endl 
              << "nDraws: " << nDraws << std::endl 
              << "nRows: " << nRows << std::endl;

  arma::mat out(nRows, 5);

  // Show trace of matrix construction
  Rcpp::Rcout << "out - rows: " << out.n_rows << std::endl 
              << "out - columns: " << out.n_cols << std::endl;

  int i,n,iter,row;
  double dot_product, random_number, p;
  omp_set_num_threads(2);
#pragma omp parallel for private(i, n, iter, row)
  for(i = 0; i < nDraws; ++i){
    for(n = 0; n < nObservations; ++n) {
      row = i * nObservations + n;
      dot_product = arma::as_scalar(A.col(n).t() * B.row(i).t());
      // Show trace statement of index being accessed
      out(row, 0) = i + 1;
      out(row, 1) = n + 1;
      out(row, 2) = R::rnorm(2.0, 1.0) ;//dqrng::dqrnorm(1, 2.0, 1.0)[1]; 
      out(row, 3) = 1 / (1 + std::exp(-out(row, 3) - std::exp(dot_product)));
      out(row, 4) = R::rbinom(1,out(row, 3));
    }
  }

  return out;
}

/*** R
set.seed(9782)
A <- matrix(rnorm(10), nrow = 5)
B <- matrix(rnorm(10), ncol = 5)
test <- my_matrix3(A = A, B = B)
test

mean(test[,5])
*/

正如 @ralf-stubner 所建议的,我正在尝试将该代码替换为dqrng https://cran.r-project.org/web/packages/dqrng/vignettes/dqrng.html。如果我正确理解文档,我可以替换R::rnorm(2.0, 1.0) with dqrng::dqrnorm(1, 2.0, 1.0)[1]。是对的吗?更换怎么样R::rbinom(1,out(row, 3))?我无法找到任何关于二项式绘图的参考文档 https://cran.r-project.org/web/packages/dqrng/dqrng.pdf


我能够编写以下并行从二项式分布中提取的代码:

#include <RcppArmadillo.h>
// [[Rcpp::depends(dqrng, BH, RcppArmadillo)]]
#include <pcg_random.hpp>
#include <boost/random/binomial_distribution.hpp>
#include <xoshiro.h>
#include <dqrng_distribution.h>
// [[Rcpp::plugins(openmp)]]
#include <omp.h>

// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
arma::mat parallel_random_matrix(int n, int m, int ncores, double p=0.5) {
  //dqrng::uniform_distribution dist(0.0, 1.0);
  boost::random::binomial_distribution<int> dist(1,p);
  dqrng::xoshiro256plus rng(42);
  arma::mat out(n,m);
  // ok to use rng here



#pragma omp parallel num_threads(ncores)
{
  dqrng::xoshiro256plus lrng(rng);      // make thread local copy of rng 
  lrng.jump(omp_get_thread_num() + 1);  // advance rng by 1 ... ncores jumps 
  auto gen = std::bind(dist, std::ref(lrng));

#pragma omp for
  for (int i = 0; i < m; ++i) {
    double lres(0);
    for (int j = 0; j < n; ++j) {
      out(j,i) = gen(); /// CAN I MAKE P BE A FUNCTION OF i and j? how???
    }
  }
}
// ok to use rng here
return out;
}

/*** R
parallel_random_matrix(5, 5, 4, 0.75)
*/

> parallel_random_matrix(5, 5, 4, 0.75)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]    0    1    1    1    1
[3,]    0    1    0    1    0
[4,]    1    1    1    1    1
[5,]    1    1    1    1    1

有办法打电话吗out(j,i) = gen();并使概率成为 i 和 j 的函数?

我写的代码有什么问题吗?


一个简单的解决方案是在循环中创建一个新的分发对象:

// [[Rcpp::depends(dqrng, BH, RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <boost/random/binomial_distribution.hpp>
#include <xoshiro.h>
#include <dqrng_distribution.h>
// [[Rcpp::plugins(openmp)]]
#include <omp.h>

// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
arma::mat parallel_random_matrix(int n, int m, int ncores, double p=0.5) {
  dqrng::xoshiro256plus rng(42);
  arma::mat out(n,m);
  // ok to use rng here

#pragma omp parallel num_threads(ncores)
{
  dqrng::xoshiro256plus lrng(rng);      // make thread local copy of rng 
  lrng.jump(omp_get_thread_num() + 1);  // advance rng by 1 ... ncores jumps 

#pragma omp for
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < n; ++j) {
      // p can be a function of i and j
      boost::random::binomial_distribution<int> dist(1,p);
      auto gen = std::bind(dist, std::ref(lrng));
      out(j,i) = gen();
    }
  }
}
  // ok to use rng here
  return out;
}

/*** R
parallel_random_matrix(5, 5, 4, 0.75)
*/

这样你就可以制作p取决于i and j。保留一个全局可能会更有效dist对象并在循环内重新配置它,请参阅here https://stackoverflow.com/questions/14268049/how-to-set-the-parameters-of-boostuniform-int-distribution-outside-of-the-stan对于类似的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

dqrng 与 Rcpp 用于从正态分布和二项分布中绘制 的相关文章

  • RcppArmadillo:带有each_slice的Lambda表达式

    我有一个具有正定矩阵的三维数组 我想获得一个具有所有矩阵的 Cholesky 因子的相同大小的数组 我正在使用犰狳库和cube类型 有方便的功能each slice我正在尝试使用它 但我没有让 lambda 表达式正常工作 所以希望有人可以
  • 在 Windows 中使用 rinside 和 qt

    我开始在 C 中使用 rinside 和 rcpp 我只想从零开始 所以我的 QT 项目除了创建 RInside 实例之外什么都没有 但我有一个无法解决的问题 我的项目中只有一个对话框 我的项目文件 QT core gui TARGET r
  • R 重新编译包失败,因为失败

    在我的 Linux 集群上 我在重新编译需要重新编译的 R 包时遇到问题 随着去除libRcpp so在最新版本中 最终目标是 让 R 包 DEseq2 运行 我们已经安装了新版本 g 中的 opt bin目录中有新库 opt lib64
  • 当 R 编译要在包中使用的 C++ 代码时,如何将标志传递给 R?

    我正在尝试在 R 包中使用 OpenCV 中的一些代码 并使用 Rcpp 来构建包 当我在我的机器上编译c代码时 它工作正常 例如 我在本地使用以下语法来编译facedetect cpp代码 g pkg config cflags open
  • 如何链接到 boost date_time

    Example 我有一个 Rcpp 函数 我想调用它boost posix time time from string 我从以下位置获取了示例代码增强文档 https www boost org doc libs 1 65 0 doc ht
  • 在 Rcpp 中按列对数据框排序

    有没有简单的方法可以通过 RCpp 中的两列 或多列或一列 对 DataFrame 进行排序 网上有很多排序算法 或者我可以使用std sort带有 DataFrame 的包装器 但我想知道 RCpp 或 RCppArmadillo 中是否
  • 用于矩阵向量乘积的 Rcpp Parallel 或 openmp

    我正在尝试对共轭梯度的朴素并行版本进行编程 所以我从简单的维基百科算法开始 我想改变dot products and MatrixVector产品通过其适当的并行版本 Rcppparallel 文档具有以下代码dot product使用并行
  • 从 Rcpp 返回 NA

    我正在尝试通过 Rcpp 返回 NA 我不懂为什么get na 按照这里的建议在这里不起作用post https stackoverflow com a 23745470 6484844 gt Rcpp cppFunction Numeri
  • 使用 Rcpp 运行编译的 C++ 代码

    我一直在努力通过 Dirk Eddelbuettel 的方法Rcpp教程在这里 http www rinfinance com agenda http www rinfinance com agenda 我已经学会了如何将 C 文件保存在目
  • Rcpp:无法打开共享对象文件

    我正在尝试开发一个 R 包 它利用阵列火 https github com arrayfire arrayfire 感谢 Rcpp 库 我已经开始编写示例代码 让我们将其命名为你好世界 cpp 看起来像这样 include
  • R中的快速并行二分距离计算

    使用并行 Rcpp 后端计算 R 中二分距离最快的方法是什么 parallelDist是一个很棒的包 带有 cpp 后端并支持多线程 但不支持二分距离计算 据我所知 Using parallelDist 用于二分距离矩阵计算 除了 m1 m
  • Rcpp 公开类的序列化

    我在 R 包中编写了一个 C 类 并将其暴露给 R 命名空间RCPP EXPOSED CLASS and RCPP MODULE 一切都很好 gt index An object of class Index Slot index C ob
  • 通过环境 Rcpp 从 C++ 调用函数

    我正在考虑通过环境从 C 调用 R 函数 但出现错误 这就是我所做的 include
  • 带有 C++ 代码的 R 包安装失败,未创建 DLL

    我目前正在开发一个 R 包 它使用 C 代码并包含外部库 dlib boost 和小组开发的优化库 我们使用 Rcpp 来集成 R 和 C 但问题是该包总是无法编译 而且我发现的类似问题都对我不起作用 R CMD 检查生成的报告为 inst
  • 使用 Rcpp 将目标文件链接到函数的简化示例[重复]

    这个问题在这里已经有答案了 我现有的 C 代码由三个文件组成 头文件 h 文件 库文件 o 文件 和源文件 它们目前在 UNIX 下运行 并在 Matlab 中编译为 mex 文件 我想使用 Rcpp 将它们移植到 R 它们都又长又复杂 所
  • 使累计总和更快

    我正在尝试计算矩阵每一列的累积和 这是我的 R 代码 testMatrix matrix 1 65536 ncol 256 microbenchmark apply testMatrix 2 cumsum times 100L Unit m
  • Rcpp 和 boost:它应该可以工作,但不能

    我对在以下位置找到的有趣帖子有疑问 具有四精度计算的 Rcpp https stackoverflow com questions 42262963 rcpp with quad precision computation I use Rc
  • 使用 Xptr 和 Function 调用 Rcpp 函数 - 仅 xptr 情况有效

    我正在尝试开发一个包 其中我需要输入用户的函数 可以使用定义Rcpp or in R 将其发送到另一个函数 在包内 struct并在那里处理它 当我使用Rcpp Xptr 即函数指针 代码可以工作 但同样不起作用Rcpp Function
  • 使用 Rcpp 的 R 快速 cbind 矩阵

    cbindR中的重复调用比较耗时 但对于各种数据类型也很强大 我编写的代码比cbind当绑定两个矩阵时 但bind cols in dplyr封装速度仅比cbind 唯一遗憾的是它不能将矩阵作为输入 有人可以让下面的代码更快吗 另外 如何快
  • 当我用一个观察值运行回归时,为什么“fastLm()”会返回结果?

    为什么fastLm 当我用一项观察进行回归时返回结果吗 下面为什么不lm and fastLm 结果相等吗 library Rcpp library RcppArmadillo library data table set seed 1 D

随机推荐