[英]How to scale a NumericMatrix in-place with Rcpp?
This is what I'm doing now 这就是我现在正在做的
library(Rcpp)
A <- diag(c(1.0, 2.0, 3.0))
rownames(A) <- c('X', 'Y', 'Z')
colnames(A) <- c('A', 'B', 'C')
cppFunction('
void scaleMatrix(NumericMatrix& A, double x) {
A = A * x;
}')
Unfortunately It doesn't work :( 不幸的是,它不起作用:(
> A
A B C
X 1 0 0
Y 0 2 0
Z 0 0 3
> scaleMatrix(A, 2)
> A
A B C
X 1 0 0
Y 0 2 0
Z 0 0 3
I learned from Rcpp FAQ, Question 5.1 that Rcpp should be able to change the object I passed by value. 我从Rcpp常见问题解答5.1中获悉,Rcpp应该能够更改按值传递的对象。 Stealing an example from Dirk's answer to my previous question: 从Dirk回答我以前的问题中窃取一个例子:
> library(Rcpp)
> cppFunction("void inplaceMod(NumericVector x) { x = x * 2; }")
> x <- as.numeric(1:5)
> inplaceMod(x)
> x
[1] 2 4 6 8 10
I'm confused: it is possible to modify a NumericVector
in-place, but not a NumericMatrix
? 我很困惑:可以就地修改NumericVector
,但不能修改NumericMatrix
吗?
You can preserve the row and column names by using NumericVector
instead of NumericMatrix
, keeping in mind that a matrix in R is just a vector with attached dimensions. 您可以使用NumericVector
而不是NumericMatrix
来保留行名和列名,请记住R中的矩阵只是具有附NumericMatrix
的向量。 You can do this switch either when going from R to C++ ( scaleVector
below) or within C++ ( scaleMatrix
below taken from a now deleted answer by @Roland ): 您可以在从R到C ++时(以下scaleVector
)或在C ++内(以下scaleMatrix
取自scaleMatrix
现已删除的答案)进行此切换 :
library(Rcpp)
cppFunction('
NumericVector scaleVector(NumericVector& A, double x) {
A = A * x;
return A;
}')
cppFunction('
NumericMatrix scaleMatrix(NumericMatrix& A, double x) {
NumericVector B = A;
B = B * x;
return A;
}')
If one applies these two function to your matrix, the row and column names are preserved. 如果将这两个函数应用于矩阵,则保留行名和列名。 However, the matrix is not changed in place: 但是,矩阵未更改到位:
A <- diag(1:3)
rownames(A) <- c('X', 'Y', 'Z')
colnames(A) <- c('A', 'B', 'C')
scaleMatrix(A, 2)
#> A B C
#> X 2 0 0
#> Y 0 4 0
#> Z 0 0 6
scaleVector(A, 2)
#> A B C
#> X 2 0 0
#> Y 0 4 0
#> Z 0 0 6
A
#> A B C
#> X 1 0 0
#> Y 0 2 0
#> Z 0 0 3
The reason for that is that diag(1:3)
is actually an integer matrix, so a copy is made when you transfer it to a numeric matrix (or vector): 原因是diag(1:3)
实际上是一个整数矩阵,因此当您将其传输到数值矩阵(或向量)时会生成一个副本:
is.integer(A)
#> [1] TRUE
If one uses a numeric matrix to begin with, modification is done in place: 如果使用数字矩阵作为开始,则会进行适当的修改:
A <- diag(c(1.0, 2.0, 3.0))
rownames(A) <- c('X', 'Y', 'Z')
colnames(A) <- c('A', 'B', 'C')
scaleMatrix(A, 2)
#> A B C
#> X 2 0 0
#> Y 0 4 0
#> Z 0 0 6
scaleVector(A, 2)
#> A B C
#> X 4 0 0
#> Y 0 8 0
#> Z 0 0 12
A
#> A B C
#> X 4 0 0
#> Y 0 8 0
#> Z 0 0 12
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.