Why do I get the error for using “pnorm” in Rcpp

前端 未结 2 1627
小鲜肉
小鲜肉 2021-01-21 18:27

I need to involve variable from arma::in my Rcpp code. But I ran into a problem when trying to use the sugar function pnorm. Here is a demo:

         


        
相关标签:
2条回答
  • 2021-01-21 18:59

    I'm much less of an expert than @RalfStubner at Rcpp, so I had to hack around (with help from StackOverflow and the Rcpp cheat sheat) to get the following code. Instead of using the R-namespace versions on scalars, I converted back to a NumericVector ... this can almost certainly be done more efficiently/skipping a few steps by someone who actually knows what they're doing ... e.g. it's possible that the arma-to-NumericVector conversion could be done directly without going through 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 讨论(0)
  • 2021-01-21 19:00

    The Rcpp sugar functions are meant for vector type arguments like Rcpp::NumericVector. For scalar arguments you can use the functions in the R namespace:

    #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)
    */
    

    BTW, here two variants. First variant uses arma instead of Rcpp vectors as arguments. Since these are const references, no data is copied. In addition, arma::dot is used:

    // [[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);
    }
    

    The second variant calculates the scalar product without resorting to 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);
    }
    
    0 讨论(0)
提交回复
热议问题