我有一个大型矩阵。我正试图通过动态改变权重从中抽样。由于它被迫在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)
的情况下实现这一目标?
答案 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::ivec
或arma::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的一些子集功能。他们非常有帮助。
免责声明:我提供或撰写的第一个和第二个链接。