[Rcpp-devel] When does using iterators for subscripting help?

Hadley Wickham hadley at rice.edu
Fri Jan 6 19:25:20 CET 2012


> I'm coming late to the party but ...  I was able to squeeze a couple
> of milliseconds from the computation by expressing the counts as
> integers and ensuring that I did not copy x by using an Eigen::Map.
> It may well be that an Rcpp::NumericVector will not be a copy in this
> case but I have found it difficult to determine exactly when an Rcpp
> vector is going to be copied.  With Eigen I can ensure that the
> original storage in R will be used for the vector.
>
> count_eigen <- cxxfunction(signature(x="numeric", binwidth="numeric",
>                                     origin="numeric", nbins="integer"), '
> double binwidth_ = ::Rf_asReal(binwidth), origin_ = ::Rf_asReal(origin);
>
> Eigen::VectorXi counts(::Rf_asInteger(nbins));
> Eigen::Map<Eigen::VectorXd> x_(as<Eigen::Map<Eigen::VectorXd> >(x));
>
> int n = x_.size();
>
> counts.setZero();
> for (int i = 0; i < n; i++) counts[((x_[i] - origin_) / binwidth_)]++;
>
> return wrap(counts);
> ', plugin="RcppEigen")
>
>
> As you see, I use ::Rf_asReal() and ::Rf_asInteger() for conversion to
> scalar doubles or scalar integers.  Those functions are part of the R
> API and are fast and general.

Thanks.  Would you mind explaining a couple of the C++ idioms that you used?

* What's going on with Eigen::Map<Eigen::VectorXd>
x_(as<Eigen::Map<Eigen::VectorXd> >(x)) - you're creating a new Map
(templated to contain VectorXds) called x_ and initialising with a
converted x?

* I find it hard to visually parse  <Eigen::Map<Eigen::VectorXd> >(x).
 Is there a reason you don't write it as
x_(as<Eigen::Map<Eigen::VectorXd>>(x)?  Maybe because that would then
form the >> operator?

* What does ::Rf_asReal mean?  How is it different to Rf_asReal?

Thanks!

Hadley

-- 
Assistant Professor / Dobelman Family Junior Chair
Department of Statistics / Rice University
http://had.co.nz/


More information about the Rcpp-devel mailing list