[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