为什么在Rcpp中使用“ pnorm”会出现错误

时间:2018-11-14 20:50:23

标签: r rcpp armadillo

我需要在我的Rcpp代码中包含来自arma::的变量。但是在尝试使用糖功能pnorm时遇到了一个问题。这是一个演示:

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

// [[Rcpp::export]]
double pget(NumericVector x, NumericVector beta) {
  arma::colvec xx = Rcpp::as<arma::colvec>(x) ;
  arma::colvec bb = Rcpp::as<arma::colvec>(beta) ;
  double tt = as_scalar( arma::trans(xx) * bb);
  double temp = Rcpp::pnorm(tt);
  return temp;
}

然后我得到一个错误:no matching function for call to 'pnorm5'

这是否意味着我不能使用Rcpp::pnorm ???

2 个答案:

答案 0 :(得分:6)

Rcpp糖函数用于矢量类型参数,例如Rcpp::NumericVector。对于标量参数,可以使用R命名空间中的函数:

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

// [[Rcpp::export]]
double pget(NumericVector x, NumericVector beta) {
  arma::colvec xx = Rcpp::as<arma::colvec>(x) ;
  arma::colvec bb = Rcpp::as<arma::colvec>(beta) ;
  double tt = as_scalar( arma::trans(xx) * bb);
  double temp = R::pnorm(tt, 0.0, 1.0, 1, 0);
  return temp;
}

/*** R
x <- rnorm(5)
beta <- rnorm(5)
pget(x, beta)
*/

顺便说一句,这里有两个变体。第一个变体使用arma而不是Rcpp向量作为参数。由于这些是const引用,因此不会复制任何数据。另外,使用arma::dot

// [[Rcpp::export]]
double pget2(const arma::colvec& xx, const arma::colvec& bb) {
  double tt = arma::dot(xx, bb);
  return R::pnorm(tt, 0.0, 1.0, 1, 0);
}

第二个变量无需借助Armadillo即可计算标量积:

// [[Rcpp::export]]
double pget3(NumericVector x, NumericVector beta) {
  double tt = Rcpp::sum(x * beta);
  return R::pnorm(tt, 0.0, 1.0, 1, 0);
}

答案 1 :(得分:2)

与Rcpp的@RalfStubner相比,我的专家要少得多,因此我不得不四处寻找(在StackOverflowRcpp cheat sheat的帮助下)以获取以下代码。我没有在标量上使用R-namespace版本,而是转换回了NumericVector ...几乎可以肯定,这可以更有效地完成,或者由真正知道自己在做什么的人跳过几步...例如可能有可能无需经过as_scalar ...?

而直接完成arma-NumericVector转换。
#include <RcppArmadillo.h>
#include <RcppArmadilloExtensions/sample.h>
#include <Rcpp.h>

// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
NumericVector pget(NumericVector x, NumericVector beta) {
  colvec xx = as<colvec>(x) ;
  colvec bb = as<colvec>(beta) ;
  double tt = as_scalar(trans(xx) * bb);
  NumericVector tt2 = NumericVector::create( tt );
  NumericVector temp = Rcpp::pnorm(tt2);
  return temp;
}