<div dir="ltr">Yes, definitely. Thank you for your reply, Dirk! I will keep looking into this and send an update if I figure out something.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Aug 5, 2014 at 11:27 AM, Dirk Eddelbuettel <span dir="ltr"><<a href="mailto:edd@debian.org" target="_blank">edd@debian.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Hi Antonio,<br>
<div><div class="h5"><br>
On 5 August 2014 at 11:03, Antonio Coppola wrote:<br>
| Hello RCPP,<br>
|<br>
| There is a puzzle that I have been wrestling with for a while now. This is in<br>
| the context of a package for numerical optimization. The underlying<br>
| implementation is, of course, in C++. I’d like to let the user pass in both R<br>
| functions and external pointers to C++ for function evaluation, much like in<br>
| the RcppDE package. I also want the user to be able to pass in an environment<br>
| in which to evaluate the function. So far so good. No issue doing that with the<br>
| R functions, and for the C++ pointers I define a class after the RcppDE model:<br>
|<br>
| class EvalCompiled : public EvalBase {<br>
|         public:<br>
|             EvalCompiled(Rcpp::XPtr<funcPtr> xptr, SEXP __env) {<br>
|                 funptr = *(xptr);<br>
|                 env = __env;<br>
|             };<br>
|             EvalCompiled(SEXP xps, SEXP __env) {<br>
|                 Rcpp::XPtr<funcPtr> xptr(xps);<br>
|                 funptr = *(xptr);<br>
|                 env = __env;<br>
|             };<br>
|              Rcpp::NumericVector eval(SEXP par) {<br>
|                 neval++;<br>
|                 return funptr(par, env);<br>
|             }<br>
|         private:<br>
|             funcPtr funptr;<br>
|<br>
|             SEXP env;<br>
|         };<br>
|<br>
| The user has to create the external pointer using inline in R. The following is<br>
| an example using a logit regression setup with ridge penalty. The extra<br>
| environment is required to pass in the data:<br>
|<br>
| lhoodL2.inc <- 'Rcpp::NumericVector lhood(SEXP xs, SEXP env){<br>
|   arma::vec par = Rcpp::as<arma::vec>(xs);<br>
|   Rcpp::Environment e = Rcpp::as<Rcpp::Environment>(env);<br>
|   arma::mat X = Rcpp::as<arma::mat>(e["X"]);<br>
|   arma::vec y = Rcpp::as<arma::vec>(e["y"]);<br>
|   double prec = Rcpp::as<double>(e["prec"]);<br>
|   arma::mat Xbeta = X * par;<br>
|   double sum1 = sum(y % Xbeta - log(1 + exp(Xbeta)));<br>
|   arma::mat sum2 = sum(pow(par, 2 * prec));<br>
|   arma::vec out = -(sum1 - 0.5 * sum2);<br>
|   Rcpp::NumericVector ret = Rcpp::as<Rcpp::NumericVector>(wrap(out));<br>
|   return ret;<br>
| }<br>
| '<br>
|<br>
| lhoodL2.body <- '<br>
|      typedef Rcpp::NumericVector (*funcPtr)(SEXP, SEXP);<br>
|      return(XPtr<funcPtr>(new funcPtr(&lhood)));<br>
|      '<br>
|<br>
| lhoodL2.CPP <- cxxfunction(signature(), body=lhoodL2.body,<br>
|                           inc=lhoodL2.inc, plugin="RcppArmadillo")<br>
|<br>
| # Passing in some data<br>
| env <- new.env()<br>
| env[["X"]] <- X<br>
| env[["y"]] <- y<br>
| env[["prec"]] <- prec<br>
|<br>
| output <- myNumericalOptimizationFun(lhoodL2.CPP(), c(-1.2,1), environment=env)<br>
|<br>
| The external pointer is passed into the numerical optimization routine, and<br>
| then the function is evaluated repeatedly until the optimization algorithm<br>
| reaches convergence. Now this works, but there is a big inefficiency here,<br>
| which is presumably slowing down things a lot. Namely, the data in the<br>
| environment is copied in memory at each iteration of the function, even though<br>
| this is not actually necessary. One would only need to copy the objects in<br>
| memory the first time the function is evaluated, and then reference them with a<br>
| pointer for the next iterations. Can you envision any way of doing this within<br>
| the context of the RCPP framework?<br>
<br>
</div></div>Hm. Excellent question, and I quite like the XPtr use -- and I mentioned this<br>
very trick for this very use in talks / workshops at U Chicago and U Kansas.<br>
<br>
The environment should not get copied if it isn't altered.  You could try<br>
the  Rcpp::Environment class.<br>
<br>
Or you could try constructing an outer object holding the data, ensuring<br>
there is only one and then supplying an accessor object.  I know I am being<br>
brief here but does that makes sense to you?<br>
<span class="HOEnZb"><font color="#888888"><br>
Dirk<br>
<br>
--<br>
<a href="http://dirk.eddelbuettel.com" target="_blank">http://dirk.eddelbuettel.com</a> | @eddelbuettel | <a href="mailto:edd@debian.org">edd@debian.org</a><br>
</font></span></blockquote></div><br></div>