我是Rccp的新手并且通过将C ++代码翻译成Rcpp环境遇到了一个问题 - 到目前为止我找不到解决方案(这是我原来的帖子的编辑版本,我认为不清楚):
背景:我有多个参数和大型矩阵/数组需要转移到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)
*/
答案 0 :(得分:3)
好的,让我们谈谈 R 到 C ++ 。在某些时候,你必须有一个导出到 R 的函数,它将接收一个 R 对象并传递它到 C ++ 。一旦进入 C ++ ,天空就是你想要如何构建与该对象的交互的限制。思想过程:
但是,然后我将整个矩阵交给一个子函数,以便在此函数中使用矩阵。这似乎是一个非常糟糕的主意,我想在命名空间内存中使用矩阵M并且在子函数中访问它而不克隆它 。
稍有问题,因为您现在刚刚引入了一个名为 M 的全局变量来处理您的数据。如果未初始化 M ,则例程将停滞不前。如果您无意中修改了 M ,那么所有例程的数据都将更改。因此,我不确定全局变量方法是否是您想要的解决方案。
您似乎遇到的主要问题是关于&#34;克隆&#34;的强调部分。使用 C ++ 时,默认的构造传递是复制对象。但是,与 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()
*/