【发布时间】:2015-12-08 16:55:01
【问题描述】:
我有一个使用 Rcpp 的小型 C++ 函数,它将一个矩阵的元素替换为另一个矩阵的值。它适用于单个单元格或如下列:
cppFunction('NumericMatrix changeC(NumericMatrix one, NumericMatrix two) {
NumericMatrix a = one;
NumericMatrix b = two;
b(_,1) = a(_,1);
return b;
}')
changeC(g,f)
如果原来f是下面的矩阵:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 6 6 6 6 6 6
[2,] 6 6 6 6 6 6
[3,] 6 6 6 6 6 6
[4,] 6 6 6 6 6 6
[5,] 6 6 6 6 6 6
[6,] 6 6 6 6 6 6
和 g 看起来像下面的矩阵:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 5 5 5 5 5 5
[2,] 5 5 5 5 5 5
[3,] 5 5 5 5 5 5
[4,] 5 5 5 5 5 5
[5,] 5 5 5 5 5 5
[6,] 5 5 5 5 5 5
当我运行 changeC(g,f) 时,我最终得到(如预期的那样):
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 6 5 6 6 6 6
[2,] 6 5 6 6 6 6
[3,] 6 5 6 6 6 6
[4,] 6 5 6 6 6 6
[5,] 6 5 6 6 6 6
[6,] 6 5 6 6 6 6
但我真正想做的是将一个矩阵的子集替换为来自不同位置的另一个矩阵的子集(例如,一个矩阵 (3*3) 的第 1 到 3 行、第 1 到 3 列到第 3 行到6,其他矩阵的第 3 到 6 列(也是 3*3)。我试过了:
cppFunction('NumericMatrix changeC(NumericMatrix one, NumericMatrix two) {
NumericMatrix a = one;
NumericMatrix b = two;
b( Range(0,2), Range(0,2)) = a( Range(3,5), Range(3,5));
return b;
}')
但这不会编译。虽然:
cppFunction('NumericMatrix changeC(NumericMatrix one, NumericMatrix two) {
NumericMatrix a = one;
NumericMatrix b = two;
b = a( Range(3,5), Range(3,5));
return b;
}')
编译。我究竟做错了什么?在 R 中,我会执行以下操作:
f[1:3,1:3]
提前感谢您的帮助。
编辑 1
在玩了一会儿之后,我设法让我的矩阵向东和向西移动(我认为它类似于向北和向南 - 可能是东北、西北的两步方法??):
func <- 'NumericMatrix eastC(NumericMatrix a) {
int acoln=a.ncol();
NumericMatrix out(a.nrow(),a.ncol()) ;
for (int j = 0;j < acoln;j++) {
if (j > 0) {
out(_,j) = a(_,j-1);
} else {
out(_,j) = a(_,0);
}
}
return out ;
}'
cppFunction(func)
欢迎任何改进。理想情况下,我希望将第一列保留为零而不是第 0 列。有什么想法吗?
【问题讨论】:
-
如果你用几个嵌套的 for 循环来做这件事会发生什么?
-
你能演示一下吗 - 我对 C++ 很陌生?
-
在从 R 迁移到 C++ 时,您必须执行许多 R 本身会执行的步骤。 IE-R 是矢量化的,C++ 不是。正如 42 条注释,通过两个循环(行、列)执行此操作是一种选择。另一种选择是在 RcppEigen 中使用 block operations
-
另外,您应该通过引用传递并在不变的矩阵上使用
const(在您的第一个示例中为one) -
Alex,42 岁,我非常想了解您在说什么,但不知道该怎么做。请您发布答案吗?