将 lambda 函数应用于 `RcppArmadillo` 中的 `arma::cube`
Apply lambda function to `arma::cube` in `RcppArmadillo`
我尝试使用 RcppArmadillo
计算数组每个切片的 Frobenious 范数 (arma::cube
)。文件 cxxFuns.cpp
中的示例代码如下所示。
// [[Rcpp::depends(RcppArmadillo)]]
#include "RcppArmadillo.h"
// [[Rcpp::export]]
arma::vec array_norm (arma::cube & x) {
arma::vec out = x.each_slice([](arma::mat& x0) {return arma::norm(x0, "fro") ;}) ;
return out ;
}
cpp
文件编译成功后,函数array_norm
抛出异常:
set.seed(2020)
Rcpp::sourceCpp('cxxFuns.cpp')
x <- array(rnorm(3*4*5), 3:5)
array_norm(x)
#> error: copy into matrix: can't interpret cube with dimensions 3x4x5 as a vector
#> Error in array_norm(x) :
#> copy into matrix: can't interpret cube with dimensions 3x4x5 as a vector
由 reprex package (v0.3.0)
创建于 2020-12-02
这实际上是来自 Armadillo 的错误消息,因为您的逻辑还不正确——结果不是向量。你可以通过更改为这个(独立的,一个非常好的 Rcpp 技巧)代码来看到:
代码
// [[Rcpp::depends(RcppArmadillo)]]
#include "RcppArmadillo.h"
// [[Rcpp::export]]
bool array_norm (arma::cube & x) {
auto out = x.each_slice([](arma::mat& x0) {return arma::norm(x0, "fro") ;}) ;
out.print("out");
return true;
}
/*** R
set.seed(2020)
x <- array(rnorm(3*4*5), 3:5)
array_norm2(x)
*/
输出
> Rcpp::sourceCpp("~/git/Whosebug/65104769/answer.cpp")
> set.seed(2020)
> x <- array(rnorm(3*4*5), 3:5)
> array_norm2(x)
out
[cube slice 0]
0.3770 -1.1304 0.9391 0.1174
0.3015 -2.7965 -0.2294 -0.8531
-1.0980 0.7206 1.7591 0.9093
[cube slice 1]
1.1964 1.8000 -2.2890 1.0982
-0.3716 1.7040 0.0583 0.3182
-0.1233 -3.0388 2.1744 -0.0731
[cube slice 2]
0.8343 0.9367 -0.8125 2.4354
0.1988 -0.1474 -0.7437 0.3881
1.2978 0.1104 1.0953 0.2906
[cube slice 3]
-0.2856 0.4472 -0.3010 0.2531
0.0760 0.9085 -0.7260 -0.3707
-0.5603 -0.5051 -1.1801 0.0222
[cube slice 4]
0.6600 0.6014 0.1188 -1.3283
0.4888 -0.6738 0.1212 -0.5669
-0.1888 0.4761 -0.1860 0.5788
[1] TRUE
我尝试使用 RcppArmadillo
计算数组每个切片的 Frobenious 范数 (arma::cube
)。文件 cxxFuns.cpp
中的示例代码如下所示。
// [[Rcpp::depends(RcppArmadillo)]]
#include "RcppArmadillo.h"
// [[Rcpp::export]]
arma::vec array_norm (arma::cube & x) {
arma::vec out = x.each_slice([](arma::mat& x0) {return arma::norm(x0, "fro") ;}) ;
return out ;
}
cpp
文件编译成功后,函数array_norm
抛出异常:
set.seed(2020)
Rcpp::sourceCpp('cxxFuns.cpp')
x <- array(rnorm(3*4*5), 3:5)
array_norm(x)
#> error: copy into matrix: can't interpret cube with dimensions 3x4x5 as a vector
#> Error in array_norm(x) :
#> copy into matrix: can't interpret cube with dimensions 3x4x5 as a vector
由 reprex package (v0.3.0)
创建于 2020-12-02这实际上是来自 Armadillo 的错误消息,因为您的逻辑还不正确——结果不是向量。你可以通过更改为这个(独立的,一个非常好的 Rcpp 技巧)代码来看到:
代码
// [[Rcpp::depends(RcppArmadillo)]]
#include "RcppArmadillo.h"
// [[Rcpp::export]]
bool array_norm (arma::cube & x) {
auto out = x.each_slice([](arma::mat& x0) {return arma::norm(x0, "fro") ;}) ;
out.print("out");
return true;
}
/*** R
set.seed(2020)
x <- array(rnorm(3*4*5), 3:5)
array_norm2(x)
*/
输出
> Rcpp::sourceCpp("~/git/Whosebug/65104769/answer.cpp")
> set.seed(2020)
> x <- array(rnorm(3*4*5), 3:5)
> array_norm2(x)
out
[cube slice 0]
0.3770 -1.1304 0.9391 0.1174
0.3015 -2.7965 -0.2294 -0.8531
-1.0980 0.7206 1.7591 0.9093
[cube slice 1]
1.1964 1.8000 -2.2890 1.0982
-0.3716 1.7040 0.0583 0.3182
-0.1233 -3.0388 2.1744 -0.0731
[cube slice 2]
0.8343 0.9367 -0.8125 2.4354
0.1988 -0.1474 -0.7437 0.3881
1.2978 0.1104 1.0953 0.2906
[cube slice 3]
-0.2856 0.4472 -0.3010 0.2531
0.0760 0.9085 -0.7260 -0.3707
-0.5603 -0.5051 -1.1801 0.0222
[cube slice 4]
0.6600 0.6014 0.1188 -1.3283
0.4888 -0.6738 0.1212 -0.5669
-0.1888 0.4761 -0.1860 0.5788
[1] TRUE