我正在寻找一种简单的方法来使用 Rcpp 构建 3D 数组,并使该数组可以在 R 中访问。总的来说,我对 Rcpp 和 C++ 编码仍然很陌生,因此我们将不胜感激。
\n这是我的源代码:
\n#include <Rcpp.h>\nusing namespace Rcpp;\n\n\nint d[5][5][5] = {0};\n\n// [[Rcpp::export]]\n\nint fit(){ \n for (int X = 0; X < 5; X++){\n for (int Y = 0; Y < 5; Y++){\n for (int Z = 0; Z < 5; Z++){\n d[X][Y][Z] = X + Y + Z;\n }\n }\n }\nreturn d;\n}\nRun Code Online (Sandbox Code Playgroud)\n我的想法是我可以将 fit() 分配给 R 中的一个元素(比如 D),并且能够从该数组中的位置进行调用。
\n我意识到我可以让“拟合”成为 x、y 和 z 的函数;但就我的目的而言,在 R 中使用数组会更快。
\n再次强调,任何帮助将不胜感激。
\n感谢您的帮助,德克,\n我仍在努力解决的一件事是运行循环。当我运行这个循环时:
\n#include <Rcpp.h>\n\nusing namespace Rcpp;\n\n// [[Rcpp::export]]\nIntegerVector rcpp_matrix(){\n\n IntegerVector v = IntegerVector(Dimension(2,2));\n \n for (int i = 0; i < 2; i++){\n for (int j = 0; j < 2; j++){\n v(i,j) = (i + 1) * (j + 1);\n }\n }\n \n // Return the vector to R\n return v;\n}\nRun Code Online (Sandbox Code Playgroud)\n它按预期工作。然而,当我尝试扩展到三个维度时,如下所示:
\n#include <Rcpp.h>\n\nusing namespace Rcpp;\n\n// [[Rcpp::export]]\nIntegerVector rcpp_matrix(){\n\n IntegerVector v = IntegerVector(Dimension(2,2,2));\n \n for (int i = 0; i < 2; i++){\n for (int j = 0; j < 2; j++){\n for (int k = 0; k < 2; k++){\n v(i,j,k) = (i + 1) * (j + 1) * (k + 1);\n }\n }\n }\n \n // Return the vector to R\n return v;\n}\nRun Code Online (Sandbox Code Playgroud)\n我收到错误:
\nfile10c2d06d0b.cpp: In function \xe2\x80\x98Rcpp::IntegerVector rcpp_matrix()\xe2\x80\x99:\nfile10c2d06d0b.cpp:14:16: error: no match for call to \xe2\x80\x98(Rcpp::IntegerVector {aka Rcpp::Vector<13>}) (int&, int&, int&)\xe2\x80\x99\n 14 | v(i,j,k) = (i + 1) * (j + 1) * (k + 1);\n | ^\nRun Code Online (Sandbox Code Playgroud)\n我还缺少其他方面吗?\n再次感谢您。
\n向量是 R 中的关键,数组只是具有二维属性的向量:
> v <- 1:12
> dim(v) <- c(3,4)
> v
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
>
Run Code Online (Sandbox Code Playgroud)
所以我们也可以做 3-d:
> dim(v) <- c(2,3,2)
> v
, , 1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
, , 2
[,1] [,2] [,3]
[1,] 7 9 11
[2,] 8 10 12
>
Run Code Online (Sandbox Code Playgroud)
等等。这与 Rcpp 中的单元测试片段中看到的完全相同:
// [[Rcpp::export]]
IntegerVector integer_dimension_ctor_3(){
return IntegerVector( Dimension( 2, 3, 4) ) ;
}
Run Code Online (Sandbox Code Playgroud)
我们可以快速测试:
> Rcpp::cppFunction("IntegerVector ivec3() { return IntegerVector(Dimension(2, 3, 4));}")
> ivec3()
, , 1
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
, , 2
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
, , 3
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
, , 4
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
>
Run Code Online (Sandbox Code Playgroud)
话虽如此,我建议您研究一下 Armadillo 'Cubes' 以及您可以从 RcppArmadillo 做什么 - 可能功能更齐全。
编辑: 这是你的方法的更简单的犰狳变体,使用cube<int>又名icube:
#include <RcppArmadillo/Lightest> // new 'lighter' header
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::icube make3dvec(){
arma::icube v(2,2,2);
for (int x = 0; x < 2; x++){
for (int y = 0; y < 2; y++){
for (int z = 0; z < 2; z++){
v(x,y,z) = (x + 1) * (y + 1) * (z + 1);
}
}
}
return v;
}
/*** R
make3dvec()
*/
Run Code Online (Sandbox Code Playgroud)
> Rcpp::sourceCpp("~/git/stackoverflow/75036466/answer.cpp")
> make3dvec()
, , 1
[,1] [,2]
[1,] 1 2
[2,] 2 4
, , 2
[,1] [,2]
[1,] 2 4
[2,] 4 8
>
Run Code Online (Sandbox Code Playgroud)