在 Rcpp (Armadillo) 函数中使用数字序列作为默认参数

Posted

技术标签:

【中文标题】在 Rcpp (Armadillo) 函数中使用数字序列作为默认参数【英文标题】:Use numeric sequence as default agument in Rcpp (Armadillo) function 【发布时间】:2020-12-18 12:38:02 【问题描述】:

我需要这个用于一个更大的项目,但我认为这个最小的 reprex 最好地解释了它。我在 R 中有以下功能:

test <- function(x = 2^(1:9)) 
    x

test()
#> [1]   2   4   8  16  32  64 128 256 512

这工作正常。但是,我想使用 Rcpp Armadillo 将其翻译成 Rcpp。我使用以下 test.cpp 文件进行了尝试:

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

// [[Rcpp::export]]
vec test(const vec &lambda = arma::exp2(arma::linspace(1, 9, 9)))

    return lambda;

但是使用Rcpp::sourceCpp("functions/test.cpp") 编译它会产生警告:

警告消息:无法解析 C++ 默认值 'arma::exp2(arma::linspace(1, 9, 9))' 用于函数的参数 lambda 测试

并且默认参数不起作用(调用test())。

非常感谢。

【问题讨论】:

【参考方案1】:

您不能“根据我们这里的合同”这样做,因为通过导出签名使其成为 R 可以看到并可以调用的东西,它必须符合来自 .Call() 的签名R API,它是一个 C 函数,其中每个参数都是 SEXP

因此,接口上不允许使用 C++ 表达式。您可以将该逻辑移到内部作为次佳选择。

修改代码

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

// [[Rcpp::export]]
arma::vec testCpp(const int s, const int e, const int n) 
    arma::vec lambda = arma::exp2(arma::linspace(s, e, n));
    return lambda;


/*** R
testCpp(1,9, 9)
*/

输出

> Rcpp::sourceCpp("~/git/***/65357225/answer.cpp")

> testCpp(1,9, 9)
      [,1]
 [1,]    2
 [2,]    4
 [3,]    8
 [4,]   16
 [5,]   32
 [6,]   64
 [7,]  128
 [8,]  256
 [9,]  512
> 

【讨论】:

【参考方案2】:

除了 Dirks 答案之外,我还想添加一个解决方案。这是 CPP 代码。

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

// [[Rcpp::export]]
vec test_cpp(Rcpp::NumericVector x = Rcpp::NumericVector::create())

    if (x.size() == 0)
    
        x = exp2(linspace(1, 9, 9));
    
    return x;

这个想法是默认将 x 初始化为一个空的 NumericVector。在函数内部,检查 x 是否为空,如果是,则将其值覆盖为所需的默认值。

【讨论】:

以上是关于在 Rcpp (Armadillo) 函数中使用数字序列作为默认参数的主要内容,如果未能解决你的问题,请参考以下文章

(Rcpp, armadillo) 将 arma::vec 转换为 arma::mat

Rcpp Armadillo:RStudio 说“exp”不明确

Parallel 和 Rcpp Armadillo 的问题:集群工作人员之间可能存在变量损坏

从 Rcpp Armadillo 中的 sp_mat 访问维度名称

如何通过在 Rcpp 或 Armadillo 中将矩阵乘以向量元素来复制 R 的功能?

RcppArmadillo 和 Armadillo 之间的性能差异