【问题标题】:Rcpp - transform NumericVector with binary function?Rcpp - 用二进制函数转换 NumericVector?
【发布时间】:2018-04-09 16:04:51
【问题描述】:

我正在考虑通过用 C++ 重写并通过 Rcpp 集成来加速一些 R 代码。至少可以说,我的 Cpp 生锈了:因此,如果有任何建议,我将不胜感激。特别是,我正在寻找有关将函数映射到 Rcpp NumericVector 的所有元素的指针。这是一个例子。

我需要生成一个新的向量如下:

  • 从现有的NumericVector 中提取tail 切片;
  • 将新切片的每个元素除以除数

到目前为止我有这个:

// [[Rcpp::export]]
NumericVector cppAdjustProbabilities(  NumericVector& currentProbs, 
                                       const int index,
                                       const double divisor ) {

  //Note index <=0, e.g. -1 means remove first element
  if(index == 0) {
    return(currentProbs);
  } else {
    NumericVector newProbs = no_init(currentProbs.size()+index);                 
    NumericVector::iterator i = currentProbs.begin() - index; 
    NumericVector::iterator j = newProbs.begin();
    for(; i != currentProbs.end(); ++i, ++j) {
      *j=*i/divisor;
    }    
    return(newProbs);
  }
}

这可行,但我更喜欢使用“地图”方法。我查看了std::transform,但它只支持向量元素的一元运算——所以我看不到如何传递除数。例如,这无效:

std::transform(currentProbs.begin()-index, currentProbs.end(),
               newProbs.begin(), [](double val) { return (val / divisor);} );

有没有办法将divisor 带入 lambda 的范围?还是另一种方式?

谢谢

【问题讨论】:

  • 所以我明白了,你想将切片的每个元素除以一个值吗?例如,如果currentProbs 为 (0.1, 0.2, 0.3),索引为 -1,除数为 2,则输出是否为 (0.1, 0.15) - 取除第一个元素之外的所有元素 (0.2, 0.3),以及除以 2 得到 (0.1, 0.15)?
  • 我问是因为我非常怀疑分割向量的一个子集是一个上下文,你会得到很多(如果有的话)与 R 相比的速度提升
  • @duckmayr,是的,这是正确的-谢谢。这只是更大计算的一部分,因此有理由进行调查。还要研究在替代 BLAS 库中的链接是否会有所改善。

标签: c++ rcpp


【解决方案1】:

使用c++ lambda functions,您可以捕获这样的值:

src1 <- 'NumericVector cppAdjustProbabilities(  NumericVector& currentProbs, 
                                       const int index,
                                       const double divisor ) {

  //Note index <=0, e.g. -1 means remove first element
  if(index == 0) {
    return(currentProbs);
  } else {
    NumericVector newProbs = no_init(currentProbs.size()+index);
    std::transform(currentProbs.begin()-index, currentProbs.end(),
               newProbs.begin(), [&divisor](double val) { return (val / divisor);} );
               //                 ^^^^^^^^
    return(newProbs);
  }
}'

Rcpp::cppFunction(src1)

currentProbs <- c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)
index <- -5L
divisor <- 2.0
cppAdjustProbabilities(currentProbs, index, divisor)
#> [1] 0.30 0.35 0.40 0.45

【讨论】:

  • 谢谢@Ralf Stubner,太好了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2019-12-19
  • 1970-01-01
  • 2019-09-24
  • 2018-06-01
相关资源
最近更新 更多