【问题标题】:R Rcpp big.matrix accessionR Rcpp big.matrix 加入
【发布时间】:2014-10-30 14:45:07
【问题描述】:

我正在尝试在 R 中为 big.matrix 对象实现一些基本的 C++ 代码。我正在使用 Rcpp 包,阅读了演示 here,甚至应用了我在 rcpp-devel list 上找到的另一个简单函数:

#include "bigmemory/BigMatrix.h"
#include "bigmemory/MatrixAccessor.hpp"
#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
void fun(SEXP A) {
    Rcpp::XPtr<BigMatrix> bigMat(A);
    MatrixAccessor<int> Am(*bigMat);

    int nrows = bigMat->nrow();
    int ncolumns = bigMat->ncol();
    for (int j = 0; j < ncolumns; j++){
      for (int i = 1; i < nrows; i++){
                Am[j][i] = Am[j][i] + Am[j][i-1];
            }
    }
    return;
}

// [[Rcpp::export]]
void BigTranspose(SEXP A)
{
    Rcpp::XPtr<BigMatrix> pMat(A);
    MatrixAccessor<int> mat(*pMat);

    int r = pMat->nrow();
    int c = pMat->ncol();

    for(int i=0; i<r; ++i)
      for(int j=0; j<c; ++j)
        std::swap(mat[j][i], mat[i][j]);

    return;
}

这个fun 函数工作得很好,修改了 big.matrix 对象。

a <- matrix(seq(25), 5,5)
> a
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25
> fun(b@address)
> head(b)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    3   13   23   33   43
[3,]    6   21   36   51   66
[4,]   10   30   50   70   90
[5,]   15   40   65   90  115

但是,当我尝试一个简单的方阵转置函数时,矩阵不会被修改。为什么fun 函数可以工作,而我的“BigTranspose”却不行?

a <- matrix(seq(25), 5,5)
> a
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25
b <- as.big.matrix(a)
BigTranspose(b@address)
> head(b)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25

【问题讨论】:

    标签: c++ r rcpp r-bigmemory


    【解决方案1】:

    问题在于您的转置算法;您正在遍历所有行和列,因此您的 swaps 正在被重新交换。您可以通过将j 的下索引设置为j = i+1 而不是j = 0 来解决此问题:

    #include "bigmemory/BigMatrix.h"
    #include "bigmemory/MatrixAccessor.hpp"
    #include <Rcpp.h>
    // [[Rcpp::depends(BH, bigmemory)]]
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    void BigTranspose(SEXP A)
    {
        Rcpp::XPtr<BigMatrix> pMat(A);
        MatrixAccessor<int> mat(*pMat);
    
        int r = pMat->nrow();
        int c = pMat->ncol();
    
        for(int i=0; i<r; i++){
          for(int j=0; j<c; j++){
            std::swap(mat[j][i], mat[i][j]);
          }
        }
        return;
    }
    
    // [[Rcpp::export]]
    void BigTranspose2(SEXP A)
    {
        Rcpp::XPtr<BigMatrix> pMat(A);
        MatrixAccessor<int> mat(*pMat);
    
        int r = pMat->nrow();
        int c = pMat->ncol();
    
        for(int i=0; i<r; i++){
          for(int j=(i+1); j<c; j++){
            std::swap(mat[j][i], mat[i][j]);
          }
        }
        return;
    }
    
    /*** R
    ##
    b1 <- as.big.matrix(a)
    head(b1)
    ##
    BigTranspose(b1@address)
    head(b1)
    ##
    ##
    b2 <- as.big.matrix(a)
    head(b2)
    ##
    BigTranspose2(b2@address)
    head(b2)
    ##
    ##
    M <- matrix(1:25,ncol=5)
    t(M)
    ##
    */
    

    通过比较BigTranspose2t(M) 的输出,您可以看到第二个版本正常工作,其中Mmatrix 等效于b1b2

    > Rcpp::sourceCpp('bigMatTranspose.cpp')
    
    > b1 <- as.big.matrix(a)
    
    > head(b1)
         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    6   11   16   21
    [2,]    2    7   12   17   22
    [3,]    3    8   13   18   23
    [4,]    4    9   14   19   24
    [5,]    5   10   15   20   25
    
    > ##
    > BigTranspose(b1@address)
    
    > head(b1)
         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    6   11   16   21
    [2,]    2    7   12   17   22
    [3,]    3    8   13   18   23
    [4,]    4    9   14   19   24
    [5,]    5   10   15   20   25
    
    > ##
    > ##
    > b2 <- as.big.matrix(a)
    
    > head(b2)
         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    6   11   16   21
    [2,]    2    7   12   17   22
    [3,]    3    8   13   18   23
    [4,]    4    9   14   19   24
    [5,]    5   10   15   20   25
    
    > ##
    > BigTranspose2(b2@address)
    
    > head(b2)
         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    2    3    4    5
    [2,]    6    7    8    9   10
    [3,]   11   12   13   14   15
    [4,]   16   17   18   19   20
    [5,]   21   22   23   24   25
    
    > ##
    > ##
    > M <- matrix(1:25,ncol=5)
    
    > t(M)
         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    2    3    4    5
    [2,]    6    7    8    9   10
    [3,]   11   12   13   14   15
    [4,]   16   17   18   19   20
    [5,]   21   22   23   24   25
    

    请注意,这将适用于方阵,但您必须对其进行一些修改才能使用任意维度的矩阵。

    【讨论】:

    • 果然,这是一个简单的疏忽。谢谢你,你也是正确的,任意维度都需要进一步编码。
    猜你喜欢
    • 2012-01-09
    • 1970-01-01
    • 2015-12-28
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多