【问题标题】:How to compute rowSums in rcpp如何在 rcpp 中计算 rowSums
【发布时间】:2017-01-31 09:30:40
【问题描述】:

我正在将一个 R 函数转换为 Rcpp,其中我使用了 R 函数 rowSums,这似乎不是 Rcpp 中的有效糖表达式。我找到了 rowSums here 的 Rcpp 版本的代码。但我得到了

错误:使用了未声明的标识符

当我在我的主要 Rcpp 函数中使用 rowSumsC() 时。

有简单的解决方法吗?

编辑:代码

cppFunction(
  "NumericMatrix Expcpp(NumericVector x, NumericMatrix w,
   NumericVector mu, NumericVector var, NumericVector prob, int k) {
   for (int i=1; i<k; ++i){
   w(_,i) = prob[i] * dnorm(x,mu[i], sqrt(var[i]));
   }
   w = w / rowSums(w)
   return w;
}")

【问题讨论】:

  • 请创建一个可重现的示例(例如邮政编码和电话)。此外,还有一个相当于rowSums 的 Rcpp 糖。它是在 Rcpp 0.12.8 中添加的
  • 我已经上传了代码。我不能真正调用它,因为它无法定义,因为 rowSums 没有被识别。与 rowSums 等效的 rcpp 的名称是什么,我是否需要做任何额外的事情才能调用它?我对 rcpp 真的很陌生。

标签: r rcpp


【解决方案1】:

Rcpp officially added rowSum support in 0.12.8。因此,在 Advanced R 中无需使用 Hadley 设计的rowSumsC 函数。

话虽如此,代码还是有一些问题。


Rcpp 目前支持 MatrixVectorMatrixMatrix 计算。 (可以通过#583 添加对后者的支持,但如果需要,应考虑使用RcppArmadilloRcppEigen)。因此,下面这行是有问题的:

w = w / rowSums(w)

要解决这个问题,首先计算rowSums,然后使用传统的for 循环对矩阵进行标准化。 注意:R 不同,C++ 中的循环非常快。

NumericVector summed_by_row = rowSums(w);

for (int i = 0; i < k; ++i) {
  w(_,i) = w(_,i) / summed_by_row[i];
}

接下来,C++ 索引从 0 而不是 1 开始。因此,下面的for循环是有问题的:

for (int i=1; i<k; ++i)

修复:

for (int i=0; i<k; ++i)

最后,可以减少函数的参数,因为某些值不相关或被覆盖。

函数声明来自:

NumericMatrix Expcpp(NumericVector x, NumericMatrix w,
   NumericVector mu, NumericVector var, NumericVector prob, int k)

收件人:

NumericMatrix Expcpp(NumericVector x, NumericVector mu, NumericVector var, NumericVector prob) {

  int n = x.size();
  int k = mu.size();
  NumericMatrix w = no_init(n,k); 

  .....

将上述所有反馈放在一起,我们得到了所需的功能。

Rcpp::cppFunction(
  'NumericMatrix Expcpp(NumericVector x, NumericVector mu, NumericVector var, NumericVector prob) {

  int n = x.size();
  int k = mu.size();

  NumericMatrix w = no_init(n,k); 

  for (int i = 0; i < k; ++i) { // C++ indices start at 0
     w(_,i) = prob[i] * dnorm(x, mu[i], sqrt(var[i]));
  }

  Rcpp::Rcout << "Before: " << std::endl << w << std::endl;

  NumericVector summed_by_row = rowSums(w);

  Rcpp::Rcout << "rowSum: " << summed_by_row << std::endl;

  // normalize by column to mimic R
  for (int i = 0; i < k; ++i) {
    w(_,i) = w(_,i) / summed_by_row[i];
  }

  Rcpp::Rcout << "After: " << std::endl << w << std::endl;

  return w;
  }')

set.seed(51231)
# Test values
n <- 2
x <- seq_len(n)
mu <- x
var <- x
prob <- runif(n)

mat <- Expcpp(x, mu, var, prob)

输出

Before: 
0.0470993 0.125384
0.0285671 0.160996

rowSum: 0.172483 0.189563
After: 
0.273066 0.661436
0.165623 0.849300

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多