c++ - 将大矩阵/数组转换为 Armadillo 矩阵

标签 c++ rcpp armadillo

我有一个 big.matrix我想转换到 arma::Mat这样我就可以使用 Armadillo 的线性代数功能。

但是,我似乎无法让类型转换正常工作。

据我从阅读中收集到的信息,两者都以列主要格式在内部存储,并且 big.matrix 的实际矩阵组件只是一个 <T> 类型的指针( char/short/int/double )

以下代码可以编译,但转换为 arma::Mat不起作用,在遍历转换矩阵时出现段错误。

#include <RcppArmadillo.h>
using namespace Rcpp;

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

template <typename T>
void armacast(const arma::Mat<T>& M) {
  // This segfaults
  for (int j = 0; j < 2; j++) {
    for (int i = 0; i < 2; i++) {
      std::cout << M.at(j, i) << std::endl;
    }   
  }
  std::cout << "Success!" << std::endl;                                                                                                                                                                                                       
}

// [[Rcpp::export]]
void armacast(SEXP pDat) {
  XPtr<BigMatrix> xpDat(pDat);

  if (xpDat->matrix_type() == 8) {
    // I can iterate over this *mat and get sensible output.
    double *mat = (double *)xpDat->matrix();
    for (int j = 0; j < 2; j++) {
      for (int i = 0; i < 2; i++) {
        std::cout << *mat + 2 * (j + 0) + i << std::endl;
      }   
    }
    armacast((const arma::Mat<double> &)mat);
  } else {
    std::cout << "Not implemented yet!" << std::endl;
  }
}

在 R 中:

library(Rcpp)
library(RcppArmadillo)
library(bigmemory)
sourceCpp("armacast.cpp")
m <- as.big.matrix(matrix(1:4, 2), type="double")
armacast(m@address)

最佳答案

好问题!我们可能会把它放到另一个 Rcpp Gallery 帖子中。

您可能忽略了一个重要细节。 Bigmemory 对象是外部的,因此我们让 R 不让它的内存管理受到干扰。 Armadillo 确实有构造函数(请阅读那里的文档和警告)所以首先 我们可以做到

arma::mat M( (double*) xpDat->matrix(), xpDat->nrow(), xpDat->ncol(), false);

我们使用指向矩阵数据的指针,以及行数和列数。完整版:

// [[Rcpp::export]]
void armacast(SEXP pDat) {
  XPtr<BigMatrix> xpDat(pDat);

  if (xpDat->matrix_type() == 8) {
    arma::mat M(mat, xpDat->nrow(), xpDat>-ncol(), false);
    M.print("Arma matrix M");
  } else {
    std::cout << "Not implemented yet!" << std::endl;
  }
}

它正确地调用了 Armadillo 的 print 方法:

R> armacast(m@address)
Arma matrix M
   1.0000   3.0000
   2.0000   4.0000
R> 

关于c++ - 将大矩阵/数组转换为 Armadillo 矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24933830/

相关文章:

C++ - 以特定方式对 vector 中的字符串进行排序

c++ - C++ 开源前端的选项

c++ - Boost Asio tcp::acceptor 访问冲突异常

c++ - 使用迭代器访问存储在 vector 中的类对象的方法。如何?

rcpp - 构建使用 RcppArmadillo、RcppEigen 并依赖于 Cpp11 插件的 R 包

r - 从距离矩阵创建 dist 对象的内存高效方法

Rcpp:将 SEXP 转换为 float / double

r - 在 Rcpp 中决定 NumericVector 和 arma::vec

c++ - 在 Armadillo 中将矩阵除以 vector

opencv - LibTorch C++和Eigen之间的数据传输