我可以使用 Rcpp 就地修改一行吗?
Can I modify a row in-place with Rcpp?
比如说,我想将矩阵的第一行增加一个。显而易见的方法是 A.row(0) = A.row(0) + 1;
,但它会创建一个新行而不是修改现有行,并且当矩阵很大时可能会导致一些性能问题。
从,我了解到我可以做一个点别名,但它只适用于整个矩阵,不适用于个别行。
library(Rcpp)
cppFunction('
void increaseFirstRow(NumericMatrix& A) {
NumericVector B = A.row(0);
B = B + 1;
}')
A <- diag(c(1.0, 2.0, 3.0))
increaseFirstRow(A)
输出如下所示。请注意,第一行没有更改。
> A
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 2 0
[3,] 0 0 3
这是 RcppArmadillo 中的一个简单解决方案,经过编辑后,在 Rcpp 本身中:
示例代码
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
void incRow(arma::mat& M) {
M.row(0) = M.row(0) + 1;
}
// [[Rcpp::export]]
void incRow2(Rcpp::NumericMatrix M) {
M(0,Rcpp::_) = M(0,Rcpp::_) + 1;
}
/*** R
A <- diag(c(1.0, 2.0, 3.0))
incRow(A)
A
incRow2(A)
A
*/
输出
R> Rcpp::sourceCpp("/tmp/armarow.cpp")
R> A <- diag(c(1.0, 2.0, 3.0))
R> incRow(A)
R> A
[,1] [,2] [,3]
[1,] 2 1 1
[2,] 0 2 0
[3,] 0 0 3
R> incRow2(A)
R> A
[,1] [,2] [,3]
[1,] 3 2 2
[2,] 0 2 0
[3,] 0 0 3
R>
根据上面的公式,我认为您想获得对矩阵特定部分的引用。以下跨矩阵类型工作:
*Matrix::Row = x( 0 , Rcpp::_); // first row
*Matrix::Column = x( Rcpp::_ , 0); // first column
*Matrix::Sub = x( Rcpp::Range(0, 1) , Rcpp::Range(2, 3)); // first 2 rows and 3 -4th column.
在你的情况下,那将是:
#include <Rcpp.h>
// [[Rcpp::export]]
void row_ref(Rcpp::NumericMatrix M) {
// Create a reference to the 1st row in M.
Rcpp::NumericMatrix::Row x = M.row(0);
// Increase the first row in M.
x = x + 10;
}
示例:
(A <- diag(c(1.0, 2.0, 3.0)))
# [,1] [,2] [,3]
# [1,] 1 0 0
# [2,] 0 2 0
# [3,] 0 0 3
row_ref(A)
A
# [,1] [,2] [,3]
# [1,] 11 10 10
# [2,] 0 2 0
# [3,] 0 0 3
比如说,我想将矩阵的第一行增加一个。显而易见的方法是 A.row(0) = A.row(0) + 1;
,但它会创建一个新行而不是修改现有行,并且当矩阵很大时可能会导致一些性能问题。
从
library(Rcpp)
cppFunction('
void increaseFirstRow(NumericMatrix& A) {
NumericVector B = A.row(0);
B = B + 1;
}')
A <- diag(c(1.0, 2.0, 3.0))
increaseFirstRow(A)
输出如下所示。请注意,第一行没有更改。
> A
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 2 0
[3,] 0 0 3
这是 RcppArmadillo 中的一个简单解决方案,经过编辑后,在 Rcpp 本身中:
示例代码
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
void incRow(arma::mat& M) {
M.row(0) = M.row(0) + 1;
}
// [[Rcpp::export]]
void incRow2(Rcpp::NumericMatrix M) {
M(0,Rcpp::_) = M(0,Rcpp::_) + 1;
}
/*** R
A <- diag(c(1.0, 2.0, 3.0))
incRow(A)
A
incRow2(A)
A
*/
输出
R> Rcpp::sourceCpp("/tmp/armarow.cpp")
R> A <- diag(c(1.0, 2.0, 3.0))
R> incRow(A)
R> A
[,1] [,2] [,3]
[1,] 2 1 1
[2,] 0 2 0
[3,] 0 0 3
R> incRow2(A)
R> A
[,1] [,2] [,3]
[1,] 3 2 2
[2,] 0 2 0
[3,] 0 0 3
R>
根据上面的公式,我认为您想获得对矩阵特定部分的引用。以下跨矩阵类型工作:
*Matrix::Row = x( 0 , Rcpp::_); // first row
*Matrix::Column = x( Rcpp::_ , 0); // first column
*Matrix::Sub = x( Rcpp::Range(0, 1) , Rcpp::Range(2, 3)); // first 2 rows and 3 -4th column.
在你的情况下,那将是:
#include <Rcpp.h>
// [[Rcpp::export]]
void row_ref(Rcpp::NumericMatrix M) {
// Create a reference to the 1st row in M.
Rcpp::NumericMatrix::Row x = M.row(0);
// Increase the first row in M.
x = x + 10;
}
示例:
(A <- diag(c(1.0, 2.0, 3.0)))
# [,1] [,2] [,3]
# [1,] 1 0 0
# [2,] 0 2 0
# [3,] 0 0 3
row_ref(A)
A
# [,1] [,2] [,3]
# [1,] 11 10 10
# [2,] 0 2 0
# [3,] 0 0 3