将 C++ classes/objects 翻译成 Rcpp 的最有效方法?

Most efficient way to translate C++ classes/objects into Rcpp?

我是 Rccp 的新手,在将 C++ 代码转换到 Rcpp 环境时遇到了一个问题——到目前为止我找不到解决方案(这是我认为的原始 post 的编辑版本不清楚):

背景:我有多个参数和大matrices/arrays需要转移到C++级别。在 C++ 中,我有几个函数需要访问这些参数和矩阵,在某些情况下,还需要更改值等。在 C++ 中,我会创建 类 来组合所有参数和矩阵以及需要访问它们的函数.通过这样做,我不需要将它们(每次)传递给函数。

问题:我不知道它如何与 Rcpp 一起工作。在下面的示例中(该函数很愚蠢,但希望是一种简单的方法来说明我的问题),我在 R 中创建了一个矩阵,然后在 C++ 中使用。但是,然后我将整个矩阵交给一个子函数,以便在该函数中使用该矩阵。这似乎是一个非常糟糕的主意,我希望在命名空间内存中拥有矩阵 M 并在子函数中访问它而不克隆它。

#include <RcppArmadillo.h>
//[[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;


double fnc1 (int t, int s, arma::mat M) // I would prefer not to have M in the arguments but rather available in the namespace
{
 double out = M(t,s) - M(t,s);
 return out;
}


// [[Rcpp::export]]
arma::mat Rout (arma::mat M)
{
 int ncol = M.n_cols;
 int nrow = M.n_rows;

 for(int c = 0; c<ncol; ++c)
 {
  for(int r = 0; r<nrow; ++r)
  {
   M(r,c) =  fnc1(r, c, M);
  }
 }

return M;
}


/*** R
m <- matrix(runif(50), ncol = 10, nrow = 5)
Rout(m)
*/

好吧,我们来说说RC++。在某些时候,你必须有一个 exportedR 的函数,它将接收一个 R 对象和 传递回C++。一旦进入 C++,关于如何构造与该对象的交互,天空是无限的。的思考过程:

However, I then hand the entire matrix over to a sub-function in order to use the matrix within this function. This seems a very bad idea and I would rater like to have the matrix M in the namespace memory and access it in the sub function without cloning it.

有点问题,因为您现在刚刚引入了一个名为 M 全局变量 来处理您的数据。如果 M 没有被初始化,那么例程将会失败。如果您无意中修改了M,那么所有例程的数据都会改变。所以,我不确定采用全局变量方法是否是您想要的解决方案。

您似乎遇到的主要问题是关于 "clone" 的强调部分。使用 C++ 时,默认传递构造是 copy 对象。但是,与 R 不同的是,通过在对象名称前加上 & 前缀可以很容易地 通过引用传递 ,从而否定副本完全。这使过程本地化。

按引用传递演示

#include <RcppArmadillo.h>
//[[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;


double fnc1 (int t, int s, const arma::mat& M) {
  double out = M(t,s) - M(t,s);
  return out;
}


// [[Rcpp::export]]
arma::mat Rout (arma::mat& M) {
  int ncol = M.n_cols;
  int nrow = M.n_rows;

  for(int c = 0; c<ncol; ++c) {
    for(int r = 0; r<nrow; ++r) {
      M(r,c) =  fnc1(r, c, M);
    }
  }

  return M;
}


/*** R
m <- matrix(runif(50), ncol = 10, nrow = 5)
Rout(m)
*/

全局变量演示

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// Create a namespace to store M
namespace toad {
 arma::mat M;
}

double fnc1 (int t, int s) 
{
  double out = toad::M(t,s) - toad::M(t,s);
  return out;
}

// [[Rcpp::export]]
void Rin (arma::mat M)
{
 toad::M = M;
}

// [[Rcpp::export]]
void Rmanipulate()
{
  int ncol = toad::M.n_cols;
  int nrow = toad::M.n_rows;

  for(int c = 0; c<ncol; ++c)
  {
    for(int r = 0; r<nrow; ++r)
    {
      toad::M(r,c) =  fnc1(r, c);
    }
  }
}

// [[Rcpp::export]]
arma::mat Rout (){
  return toad::M;
}


/*** R
m <- matrix(runif(50), ncol = 10, nrow = 5)
Rin(m)
Rmanipulate()
Rout()
*/