[Rcpp-devel] Getting and setting array dimensions - simpler ways?

Douglas Bates bates at stat.wisc.edu
Mon Sep 10 16:14:36 CEST 2012


On Mon, Sep 10, 2012 at 8:55 AM, Søren Højsgaard <sorenh at math.aau.dk> wrote:
> Dear list,
>
> I want to do some operations on an array, here exemplified by taking log (the operations I have in mind are made using RcppArmadillo):
>
>> pp  <- array(c(.1, .4, .4, .1), dim=c(2,2),dimnames=list(A=c("a1","a2"), B=c("b1","b2")))
>> log(pp)
>     B
> A            b1         b2
>   a1 -2.3025851 -0.9162907
>   a2 -0.9162907 -2.3025851
>
> It is essential that dim and dimnames attributes are preserved. My take on this task is:
>
> src <-'
>  using namespace arma;
>  using namespace Rcpp;
>  NumericVector p(pp_);
>  // Some computations using RcppArmadillo
>  vec pp = as<vec>(pp_);
>  vec aa = log(pp);
>  // Get the result back
>  NumericVector ans(p.length());
>  ans = aa;
>  // Set attributes
>  ans.attr("dim")      = p.attr("dim");
>  ans.attr("dimnames") = p.attr("dimnames");
>  return(wrap(ans));
>  '
>> library(inline)
>> loga <- cxxfunction(signature(pp_ = ""), src, plugin = "RcppArmadillo", verbose=F)
>> loga(pp)
>     B
> A            b1         b2
>   a1 -2.3025851 -0.9162907
>   a2 -0.9162907 -2.3025851
>
> This works, but if anyone can spot a more elegant (fewer lines) way of doing it, I would be happy to know...

Following what Dirk said:

I think an easier way is to create an Rcpp::NumericMatrix and clone
it, then use std::transform to take the exponential of the elements.

Something like (not tested)

Rcpp::NumericMatrix p(pp_);
Rcpp::NumericMatrix q = clone<Rcpp::NumericMatrix>(p);
std::transform(p.begin(), p.end(), q.begin(), std::ptr_func(exp));
return q;

There is a method called something like input_transform for some Rcpp
objects that may make it even easier but a quick scan of the unit
tests didn't show a use.


More information about the Rcpp-devel mailing list