将Rcpp NumericVector映射到*静态*或*固定大小*的Eigen向量?

huangapple go评论75阅读模式
英文:

Mapping Rcpp NumericVector to *static* or *fixed-size* Eigen Vectors?

问题

这个帖子提供了一个将Rcpp::NumericVector转换为Eigen::VectorXd的示例:

  1. Rcpp::cppFunction("bool conv(NumericVector X) { \
  2. Eigen::Map<Eigen::VectorXd> \
  3. XS(Rcpp::as<Eigen::Map<Eigen::VectorXd>>(X)); return true; } ",
  4. depends="RcppEigen")
  5. conv(1:4)

但我无法将其调整为创建具有静态大小或固定大小的Eigen容器:

  1. Rcpp::cppFunction("bool conv(NumericVector X) { \
  2. Eigen::Map<Eigen::Matrix<double,4,1>> \
  3. XS(Rcpp::as<Eigen::Map<Eigen::Matrix<double,4,1>>>(X)); return true; } ",
  4. depends="RcppEigen")
  5. conv(1:4)

如何实现这个目标?

英文:

This thread provides an example of converting an Rcpp::NumericVector to an Eigen::VectorXd:

  1. Rcpp::cppFunction(&quot;bool conv(NumericVector X) { \
  2. Eigen::Map&lt;Eigen::VectorXd&gt; \
  3. XS(Rcpp::as&lt;Eigen::Map&lt;Eigen::VectorXd&gt; &gt;(X)); return true; } &quot;,
  4. depends=&quot;RcppEigen&quot;)
  5. conv(1:4)

but I can't manage to adapt this to creating statically-sized or fixed-size Eigen containers

  1. Rcpp::cppFunction(&quot;bool conv(NumericVector X) { \
  2. Eigen::Map&lt;Eigen::Matrix&lt;double,4,1&gt;&gt; \
  3. XS(Rcpp::as&lt;Eigen::Map&lt;Eigen::Matrix&lt;double,4,1&gt;&gt; &gt;(X)); return true; } &quot;,
  4. depends=&quot;RcppEigen&quot;)
  5. conv(1:4)

How can this be done?

答案1

得分: 2

以下是翻译好的部分:

这是一种最小化的蛮力方法,用于实例化一个固定大小的4x1矩阵...然后使用memcpy()来复制数据负载。正如我之前的评论中提到的,我们在RcppEigen中没有代码可以从SEXP R对象转换到Eigen类型,因此我们不能做更多的事情。

代码

  1. #include <RcppEigen.h>
  2. // [[Rcpp::depends(RcppEigen)]]
  3. // [[Rcpp::export]]
  4. bool conv1(Rcpp::NumericVector X) {
  5. Eigen::Map<Eigen::VectorXd> XS(Rcpp::as<Eigen::Map<Eigen::VectorXd>>(X));
  6. return true;
  7. }
  8. // [[Rcpp::export]]
  9. bool conv2(Rcpp::NumericVector X) {
  10. const int n = 4;
  11. if (X.size() != n) Rcpp::stop("Wrong size");
  12. Eigen::Matrix<double,4,1> m;
  13. std::memcpy(&m(0,0), &X[0], n*sizeof(double));
  14. Rcpp::Rcout << m << std::endl;
  15. return true;
  16. }

输出

  1. > Rcpp::sourceCpp("~/git/stackoverflow/76706728/answer.cpp")
  2. > x <- as.numeric(1:4)
  3. > conv1(x)
  4. [1] TRUE
  5. > conv2(x)
  6. 1
  7. 2
  8. 3
  9. 4
  10. [1] TRUE
英文:

Here is a minimal brute-force approach of instantiating a fixed-size 4x1 matrix ... and then using memcpy() to copy the payload over. As my comment earlier mentioned we have no code in RcppEigen that transfer from a SEXP R object to such an Eigen type so there is not a lot more we can do.

Code

  1. #include &lt;RcppEigen.h&gt;
  2. // [[Rcpp::depends(RcppEigen)]]
  3. // [[Rcpp::export]]
  4. bool conv1(Rcpp::NumericVector X) {
  5. Eigen::Map&lt;Eigen::VectorXd&gt; XS(Rcpp::as&lt;Eigen::Map&lt;Eigen::VectorXd&gt;&gt;(X));
  6. return true;
  7. }
  8. // [[Rcpp::export]]
  9. bool conv2(Rcpp::NumericVector X) {
  10. const int n = 4;
  11. if (X.size() != n) Rcpp::stop(&quot;Wrong size&quot;);
  12. Eigen::Matrix&lt;double,4,1&gt; m;
  13. std::memcpy(&amp;m[0,0], &amp;X[0], n*sizeof(double));
  14. Rcpp::Rcout &lt;&lt; m &lt;&lt; std::endl;
  15. return true;
  16. }
  17. /*** R
  18. x &lt;- as.numeric(1:4)
  19. conv1(x)
  20. conv2(x)
  21. */

Output

  1. &gt; Rcpp::sourceCpp(&quot;~/git/stackoverflow/76706728/answer.cpp&quot;)
  2. &gt; x &lt;- as.numeric(1:4)
  3. &gt; conv1(x)
  4. [1] TRUE
  5. &gt; conv2(x)
  6. 1
  7. 2
  8. 3
  9. 4
  10. [1] TRUE
  11. &gt;

huangapple
  • 本文由 发表于 2023年7月18日 01:15:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76706728.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定