如何用另一个矩阵的值替换 C++ 中矩阵的元素(使用 Rcpp)?
How to replace elements of a matrix in C++ with values from another matrix (using 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)
如果原来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] <- 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)
欢迎任何改进。理想情况下,我希望将第一列保留为零而不是第 0 列。有什么想法吗?
我认为 Rcpp subMatrix 不允许以这种方式进行分配。
看看使用 RcppArmadillo 和 Armadillo submatrix views
#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)
*/
> 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
我有一个使用 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] <- 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)
欢迎任何改进。理想情况下,我希望将第一列保留为零而不是第 0 列。有什么想法吗?
我认为 Rcpp subMatrix 不允许以这种方式进行分配。
看看使用 RcppArmadillo 和 Armadillo submatrix views
#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)
*/
> 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