如何使用 Rcpp 就地缩放 NumericMatrix? [英] How to scale a NumericMatrix in-place with Rcpp?

查看:51
本文介绍了如何使用 Rcpp 就地缩放 NumericMatrix?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这就是我现在正在做的

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

我从 Rcpp 常见问题解答,问题 5.1 那 Rcpp 应该能够改变我通过值传递的对象.从 Dirk 的回答 中窃取我之前问题的示例:

I learned from Rcpp FAQ, Question 5.1 that Rcpp should be able to change the object I passed by value. Stealing an example from Dirk's answer to my previous question:

> library(Rcpp)
> cppFunction("void inplaceMod(NumericVector x) { x = x * 2; }")
> x <- as.numeric(1:5)
> inplaceMod(x)
> x
[1]  2  4  6  8 10

我很困惑:可以就地修改 NumericVector,但不能修改 NumericMatrix?

I'm confused: it is possible to modify a NumericVector in-place, but not a NumericMatrix?

推荐答案

您可以使用 NumericVector 而不是 NumericMatrix 来保留行和列名称,请记住R 中的矩阵只是一个带有附加维度的向量.您可以在从 R 转到 C++(下面的scaleVector)或在 C++ 中(下面的 scaleMatrix 取自 @Roland):

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. 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):

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

这样做的原因是 diag(1:3) 实际上是一个整数矩阵,所以当你把它转移到一个 numeric 矩阵(或向量):

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):

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

这篇关于如何使用 Rcpp 就地缩放 NumericMatrix?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆