【问题标题】:RcppArmadillo and arma namespaceRcppArmadillo 和 arma 命名空间
【发布时间】:2014-03-23 13:45:52
【问题描述】:

刚开始接触 R,但完全是 C++ 新手,我用 RcppArmadillo 编写了一些函数,并且对它的可用性和速度都非常感兴趣。我现在想把函数变成一个包,使用函数RcppArmadillo.package.skeleton()

只要我在每个犰狳对象(垫子、colvec 等)之前明确使用arma:: 前缀,这就可以了。但是,如果我将 using namespace arma; 放在我的 cpp 文件的开头,然后省略 arma::,我将无法加载新创建的包并获得大量错误,这些错误表明 Armadillo 命名空间未被识别。

非常感谢任何有关如何解决此问题的帮助/建议。谢谢,

法比安

PS:我在 Windows 7 和 Ubuntu 12.04 上都尝试了上述方法,在每种情况下都使用 R 3.0.2 和 RcppArmadillo_0.4.000.4。

PS2:附加的 cpp 文件(紧跟在http://gallery.rcpp.org/articles/simulate-multivariate-normal/ 后面)说明了我的观点。如果我通过sourceCpp(来自 Rcpp 包)将它导入 R 中,它会很好地工作,但是当我尝试将它包含在新包中时会导致上面提到的问题。

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
colvec mvndrawC(colvec mu, mat sig) {

double k = mu.size();
colvec aux = as<colvec>(rnorm(k));
mat csig = chol(sig).t();
colvec out = mu + csig*aux;
return(out);

}

编辑:详细信息

这是我执行以下操作时得到的错误输出:

  1. 运行命令RcppArmadillo.package.skeleton("test2"),从而为新包“test2”创建文件夹
  2. 将以上代码粘贴到.cpp文件中,并复制到新的test2/src文件夹中
  3. 尝试加载新的test2 包,方法是从devtools 包中调用load_all("test2")

错误消息(在 Rstudio 中)

Loading test2
Re-compiling test2
'/usr/lib/R/bin/R' --vanilla CMD INSTALL '/home/fabian/test2' --library='/tmp    
/RtmplfAET0'  \
--no-R --no-data --no-help --no-demo --no-inst --no-docs --no-exec --no-multiarch  \
--no-test-load --preclean 

* installing *source* package 'test2' ...
** libs
g++ -I/usr/share/R/include -DNDEBUG   -I"/home/fabian/R/x86_64-pc-linux-gnu-library   
/3.0/Rcpp/include" -I"/home/fabian/R/x86_64-pc-linux-gnu-library/3.0/RcppArmadillo  
/include"  -UNDEBUG -Wall -pedantic -g -O0 -fpic  -O3 -pipe  -g  -c RcppExports.cpp -o 
RcppExports.o
RcppExports.cpp:10:1: error: 'colvec' does not name a type
RcppExports.cpp: In function 'SEXPREC* test2_mvndrawC(SEXP, SEXP)':
RcppExports.cpp:16:40: error: 'colvec' was not declared in this scope
RcppExports.cpp:16:40: note: suggested alternative:
/home/fabian/R/x86_64-pc-linux-gnu-library/3.0/RcppArmadillo/include/armadillo_bits   
/typedef_mat.hpp:65:22: note:   'arma::colvec'
RcppExports.cpp:16:47: error: template argument 1 is invalid
RcppExports.cpp:16:55: error: expected initializer before 'mu'
RcppExports.cpp:17:40: error: 'mat' was not declared in this scope
RcppExports.cpp:17:40: note: suggested alternative:
/home/fabian/R/x86_64-pc-linux-gnu-library/3.0/RcppArmadillo/include/armadillo_bits   
/typedef_mat.hpp:63:22: note:   'arma::mat'
RcppExports.cpp:17:44: error: template argument 1 is invalid
RcppExports.cpp:17:52: error: expected initializer before 'sig'
RcppExports.cpp:18:16: error: expected ';' before '__result'
RcppExports.cpp:19:9: error: '__result' was not declared in this scope
make: *** [RcppExports.o] Error 1
ERROR: compilation failed for package 'test2'
* removing '/tmp/RtmplfAET0/test2'
Error: Command failed (1)
In addition: Warning message:
The following packages are referenced using Rcpp::depends attributes however are  
not listed in the Depends and LinkingTo fields of the package DESCRIPTION file: 
RcppArmadillo 

PS3:如果我在文件开头删除// [[Rcpp... 行,最后的警告消息就会消失(但我无法通过sourceCpp 获取它,所以我让它进来)。

【问题讨论】:

  • "没有足够的信息"——你的包应该加载任何一种方式。但如果有疑问,只需添加前缀 arma:: ...
  • 确实如此。特别是,即使编译器错误消息通常很神秘且非常冗长,但在这些情况下发布它们仍然非常有帮助。
  • 感谢您的帖子,真是太快了!我编辑了问题以包含更多细节。

标签: r rcpp armadillo


【解决方案1】:

我相信这是因为 Rcpp 属性(将您制作的 C++ 源文件编译成 RcppExports.cpp)不会将 using namespace arma; 语句复制到那里。

这很棘手,因为不同的文件可能使用不同的命名空间,所以属性解析器不能将所有 using namespace ... 语句复制到 RcppExports.cpp 中——它只是默认使用 Rcpp 命名空间。如果我们只是将所有 using namespace 语句随意复制到 RcppExports.cpp 中,肯定会发生冲突。

无论如何,解决方法是显式添加 arma:: 前缀,或者您可以修改 RcppExports.cpp 文件以在顶部添加 using namespace arma;(但每次调用 compileAttributes() 后都必须这样做) .

【讨论】:

  • 哦,好预感。这是有道理的。我,一方面,在我的代码中使用明确的arma::
  • 否则你可以在inst/include/test2.h 中有use namespace arma; compileAttribute 会自动#include
  • 感谢您的提示,并首先提供 Rcpp 和 RcppArmadillo!对于我目前的大部分工作(贝叶斯时间序列模型的 MCMC 采样),它们确实提高了 R 的吸引力。
猜你喜欢
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多