简体   繁体   English

如何在rcpp中计算rowSums

[英]How to compute rowSums in rcpp

I'm converting an R function into Rcpp, where I have used the R function rowSums , which appears to not be a valid sugar expression in Rcpp. 我正在将R函数转换为Rcpp,在那里我使用了R函数rowSums ,它似乎不是rowSums中的有效糖表达式。 I found code for an Rcpp version of rowSums here . 我在这里找到了一个Rcpp版本的rowSums的代码。 But I'm getting 但我得到了

error: use of undeclared identifier 错误:使用未声明的标识符

when I use rowSumsC() in my main Rcpp function. 当我在主Rcpp函数中使用rowSumsC()时。

Is there a easy fix? 有一个简单的解决方案吗?

Edit: The code 编辑:代码

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;
}")

Rcpp officially added rowSum support in 0.12.8 . Rcpp正式在0.12.8中添加了rowSum支持 Therefore, there is no need to use rowSumsC function devised by Hadley in Advanced R. 因此,不需要使用Hadley在Advanced R中设计的rowSumsC函数。

Having said this, there are a few issues with the code. 话虽如此,代码存在一些问题。


Rcpp presently does not support Matrix to Vector or Matrix to Matrix computations. 目前RCPP 支持Matrix ,以VectorMatrix ,以Matrix计算。 (Support for the later may be added per #583 , though if needed one should consider using RcppArmadillo or RcppEigen ). (根据#583可以添加对后者的支持,但如果需要,可以考虑使用RcppArmadilloRcppEigen )。 Therefore, the following line is problematic: 因此,以下行存在问题:

w = w / rowSums(w)

To address this, first compute the rowSums and then standardize the matrix using a traditional for loop. 为了解决这个问题,首先计算rowSums ,然后使用传统的for循环标准化矩阵。 Note: Looping in C++ is very fast unlike R . 注意:R不同,C ++中的循环非常快。

NumericVector summed_by_row = rowSums(w);

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

Next, C++ indices begin at 0 not 1 . 接下来,C ++索引从0开始而不是1 Therefore, the following for loop is problematic: 因此,以下for循环是有问题的:

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

The fix: 修复:

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

Lastly, the parameters of the function can be reduced as some of the values are not relevant or are overridden. 最后,可以减少函数的参数,因为某些值不相关或被覆盖。

The function declaration goes from: 函数声明来自:

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

To: 至:

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

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

  .....

Putting all of the above feedback together, we get the desired function. 将上述所有反馈放在一起,我们就可以获得所需的功能。

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)

Output 产量

Before: 
0.0470993 0.125384
0.0285671 0.160996

rowSum: 0.172483 0.189563
After: 
0.273066 0.661436
0.165623 0.849300

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM