Dade
Dade

Reputation: 43

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.

Upvotes: 1

Views: 790

Answers (1)

Dirk is no longer here
Dirk is no longer here

Reputation: 368261

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.)

Upvotes: 9

Related Questions