使用RcppArmadillo submat()更新通过引用传递的Rcpp :: NumericMatrix

时间:2017-05-14 09:32:35

标签: c++ r pass-by-reference rcpp armadillo

关注此question,我试图了解如何有效地更新Rccp::NumericMatrix数据类型的子集。

我有以下情况:

  • Rcpp::NumericMatrix m 5 x 5需要更新行和列。
  • 将通过引用将其转换为void的函数(arma::mat返回类型)传递,并更新相应的submat()
  • 此时我不明白如何“应用”将函数内部发生的更改传递给传递给函数的m矩阵。

代码如下所示:

#include <iostream>
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]


// [[Rcpp::export]]
void updateMatrix(const Rcpp::NumericMatrix &m)
{
    std::cout << m << std::endl;

    Rcpp::as<arma::mat>(m).submat(0, 0, 3, 3) = Rcpp::as<arma::mat>(m).submat(0, 0, 3, 3) + 1;

    std::cout << m << std::endl;
}

要从R运行它,我使用:

m = matrix(0, 5, 5)

updateMatrix(m)

结果是:

> updateMatrix(m)
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000

0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000

这是我第一次使用RcppRcppArmadillo而且它们绝对令人惊叹。感谢您对此方案的任何帮助。

1 个答案:

答案 0 :(得分:3)

updateMatrix中作业的左侧会创建一个在分配后被丢弃的临时文件。因此,m根本没有变化。代码无法按预期工作,因为这意味着m的类型会发生变化。看下面:

#include <typeinfo>
#include <iostream>
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]


// [[Rcpp::export]]
void updateMatrix(const Rcpp::NumericMatrix &m)
{
  std::cout << m << std::endl;

  std::cout << typeid(m).name() << std::endl;

  arma::mat m2 = Rcpp::as<arma::mat>(m);

  std::cout << typeid(m2).name() << std::endl;

  m2.submat(0, 0, 3, 3) = Rcpp::as<arma::mat>(m).submat(0, 0, 3, 3) + 1;

  std::cout << m2 << std::endl;
}

运行此代码会给出:

> m = matrix(0, 5, 5)
> updateMatrix(m)
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000

N4Rcpp6MatrixILi14ENS_15PreserveStorageEEE
N4arma3MatIdEE
   1.0000   1.0000   1.0000   1.0000        0
   1.0000   1.0000   1.0000   1.0000        0
   1.0000   1.0000   1.0000   1.0000        0
   1.0000   1.0000   1.0000   1.0000        0
        0        0        0        0        0