RcppArmadillo 中的矢量化 log1p()

Posted

技术标签:

【中文标题】RcppArmadillo 中的矢量化 log1p()【英文标题】:Vectorized log1p() in RcppArmadillo 【发布时间】:2018-11-07 03:23:07 【问题描述】:

log1p() 应用于整个arma::vec 的适当方法是什么?似乎有log()exp() 的矢量化版本,但没有log1p()。我发现NumericVector 有语法糖,所以我最终将arma::vec 转换为NumericVector,应用log1p(),然后再转换回来:

#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;

有没有更优雅的方式来做到这一点?

【问题讨论】:

【参考方案1】:

魔鬼在细节中。

对于初学者来说,RcppArmadillo 没有“糖”,所以你的推理是有缺陷的——你不能只看在 Rcpp::NumericVector 上工作的 Rcpp Sugar 函数。

再一次,一个人可以像你一样转换。但是您选择了昂贵的转换。查看显式重用内存的高级构造函数——不需要副本。

一个更简单和更直接(但本地)的方法就是添加一个小的本地内联函数。这就是我要做的 :) 几分钟后完成。

最后,我们有一些兄弟项目将 Rcpp Sugar 推广到任何可以使用迭代器的东西上。那是“大道”,它可以做一些新的发展。也许开始at this repo。

【讨论】:

谢谢,德克。感谢您的洞察力。【参考方案2】:

使用可用于犰狳向量和矩阵的.transform() 或.for_each() 工具。示例:

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

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

您可能需要使用std 前缀:std::log1p() 而不是log1p()

【讨论】:

.for_each() 将成为我的建议 (+1)。请注意,OP 不需要使用std::log1p(),因为RcppArmadillo pulls in Rcpp 和Rcpp ensures log1p() is defined(参见第227-28 行)。 这就是我对“添加单行”的评论所想到的。我们可以几乎总是添加这样的东西,无论 Sugar 是否有预制的东西。

以上是关于RcppArmadillo 中的矢量化 log1p()的主要内容,如果未能解决你的问题,请参考以下文章

通用函数:快速的元素级数组函数

RcppArmadillo:for循环中的负索引

将 lambda 函数应用于 `RcppArmadillo` 中的 `arma::cube`

带有 Rcpparmadillo 的 Rcppnumerical 和 RcppEigen 中的 obtim_lbfgs 函数

js math 对数和指数处理 expm1 log1p

犰狳:将立方体子视图(管)转换为矢量