Search code examples
c++rcpparmadillo

Vectorized log1p() in RcppArmadillo


What is the appropriate way to apply log1p() to an entire arma::vec? It seems that there are vectorized versions of log() and exp(), but not log1p(). I found that there's syntactic sugar for NumericVector, so I end up converting arma::vec to NumericVector, applying log1p(), then converting back:

#include <RcppArmadillo.h>

using namespace Rcpp;

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::vec test_log1p( arma::vec v )
{
  // arma::vec res = log1p(v);         // results in a compilation error
  NumericVector v1 = log1p( wrap(v) );
  arma::vec res = as<arma::vec>(v1);
  return res;
}

Is there a more elegant way of doing this?


Solution

  • Use the .transform() or .for_each() facilities available for Armadillo vectors and matrices. Example:

    v.transform( [](double val) { return log1p(val); } );
    

    or

    v.for_each( [](double& val) { val = log1p(val); } );  // note the & character
    

    You may need to use the std prefix: std::log1p() instead of log1p().