Почему я получаю сообщение об ошибке "pnorm" в Rcpp - PullRequest
0 голосов
/ 14 ноября 2018

Мне нужно включить переменную от arma:: в мой код Rcpp. Но я столкнулся с проблемой при попытке использовать сахарную функцию 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 голосов
/ 15 ноября 2018

Я гораздо менее эксперт, чем @RalfStubner в Rcpp, поэтому мне пришлось взломать (с помощью StackOverflow и чит-код Rcpp ), чтобы получить следующее код. Вместо того чтобы использовать версии пространства имен R в скалярах, я преобразовал обратно в NumericVector ... это почти наверняка можно сделать более эффективно / пропустив несколько шагов кем-то, кто действительно знает, что они делают ... например, Возможно, что преобразование arma-to-NumericVector может быть выполнено напрямую, не проходя через as_scalar ...?

#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;
}
0 голосов
/ 15 ноября 2018

Функции сахара 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);
}

Второй вариант вычисляет скалярное произведение, не прибегая к броненосцу:

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