最近被问到的一个问题让我相信语法糖*
by Rcpp
不按预期工作。在链接的问题中,用户试图将矩阵乘以标量。
R code
这就是我们想要实现的目标Rcpp
,但现在简单地说R
:
> m <- matrix(0:3, 2, 2)
> m * 3
[,1] [,2]
[1,] 0 6
[2,] 3 9
RCPP代码
我创建了一些最小的示例来演示上述问题以及一些意外的行为。首先请注意,我一直在使用List
作为返回类型,因为它不需要我提前声明适当的类型:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List FooMat() {
// Create a fill a 2x2 matrix
NumericMatrix tmp(2,2);
for (int i = 0; i < 4; i++) {
tmp[i] = i;
}
return List::create(tmp);
}
// [[Rcpp::export]]
List FooMat2() {
// Create a fill a 2x2 matrix
NumericMatrix tmp(2,2);
for (int i = 0; i < 4; i++) {
tmp[i] = i;
}
NumericVector x(1);
x[1] = 3;
return List::create(tmp * x);
}
// [[Rcpp::export]]
List FooMat3() {
// Create a fill a 2x2 matrix
NumericMatrix tmp(2,2);
for (int i = 0; i < 4; i++) {
tmp[i] = i;
}
NumericVector x(1);
x[1] = 3;
return List::create(tmp * x[1]);
}
// [[Rcpp::export]]
List FooMat4() {
// Create a fill a 2x2 matrix
NumericMatrix tmp(2,2);
for (int i = 0; i < 4; i++) {
tmp[i] = i;
}
return List::create(tmp * 3);
}
现在,如果我们获取该文件,我们会得到一些奇怪的行为:
# Proof that we can return a NumericMatrix in a List:
> FooMat()
[[1]]
[,1] [,2]
[1,] 0 2
[2,] 1 3
# Multiply the whole NumericMatrix by a whole NumericVector
# whose size is 1. Unsafe behaviour?
> FooMat2()
[[1]]
[1] 0.000000e+00 3.000000e+00 1.388988e-309 2.083483e-309
# Multiply the whole NumericMatrix by the first element of
# The NumericVector. Results are correct, but `*` converts
# the answer to a NumericVector instead of a NumericMatrix
> FooMat3()
[[1]]
[1] 0 3 6 9
# Same as FooMat3() except now we just multiply the NumericMatrix
# by an integer
> FooMat4()
[[1]]
[1] 0 3 6 9
一、语法糖*
由...提供Rcpp
似乎无法正确处理矩阵与标量的乘法。二、乘以整数NumericVector
, as in FooMat2()
导致不安全行为。