c++ - Rcpp 相当于 rowsum

标签 c++ r eigen rcpp armadillo

<分区>

我正在寻找 C++/Rcpp/Eigen 或 Armadillo 中 R 函数 rowsum 的快速替代方案。

目的是根据一个分组 vector b得到一个 vector a中的元素之和。例如:

> a
 [1] 2 2 2 2 2 2 2 2 2 2    
> b
 [1] 1 1 1 1 1 2 2 2 2 2
> rowsum(a,b)
  [,1]
1   10
2   10

Rcpp 中编写一个简单的 for 循环非常慢,但也许我的代码效率低下。

我也尝试在 Rcpp 中调用函数 rowsum,但是,rowsum 不是很快。

最佳答案

为了补充 Martin 的代码,这里有一些基于 Rcpp 的版本。

int increment_maybe(int value, double vec_i){
    return vec_i == 0 ? value : ( value +1 ) ;  
}

// [[Rcpp::export]]
NumericVector cpprowsum2(NumericVector x, IntegerVector f){
    std::vector<double> vec(10) ;
    vec.reserve(1000); 
    int n=x.size(); 
    for( int i=0; i<n; i++){
        int index=f[i]; 
        while( index >= vec.size() ){
            vec.resize( vec.size() * 2 ) ;    
        }
        vec[ index ] += x[i] ;
    }
    // count the number of non zeros
    int s = std::accumulate( vec.begin(), vec.end(), 0, increment_maybe) ; 
    NumericVector result(s) ;
    CharacterVector names(s) ;

    std::vector<double>::iterator it = vec.begin() ;
    for( int i=0, j=0 ; j<s; j++ ,++it, ++i ){
        // move until the next non zero value
        while( ! *it ){ i++ ; ++it ;}
        result[j] = *it ;
        names[j]  = i ;
    }
    result.attr( "dim" ) = IntegerVector::create(s, 1) ;
    result.attr( "dimnames" ) = List::create(names, R_NilValue) ; 
    return result ;
}

C++ 代码处理一切,包括格式化为 rowsum 给出的矩阵格式,并显示出(稍微)更好的性能(至少在示例中)。

# from Martin's answer
> system.time(r1 <- rowsum1(x, f))
   user  system elapsed
  0.014   0.001   0.015

> system.time(r3 <- cpprowsum2(x, f))
   user  system elapsed
  0.011   0.001   0.013

> identical(r1, r3)
[1] TRUE

关于c++ - Rcpp 相当于 rowsum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16975034/

相关文章:

linear-algebra - 特征库中的广义特征值和向量

c++ - 在同一个 DLL 中使用 _COM_SMARTPTR CreateInstance 而无需注册

r - R 中的并行包在 Windows 上通过引用传递大对象

r - 检查和可视化大型数据框中的间隙/空白和结构

即使设置了 rm(df),R 循环也会消耗 5GB RAM

eigen - 如何在控制台中打印带有特征的格式化稀疏矩阵?

C++ 闭包和 std::function

c++ - 如何使用cpp将类的成员写入二进制文件?

c++ - 关于 sizeof 运算符的困惑

c++ - Eigen :设置 EIGEN_STACK_ALLOCATION_LIMIT 不起作用