如何解决如何使用Rcpp使执行就地操作的C ++函数可用于另一个R包?
说我有一个名为“ packA”的R软件包,其中包含以下文件“ funcA.cpp”:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r,cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcA (arma::vec& x) {
x += 1;
}
从R调用此函数会产生预期结果,即就地向向量的每个元素加1:
> vec <- c(1,2,3)
> funcA(vec)
> vec
[1] 2 3 4
现在说我有第二个软件包“ packB”,它想调用函数“ funcA”。它包含以下名为“ funcB.cpp”的文件:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcB() {
arma::vec x = {1,3};
Rcout << x << "\n";
packA::funcA(x);
Rcout << x << "\n";
}
调用此函数不再产生所需的结果,因为似乎向量x不再就地修改:
> funcB()
1.0000
2.0000
3.0000
1.0000
2.0000
3.0000
在仍然使用Rcpp的同时,有什么方法可以保留C ++函数的就地操作吗?预先感谢您的任何建议。
编辑: 我根据DirkEddelbüttel的建议修改了“ funcB.cpp”:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcB(arma::vec& y) {
packA::funcA(y);
}
不幸的是,从R调用函数时的结果是相同的:
> vec <- c(1,3)
> funcB(vec)
> vec
[1] 1 2 3
修改2:
经过一些进一步的实验,我注意到,arma::vec& x
一旦进入funcA
的足迹,一切就开始崩溃。只需使用NumericVector
即可:
“ funcA.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r,cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcA (NumericVector& num_x) {
num_x[2] = 10 + num_x[2];
}
> vec <- c(1,3)
> funcA(vec)
> vec
[1] 1 2 13
“ funcB.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcB(NumericVector& num_y) {
packA::funcA(num_y);
}
> vec <- c(1,3)
> funcB(vec)
> vec
[1] 1 2 13
即使使用高级arma::vec
构造函数创建具有共享内存的Armadillo矢量,只要输入是NumericVector
:
“ funcA.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r,cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcA (NumericVector& num_x) {
arma::vec x_int = arma::vec(num_x.begin(),3,false,false);
x_int(2) = 10 + x_int(2);
}
> vec <- c(1,3)
> funcA(vec)
> vec
[1] 1 2 13
> vec <- c(1,3)
> funcB(vec)
> vec
[1] 1 2 13
使用arma::vec
尝试相同的操作不再有效。
“ funcA.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r,cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcA (arma::vec& x) {
arma::vec x_int = arma::vec(x.begin(),false);
x(2) = 10 + x(2);
}
> vec <- c(1,3)
> funcA(vec)
> vec
[1] 1 2 13
“ funcB.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcB(arma::vec& y) {
packA::funcA(y);
}
> vec <- c(1,3)
> funcB(vec)
> vec
[1] 1 2 3
解决方法
我认为这是一个不同的话题。调用A
时,将创建一个R向量。该R向量是由R存储器构成的,R拥有“ R”并让Armadillo重用。在那里就可以。
但是,当您运行B
时,您将构建一个R所不拥有的 Armadillo 向量。这不是R中的“我们”内存,并且内容只能通过复制返回。然后您就地释放了mod。使该函数具有arma::vec
签名,并改为传递现有的向量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。