簡體   English   中英

如何在Rcpp中求和矩陣的10個步驟行?

[英]How to sum 10 step rows of matrix in Rcpp?

我想使用Rcpp獲得以下結果。 大數據時,R較慢。 因此,我嘗試在Rcpp中進行編碼。

x <- matrix(1:150, ncol = 5)
z <- matrix(nrow = nrow(x) / 10, ncol = 5)
for (i in 1:5) {
    for (j in 1:(nrow(x) / 10)) {
    k = (j - 1) * 10 + 1;
    z[j, i] <- sum(x[k:(k+9), i])
    }
}
x
       [,1] [,2] [,3] [,4] [,5]
 [1,]    1   31   61   91  121
 [2,]    2   32   62   92  122
 [3,]    3   33   63   93  123
 [4,]    4   34   64   94  124
 [5,]    5   35   65   95  125
 [6,]    6   36   66   96  126
 [7,]    7   37   67   97  127
 [8,]    8   38   68   98  128
 [9,]    9   39   69   99  129
[10,]   10   40   70  100  130
[11,]   11   41   71  101  131
[12,]   12   42   72  102  132
[13,]   13   43   73  103  133
[14,]   14   44   74  104  134
[15,]   15   45   75  105  135
[16,]   16   46   76  106  136
[17,]   17   47   77  107  137
[18,]   18   48   78  108  138
[19,]   19   49   79  109  139
[20,]   20   50   80  110  140
[21,]   21   51   81  111  141
[22,]   22   52   82  112  142
[23,]   23   53   83  113  143
[24,]   24   54   84  114  144
[25,]   25   55   85  115  145
[26,]   26   56   86  116  146
[27,]   27   57   87  117  147
[28,]   28   58   88  118  148
[29,]   29   59   89  119  149
[30,]   30   60   90  120  150

z
      [,1] [,2] [,3] [,4] [,5]
 [1,]   55  355  655  955 1255
 [2,]  155  455  755 1055 1355
 [3,]  255  555  855 1155 1455

我嘗試過的代碼的Rcpp如下。

#include <Rcpp.h> 
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector mySum(NumericMatrix x) {

    int ncol = x.ncol();
    int nrow = x.nrow();
    int outRow = nrow / 10;
    int i;
    int j;
    int k;
    Rcpp::NumericMatrix z(outRow, ncol);

    for (i = 0; i < ncol; i++) {
        for (j = 0; j < outRow; j++) {
        k = j * 10;
        Rcpp::SubMatrix<REALSXP> sm = x(Range(k, k + 9), i);
        Rcpp::NumericMatrix m(sm);
        double s = Rcpp::sum(m);
        z(j, i) = s;
        }
    }
  return z;
}

但是,由於錯誤,它不會移動。 請告訴我解決方案。

test.cpp: In function 'Rcpp::NumericVector mySum(Rcpp::NumericMatrix)':
test.cpp:18:59: error: no match for call to '(Rcpp::NumericMatrix {aka Rcpp::Matrix<14>}) (Rcpp::Range, int&)'

實際上,在基礎R中有一個完全矢量化的函數,稱為rowsum ,可以非常有效地按組求和(請注意,R並不總是很慢,它主要取決於您的使用方式)。

x <- matrix(1:150, ncol = 5)
rowsum.default(x, cumsum(seq_len(nrow(x)) %% 10L == 1L), reorder = FALSE)
#   [,1] [,2] [,3] [,4] [,5]
# 1   55  355  655  955 1255
# 2  155  455  755 1055 1355
# 3  255  555  855 1155 1455

Rcpp版本慢,但是在我的系統上,具有5列的20MM行矩陣在不到3秒的時間內運行

x <- matrix(seq_len(1e8), ncol = 5)
dim(x)
## [1] 20000000        5
system.time(mySum(x))
# user  system elapsed 
# 0.72    0.24    0.96 
system.time(rowsum.default(x, cumsum(seq_len(nrow(x)) %% 10L == 1L), reorder = FALSE))
# user  system elapsed 
# 2.77    0.15    2.93 

編輯:根據您的評論,在測試實際數據集時, rowsum執行速度甚至比Rcpp版本更快

x <- matrix(seq_len(62400*4100), ncol = 4100)
dim(x)
## [1] 62400  4100
system.time(mySum(x))
# user  system elapsed 
# 1.53    1.03    2.57 
system.time(rowsum.default(x, cumsum(seq_len(nrow(x)) %% 10L == 1L), reorder = FALSE))
# user  system elapsed 
# 1.48    0.00    1.50 

在處理矩陣時,我更喜歡使用RcppArmadillo ,原因之一是因為文檔非常好( http://arma.sourceforge.net/docs.html#accu )。 我略微重寫了您的代碼,並且看起來工作正常:

library(RcppArmadillo)
library(Rcpp)

cppFunction("
NumericMatrix mySum(arma::mat x) {

    int ncol = x.n_cols;
    int nrow = x.n_rows;
    int outRow = nrow / 10;
    int i, j, k;
    NumericMatrix z(outRow, ncol);

    for (i = 0; i < ncol; i++) {
        for (j = 0; j < outRow; j++) {
            k = j * 10;
            arma::mat sm = x(arma::span(k, k+9), i);
            z(j, i) = arma::accu(sm);
        }
    }
    return z;
}
", depends = "RcppArmadillo")

x <- matrix(1:150, ncol = 5)
mySum(x)
     [,1] [,2] [,3] [,4] [,5]
[1,]   55  355  655  955 1255
[2,]  155  455  755 1055 1355
[3,]  255  555  855 1155 1455

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM