c++ - 如何使用 Rcpp 就地缩放 NumericMatrix?

标签 c++ r matrix rcpp syntactic-sugar

这就是我现在做的

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;
}')

不幸的是它不起作用:(

> 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 FAQ, Question 5.1中学到了Rcpp 应该能够更改我按值传递的对象。从 Dirk's answer 中窃取示例我之前的问题:

> 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

最佳答案

您可以使用 NumericVector 保留行名和列名而不是 NumericMatrix ,请记住,R 中的矩阵只是具有附加维度的 vector 。您可以在从 R 转到 C++ 时(下面的 scaleVector)或在 C++ 中(下面的 scaleMatrix 取自 @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;
}')

如果将这两个函数应用于您的矩阵,行和列名称将被保留。然而,矩阵并没有原地改变:

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矩阵(或 vector )时会生成一个拷贝:

is.integer(A)
#> [1] TRUE

如果一开始使用数字矩阵,则修改就地完成:

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

关于c++ - 如何使用 Rcpp 就地缩放 NumericMatrix?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57818049/

相关文章:

c++ - 实现 operator< 的最佳方式是什么?

r - 如何每个 session 只显示一次警告?

r - 通过两个数据帧和一个矩阵进行匹配和索引

c++ - 如何在 C++ 中对数组中的字母进行排序?

Python:检测和参数化图像矩阵中的简单矩形/高斯条纹图案

c++ - 没有STL和动态内存分配的成员函数类

c++ - 无法从 'const std::string [3]' 转换为 'std::string'

c++ - SetCapture 不起作用并返回 nullptr

html - 使用混合字符编码读取 R 中的文件

c++ - 在 C++ 中返回多个矩阵( Armadillo 库)