Yulong Niu

个人博客

Rcpp操作矩阵和向量集锦

Posted at — Jan 7, 2016

收集和记录Rcpp或者RcppArmadillo操作矩阵和向量。

1. Rcpp

2. RcppArmadillo

基本类型是matveccolvec)和rowvec

arma::mat TransferMatArma(Rcpp::NumericMatrix x, Rcpp::NumericVector y) {
    mat tx(x.begin(), x.nrow(), x.ncol(), false);
    vec ty(y.begin(), y.size(), false);
    return tx;
}

Rcpp::NumericVector TransferMatRcpp(arma::mat x, arma::vec y) {
    NumericMatrix tx(x.n_rows, x.n_cols, x.begin());
    NumericVector ty(y.begin(), y.end());
    return ty;
    
// 不要使用as<IntegerVector>(wrap(y)),会有内存泄露。
}
arma::mat TestMat(arma::mat M, double a) {

  M.for_each([a](mat::elem_type& val) {
      val = val > 0 ? val : a;
    });

  M.each_row([](rowvec& r) {
      r /= r.max();
    });

  return M;
}

3. bigmemory

bigmemory包提供了四种数据类型的矩阵,即double(默认)、integershortchar。对于big.matrix对象pMat,四种类型通过通过MatrixAccessor<double> macc(*pMat)MatrixAccessor<int> macc(*pMat)MatrixAccessor<short> macc(*pMat)MatrixAccessor<char> macc(*pMat)提取元素。pMat有三种属性nrow()ncol()matrix_type()可以使用。一下代码示例展示了将big.matrix转换为matrix

#include <Rcpp.h>
// [[Rcpp::depends(BH, bigmemory)]]
#include <bigmemory/MatrixAccessor.hpp>

#include <numeric>

using namespace Rcpp;


// [[Rcpp::export]]
Rcpp::NumericMatrix TestBigMat(XPtr<BigMatrix> pMat) {

  MatrixAccessor<int> macc(*pMat);

  int n = pMat->nrow();
  int m = pMat->ncol();

  NumericMatrix resMat(n, m);

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      resMat(i, j) = macc[j][i];
    }
  }

  return resMat;
}

注意事项:

同样,RcppArmadillo也能与bigmemory结合,例如:

#include <RcppArmadillo.h>
#include <bigmemory/MatrixAccessor.hpp>

#include <numeric>

// [[Rcpp::depends(RcppArmadillo, bigmemory)]]

using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
Rcpp::NumericMatrix TestBigMatArma(SEXP pMat) {

  XPtr<BigMatrix> xpMat(pMat);

  Mat<int> macc = Mat<int>((int *)xpMat->matrix(), xpMat->nrow(), xpMat->ncol(), false);

  int n = xpMat->nrow();
  int m = xpMat->ncol();

  NumericMatrix resMat(n, m);

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      resMat(i, j) = macc(i, j);
    }
  }

  return resMat;
}

参考网址

更新记录

2021年12月08日