从Rarmadillo中的矩阵子集中获取一个元素

时间:2018-06-04 19:45:41

标签: r rcpp armadillo

我有一个大型矩阵。我正试图通过动态改变权重从中抽样。由于它被迫在R中使用循环,我试图在Rcpp中实现它,因此它有可能运行得更快一点。经过一些实验,我想我已经找到了如何随机获取正确权重的索引。

诀窍在于,我只是在任何给定时间从列子集中进行采样(如果在C中效率更高,则可以更改为行 - 矩阵实际上是对称的)。我的索引仅为此列的子集定义。在R中,我会按照

的方式做点什么
large_matrix[, columns_of_interest][index]

这很好用。我如何使用Rcpp / Armadillo进行等效操作?我的猜测

cppFunction("arma::vec element_from_subset(arma::mat D, arma::uvec i, arma::uvec columns) {
  # arma::mat D_subset = D.cols(columns);
  return D.cols(columns).elem(i);

  }", depends = "RcppArmadillo")

无法编译(并且.at而不是.elem也不起作用,标准的R技巧也没有在paranthesis中包围。

这确实有效,但我正在努力避免:

cppFunction("arma::vec element_from_subset(arma::mat D, arma::uvec i, arma::uvec columns) {
  arma::mat D_subset = D.cols(columns);
  return D_subset.elem(i);

  }", depends = "RcppArmadillo")

有没有办法在不需要保存D.cols(columns)的情况下实现这一目标?

1 个答案:

答案 0 :(得分:0)

简短回答:不。

但问题是错误的。想想这里发生的事情:

(M <- matrix(1:9, 3, 3)) 
#>      [,1] [,2] [,3]
#> [1,]    1    4    7
#> [2,]    2    5    8
#> [3,]    3    6    9

columns_of_interest = 1:2
M[, columns_of_interest] 
#>      [,1] [,2]
#> [1,]    1    4
#> [2,]    2    5
#> [3,]    3    6 

从这里开始,如果index为1,那么我们得到:

index = 1
M[, columns_of_interest][index]
#> 1

因此,从本质上讲,真正发生的是(i,j)的入门级子集。因此,您应该使用:

Rcpp::cppFunction("double element_from_subset(arma::mat D, int i, int j) { 
                  return D(i, j);
                  }", depends = "RcppArmadillo")
element_from_subset(M, 0, 0)
#> [1] 1

我是根据发布的 R C ++ 代码说的,例如 R 给出1个值, C ++ 的返回类型只允许一个值。

显示OP发布的代码没有错误。编译的初始错误将表明在Rcpp类中使用arma对象存在问题。如果我们更正类型,例如将Rcpp::IntegerVector替换为arma适当类型的arma::ivecarma::uvec,然后编译会产生更具信息性的错误消息。

更正代码:

Rcpp::cppFunction("double element_from_subset(arma::mat D, int i, arma::uvec columns) { 
  return D.cols(columns).elem(i);
  }", depends = "RcppArmadillo")

错误讯息:

file6cf4cef8267.cpp:10:26: error: no member named 'elem' in 'arma::subview_elem2<double, arma::Mat<unsigned int>, arma::Mat<unsigned int> >'
  return D.cols(columns).elem(i);
         ~~~~~~~~~~~~~~~ ^
1 error generated.
make: *** [file6cf4cef8267.o] Error 1

因此,无法子集通过从armadillo对象获取子集而创建的子视图

您可能想要了解Armadillo的一些子集功能。他们非常有帮助。

免责声明:我提供或撰写的第一个和第二个链接。