如何用来自另一个矩阵的值(使用 Rcpp)替换 C++ 中矩阵的元素?

use*_*667 5 c++ r matrix rcpp

我有一个使用 Rcpp 的小型 C++ 函数,它用另一个矩阵的值替换一个矩阵的元素。它适用于单个单元格或如下列:

cppFunction('NumericMatrix changeC(NumericMatrix one, NumericMatrix two) {
NumericMatrix a = one;
NumericMatrix b = two;
b(_,1) = a(_,1);
return b;
}')

changeC(g,f)
Run Code Online (Sandbox Code Playgroud)

如果最初 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
Run Code Online (Sandbox Code Playgroud)

和 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
Run Code Online (Sandbox Code Playgroud)

当我运行 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
Run Code Online (Sandbox Code Playgroud)

但是我真正想要做的是用来自不同地方的另一个矩阵的子集替换一个矩阵的子集(例如,第 1 到 3 行,一个矩阵的第 1 到 3 列(3*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;
}')
Run Code Online (Sandbox Code Playgroud)

但这不能编译。虽然:

cppFunction('NumericMatrix changeC(NumericMatrix one, NumericMatrix two) {
NumericMatrix a = one;
NumericMatrix b = two;
b = a( Range(3,5), Range(3,5));
return b;
}')
Run Code Online (Sandbox Code Playgroud)

确实编译。我究竟做错了什么?在 RI 中将执行以下操作:

f[1:3,1:3] <- g[4:6,4:6] (但是对于非常大的矩阵(因此是 Rcpp),这相对较慢)。

提前感谢您的任何帮助。

编辑 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)
Run Code Online (Sandbox Code Playgroud)

欢迎任何改进。理想情况下,我希望将第一列保留为零而不是第 0 列。有任何想法吗?

The*_*ell 6

我认为 Rcpp subMatrix 不允许以这种方式进行分配。

看看使用 RcppArmadillo 和Armadillo 子矩阵视图

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

using namespace arma;

// [[Rcpp::export]]
mat example( mat m1, mat m2) {
  m1.submat( 0,0, 2,2) = m2.submat( 3,3, 5,5 );
  return m1;
}

/*** R
m1 <- matrix(1,6,6)
m2 <- matrix(-1,6,6)
example(m1, m2)
*/
Run Code Online (Sandbox Code Playgroud)
> m1 <- matrix(1,6,6)

> m2 <- matrix(-1,6,6)

> example(m1, m2)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   -1   -1   -1    1    1    1
[2,]   -1   -1   -1    1    1    1
[3,]   -1   -1   -1    1    1    1
[4,]    1    1    1    1    1    1
[5,]    1    1    1    1    1    1
[6,]    1    1    1    1    1    1
Run Code Online (Sandbox Code Playgroud)

  • 我应该更快,正如亚历克斯在评论中所说;使用按引用传递(不要忘记 const)。 (2认同)