在 Rcpp (Armadillo) 函数中使用数字序列作为默认参数
Use numeric sequence as default agument in Rcpp (Armadillo) function
我需要这个用于一个更大的项目,但我认为这个最小的代表最好地解释了它。我在 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")
编译它会产生警告:
Warning message: Unable to parse C++ default value
'arma::exp2(arma::linspace(1, 9, 9))' for argument lambda of function
test
并且默认参数不起作用(调用 test()
)。
在此先致谢。
你不能“根据我们这里的合同”这样做,因为通过 导出 签名使其成为 R 可以看到并可以调用的东西,它必须符合来自 R API 的 .Call()
,这是一个 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/Whosebug/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
>
除了德克斯的回答,我还想添加一个解决方案。这是 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 是否为空,如果是,则其值被所需的默认值覆盖。
我需要这个用于一个更大的项目,但我认为这个最小的代表最好地解释了它。我在 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")
编译它会产生警告:
Warning message: Unable to parse C++ default value 'arma::exp2(arma::linspace(1, 9, 9))' for argument lambda of function test
并且默认参数不起作用(调用 test()
)。
在此先致谢。
你不能“根据我们这里的合同”这样做,因为通过 导出 签名使其成为 R 可以看到并可以调用的东西,它必须符合来自 R API 的 .Call()
,这是一个 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/Whosebug/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
>
除了德克斯的回答,我还想添加一个解决方案。这是 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 是否为空,如果是,则其值被所需的默认值覆盖。