首页 > 解决方案 > 如何在不复制基础数据的情况下从 Eigen::Tensor 创建 Rcpp NumericVector

问题描述

如果我在 Eigen 中创建一个大张量,并且我喜欢将张量作为多维数组返回给 R。我知道如何使用下面的数据复制来做到这一点。问题:是否可以在没有数据复制步骤的情况下做到这一点?

#include <Rcpp.h>
#include <RcppEigen.h>
#include <unsupported/Eigen/CXX11/Tensor>

// [[Rcpp::depends(RcppEigen)]]
using namespace Rcpp;

template <typename T>
NumericVector copyFromTensor(const T& x) 
{ 
    int n = x.size();
    NumericVector ans(n);
    IntegerVector dim(x.NumDimensions);
    for (int i = 0; i < x.NumDimensions; ++i) {
      dim[i] = x.dimension(i);
    }
    memcpy((double*)ans.begin(), (double*)x.data(), n * sizeof(double));
    ans.attr("dim") = dim;
    return ans;
}

// [[Rcpp::export]]
NumericVector getTensor() {
    Eigen::Tensor<double, 3> x(4, 3, 1);
    x.setRandom();
    return copyFromTensor(x);
}

/*** R
getTensor()
*/

标签: reigenrcpprcppeigen

解决方案


作为一般规则,您可以使用来自 R 并已由 R 管理的数据将一种方式零复制到您的 C++ 代码中。

在将数据返回到 R 的 C++ 代码中,任何未使用的 R 分配器都必须被复制。

在这里,您的对象x是堆栈分配的,因此您需要一个副本。请参阅编写有关 R 分配器的 R 扩展;当你创建一个新的张量对象时,Eigen 可能会让你使用它。不是微不足道的一步。我想我会和副本一起生活。


推荐阅读