简体   繁体   中英

Issue importing dnorm and pnorm functions from R to Rcpp

I came across the following strange behaviour when trying to import dnorm() and pnorm() functions from R package stats into Rcpp. I apply both dnorm() and pnorm() with mean 0 and standard deviation 1 to a vector of observations. If I repeat the computations several times on the same vector, sometimes I obtain different results. It looks like I'm doing something wrong with the import of the two functions, but that does not explain why the results are sometimes good, and other inconsistent.

I put here the function that import the dnorm() and pnorm() functions from stats :

    {test_imp_script<-'
     using Eigen::VectorXd;
     VectorXd a = Rcpp::as<VectorXd>(aa);

     Environment st("package:stats");
     Function dn = st["dnorm"];
     Function pn = st["pnorm"]; 
     SEXP dd_a = dn(a,0,1);
     SEXP pp_a = pn(a,0,1);
     VectorXd d_a = as<VectorXd>(dd_a);
     VectorXd p_a = as<VectorXd>(pp_a);

     return List::create(Named("d") = d_a,Named("p") = p_a);'}
    test_imp <- cxxfunction(signature( aa="numeric"), test_imp_script, plugin = "RcppEigen")

Now, try to run the following example with 2000 repetitions of test_imp .

    set.seed(123)
    t<-rnorm(1000,0,1)
    a<-test_imp(t)
    for (i in 1:2000){
      set.seed(123)
      b<-test_imp(t)
      cat(i,"d",c(sum(b$d),sum(b$p)),"\n")
      if (any(a$d!=b$d)) break    
      if (any(a$p!=b$p)) break    
    }

Sometimes, the experiment breaks before reaching the end of the loop. Sometimes it does not. No clear pattern.

Thank you for your responses.

OMG these are already available.

First, via sugar:

R> library(Rcpp)
R> cppFunction("NumericVector ex1() { return rnorm(5, 0, 1); }")
R> set.seed(42); ex1()
[1]  1.370958 -0.564698  0.363128  0.632863  0.404268
R> 

Second, via a convenience namespace (but note that this is NOT vectorized)

R> cppFunction("double ex2() { return R::rnorm(0, 1); }")
R> set.seed(42); ex2()
[1] 1.37096
R> 

Third, if you insist, call the R API directly which is more the less the previous answer but uglier:

R> cppFunction("double ex3() { return Rf_rnorm(0, 1); }")
R> set.seed(42); ex3()
[1] 1.37096
R> 

We have gone out of our way to provide free and comprehensive documentation. I really do not think you have looked at it. It would be to your advantage to do so as will no longer rely on others to retype it here for you.

(Yes, you did ask for dnorm and pnorm but all the so called d/p/q/r functions for the statistical distributions are implemented in parallel. Hence, where rnorm exists you also have dnorm , qnorm and pnorm , of course with different arguments.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM