Note that there are some explanatory texts on larger screens.

plurals
  1. PORcpp function to be SLOWER than same R function
    primarykey
    data
    text
    <p>I have been coding a R function to compute an integral with respect to certain distributions, see code below.</p> <pre><code>EVofPsi = function(psi, probabilityMeasure, eps=0.01, ...){ distFun = function(u){ probabilityMeasure(u, ...) } xx = yy = seq(0,1,length=1/eps+1) summand=0 for(i in 1:(length(xx)-1)){ for(j in 1:(length(yy)-1)){ signPlus = distFun(c(xx[i+1],yy[j+1]))+distFun(c(xx[i],yy[j])) signMinus = distFun(c(xx[i+1],yy[j]))+distFun(c(xx[i],yy[j+1])) summand = c(summand, psi(c(xx[i],yy[j]))*(signPlus-signMinus)) } } sum(summand) } </code></pre> <p>It works fine, but it is pretty slow. It is common to hear that re-programming the function in a compiled language such as C++ would speed it up, especially because the R code above involves a double loop. So did I, using Rcpp:</p> <pre><code>#include &lt;Rcpp.h&gt; using namespace Rcpp; // [[Rcpp::export]] double EVofPsiCPP(Function distFun, Function psi, int n, double eps) { NumericVector xx(n+1); NumericVector yy(n+1); xx[0] = 0; yy[0] = 0; // discretize [0,1]^2 for(int i = 1; i &lt; n+1; i++) { xx[i] = xx[i-1] + eps; yy[i] = yy[i-1] + eps; } Function psiCPP(psi); Function distFunCPP(distFun); double signPlus; double signMinus; double summand = 0; NumericVector topRight(2); NumericVector bottomLeft(2); NumericVector bottomRight(2); NumericVector topLeft(2); // compute the integral for(int i=0; i&lt;n; i++){ //printf("i:%d \n",i); for(int j=0; j&lt;n; j++){ //printf("j:%d \n",j); topRight[0] = xx[i+1]; topRight[1] = yy[j+1]; bottomLeft[0] = xx[i]; bottomLeft[1] = yy[j]; bottomRight[0] = xx[i+1]; bottomRight[1] = yy[j]; topLeft[0] = xx[i]; topLeft[1] = yy[j+1]; signPlus = NumericVector(distFunCPP(topRight))[0] + NumericVector(distFunCPP(bottomLeft))[0]; signMinus = NumericVector(distFunCPP(bottomRight))[0] + NumericVector(distFunCPP(topLeft))[0]; summand = summand + NumericVector(psiCPP(bottomLeft))[0]*(signPlus-signMinus); //printf("summand:%f \n",summand); } } return summand; } </code></pre> <p>I'm pretty happy since this C++ function works fine. However, when I tested both functions, the C++ one ran SLOWER:</p> <pre><code>sourceCpp("EVofPsiCPP.cpp") pFGM = function(u,theta){ u[1]*u[2] + theta*u[1]*u[2]*(1-u[1])*(1-u[2]) } psi = function(u){ u[1]*u[2] } print(system.time( for(i in 1:10){ test = EVofPsi(psi, pFGM, 1/100, 0.2) } )) test print(system.time( for(i in 1:10){ test = EVofPsiCPP(psi, function(u){pFGM(u,0.2)}, 100, 1/100) } )) </code></pre> <p>So, is there some kind expert around willing to explain me this? Did I code like a monkey and is there a way to speed up that function? Moreover, I would have a second question. Indeed, I could have replaced the output type double by SEXP, and the argument types Function by SEXP as well, it doesn't seem to change anything. So what is the difference?</p> <p>Thank you very much in advance, Gildas </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload