Rcpp NumericMatrix在左/右乘以标量时的奇怪行为

  • 本文关键字:标量 在左 NumericMatrix Rcpp rcpp
  • 更新时间 :
  • 英文 :


谁能解释以下行为?

当声明一个新的NumericMatrix时,y,作为原始矩阵,x乘以标量,c,标量/矩阵乘法的顺序很重要。如果我将左边的标量和右边的矩阵相乘(例如NumericMatrix y = c * x;(,然后我得到奇怪的行为。原来的矩阵,x,被改变了!

但是,如果我将原始矩阵放在左侧并将标量乘以右侧(例如NumericMatrix y = x * c;(,x保持不变。

这似乎不会影响其他数据类型。我已经用intNumericVector进行了测试。

示例:使用NumericMatrix时出现问题

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix testfun(NumericMatrix x) {
NumericMatrix y(x.rows(), x.cols());
y = x * 2;
std::cout << x; // x is unmodified
y = 2 * x; 
std::cout << x; // x is now modified
return x;
}

/*** R
x <- matrix(2, nrow = 3, ncol = 3)
print(x)
y <- testfun(x = x)
print(y)
print(x)
*/

输出如下。

> x <- matrix(2, nrow = 3, ncol = 3)
> print(x)
[,1] [,2] [,3]
[1,]    2    2    2
[2,]    2    2    2
[3,]    2    2    2
> y <- testfun(x = x)
2.00000 2.00000 2.00000
2.00000 2.00000 2.00000
2.00000 2.00000 2.00000
4.00000 4.00000 4.00000
4.00000 4.00000 4.00000
4.00000 4.00000 4.00000
> print(y)
[,1] [,2] [,3]
[1,]    4    4    4
[2,]    4    4    4
[3,]    4    4    4
> print(x)
[,1] [,2] [,3]
[1,]    4    4    4
[2,]    4    4    4
[3,]    4    4    4

这是我的会话信息

> sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Catalina 10.15.1
Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     
loaded via a namespace (and not attached):
[1] compiler_3.6.1            tools_3.6.1               RcppArmadillo_0.9.800.1.0
[4] Rcpp_1.0.2                RcppProgress_0.4.1        packrat_0.5.0            
[7] RcppParallel_4.4.4  

.

这个问题太长了,因为张贴了,隐藏了它的观点。我们不需要第二个和第三个例子。 我们所需要的只是这段代码:

法典

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix testfun(NumericMatrix x) {
NumericMatrix y(x.rows(), x.cols());
y = x * 2;
std::cout << x; // x is unmodified
y = 2 * x;      // contrast with x * 2
std::cout << x; // x is now modified
return x;
}
/*** R
print(x <- matrix(2, nrow = 2, ncol = 2))
print(y <- testfun(x = x))
print(x)
*/

输出

R> Rcpp::sourceCpp("~/git/stackoverflow/59515517/question.cpp")
R> print(x <- matrix(2, nrow = 2, ncol = 2))
[,1] [,2]
[1,]    2    2
[2,]    2    2
R> print(y <- testfun(x = x))
2.00000 2.00000
2.00000 2.00000
4.00000 4.00000
4.00000 4.00000
[,1] [,2]
[1,]    4    4
[2,]    4    4
R> print(x)
[,1] [,2]
[1,]    4    4
[2,]    4    4
R> 

问题

x * 2的行为与2 * x不同。 后者有副作用。 这可能是一个错误,

更大的问题

用 Rcpp 做矩阵代数并没有真正的意义。实施是初级和不完整的。 如果你想做"数学",使用RcppArmadillo或RcppEigen。

阿玛实施

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat testfun(arma::mat x) {
arma::mat y(x.n_rows, x.n_cols);
y = x * 2;
std::cout << x; // x is unmodified
y = 2 * x;      // contrast with x * 2
std::cout << x; // x is now modified
return x;
}
/*** R
print(x <- matrix(2, nrow = 2, ncol = 2))
print(y <- testfun(x = x))
print(x)
*/

阿玛输出

R> Rcpp::sourceCpp("~/git/stackoverflow/59515517/answer.cpp")
R> print(x <- matrix(2, nrow = 2, ncol = 2))
[,1] [,2]
[1,]    2    2
[2,]    2    2
R> print(y <- testfun(x = x))
2.0000   2.0000
2.0000   2.0000
2.0000   2.0000
2.0000   2.0000
[,1] [,2]
[1,]    2    2
[2,]    2    2
R> print(x)
[,1] [,2]
[1,]    2    2
[2,]    2    2
R> 

我会看看我是否可以找到你在这里找到的 Rcpp 错误。

编辑:这是一个错误,我还不太明白,但我在代码起源的问题中添加了一些东西:https://github.com/RcppCore/Rcpp/issues/365

编辑 2:修复程序现已掌握。 感谢 KK 的公关,感谢其他人在评论中暗示这背后可能是什么,尤其是 Ralf 让我们所有人都尝试修复。

最新更新