从 Rarmadillo 中的矩阵子集中获取元素
get an element from a subset of a matrix in Rarmadillo
我有一个很大的矩阵。我正在尝试通过动态变化的权重从中进行采样。由于它被迫在 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 技巧也不起作用。
这确实有效,但这是我要避免的:
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)
?
简答:否
但是,问题的表述不正确。想想这里发生了什么:
(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++ 有一个 return 类型只允许一个值。
OP 发布的代码显示没有错误。编译后的初始错误将表明在 arma
class 中使用 Rcpp
对象存在问题。如果我们更正类型,例如将 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
因此,无法 subset a subview 是通过 subset 来自犰狳对象。
您可能想要阅读 Armadillo 的一些子集功能。他们非常有帮助。
- Rcpp 库:http://gallery.rcpp.org/articles/armadillo-subsetting
- 将 R 代码转换为 Armadillo 的指南:http://thecoatlessprofessor.com/programming/common-operations-with-rcpparmadillo/
- 犰狳特定文档
免责声明:我贡献或编写的第一个和第二个链接。
我有一个很大的矩阵。我正在尝试通过动态变化的权重从中进行采样。由于它被迫在 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 技巧也不起作用。
这确实有效,但这是我要避免的:
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)
?
简答:否
但是,问题的表述不正确。想想这里发生了什么:
(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++ 有一个 return 类型只允许一个值。
OP 发布的代码显示没有错误。编译后的初始错误将表明在 arma
class 中使用 Rcpp
对象存在问题。如果我们更正类型,例如将 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
因此,无法 subset a subview 是通过 subset 来自犰狳对象。
您可能想要阅读 Armadillo 的一些子集功能。他们非常有帮助。
- Rcpp 库:http://gallery.rcpp.org/articles/armadillo-subsetting
- 将 R 代码转换为 Armadillo 的指南:http://thecoatlessprofessor.com/programming/common-operations-with-rcpparmadillo/
- 犰狳特定文档
免责声明:我贡献或编写的第一个和第二个链接。