gpt4 book ai didi

Rcpp:在处理 NumericMatrix 时,* 的语法糖会产生意想不到的结果

转载 作者:行者123 更新时间:2023-12-04 12:00:31 25 4
gpt4 key购买 nike

A recently asked question让我相信 Rcpp* 语法糖没有按预期工作。在链接的问题中,用户试图将矩阵乘以标量。

R代码

这是我们在 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,如 FooMat2() 中那样会导致不安全的行为。

最佳答案

正如我在之前的回答中所述,当我需要对矩阵进行实际数学运算时,我会使用 Armadillo 对象:

R> cppFunction('arma::mat scott(arma::mat x, double z) { 
+ return(x*z); }',
+ depends="RcppArmadillo")
R> scott(matrix(1:4,2), 2)
[,1] [,2]
[1,] 2 6
[2,] 4 8
R>

Sugar 操作很好,但还不够完整。不过,我们肯定会打补丁。

正如我们之前多次说过的:rcpp-devel 是合适的支持 channel 。

编辑(2016 年 10 月或 2.5 年后):搜索其他内容让我回到了这里。在 Rcpp 0.12.* 系列中,一些在矩阵和向量之间进行运算时起作用,因此基本的“矩阵乘以标量”现在可以按照您的预期工作:

R> cppFunction("NumericMatrix testmat(NumericMatrix m, double multme) { 
+ NumericMatrix n = m * multme;
+ return n; }")
R> testmat(matrix(1:4,2), 1)
[,1] [,2]
[1,] 1 3
[2,] 2 4
R> testmat(matrix(1:4,2), 3)
[,1] [,2]
[1,] 3 9
[2,] 6 12
R>

不过,我可能仍会使用 RcppArmadillo 进行矩阵数学运算。

关于Rcpp:在处理 NumericMatrix 时,* 的语法糖会产生意想不到的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20950880/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com