c++ - 如何构建 Eigen::Map 到我打算用数据填充的 matlab::data::Array 对象

标签 c++ matlab eigen mex

这个问题是上一个 question 的后续问题。关于在用于 C++ 的 Matlab Data API 中构建 Eigen::Map 到输入 matlab::data::Array 对象。现在我想知道如何实现类似的东西,但要实现一个输出数组,当我循环遍历它时,我将用数据填充该数组。

在上一个问题中,我实现了 Matlab's forums 中的链接解决方案。在这里,我尝试使用以下方法来获取非常量指针:

template <typename T>
T* getOutDataPtr(matlab::data::Array arr) {
  matlab::data::TypedArray<T> arr_t = arr;
  matlab::data::TypedIterator<T> it(arr_t.begin());
  return it.operator->();
}

使用方式如下:

// Initialize input parameters
long int numEl = inputs[0][0];
long int na = inputs[0][1];
long int nPoints = inputs[0][2];
        
// Preallocate output and define map to output array
outputs[0] = factory.createArray<double>
  ({static_cast<size_t>(nPoints),static_cast<size_t>(numEl*na)});
        
auto ptrRecon = getOutDataPtr<double>(outputs[0]);
Eigen::Map<Eigen::MatrixXd> Recon(ptrRecon,nPoints,numEl*na);

for(int i = 0; i < nPoints; i++) {
 for(int n = 0; n < na; n++) {
  for (int j = 0; j < numEl; j++) {
   Recon(i,n*numEl + j) = 5.0;
  }
 }    
}

即使是这样简单的赋值,我也会在编译后遇到运行时错误并且 Matlab 崩溃。究竟出了什么问题?

额外试验 我还尝试了以下内部循环,它似乎确实有效:

for(int i = 0; i < nPoints; i++) {
    for(int n = 0; n < na; n++) {
        for (int j = 0; j < numEl; j++) {
            outputs[0][i][n*numEl + j] = 5.0;

        }
    }    
}

我怀疑这意味着我获取指向输出 matlab 数据数组的指针的方式存在一些问题?

最佳答案

这只是一个猜测,因为我将放弃相当平庸的 Matlab API 文档,并且没有 Matlab 许可证来测试它。所以请对此持保留态度。

我看到的一个区别是您创建了一个可变迭代器 TypedIterator<T>而不是 TypedIterator<const T>在 Matlab 论坛中使用。您可以在一个需要 matlab::data::Array 的函数中执行此操作。按值(value)。这将创建一个 shared data copy 。据我了解,这些是写时复制。

我的假设是,构造该迭代器或以可以修改该共享数组的方式使用它“取消共享”它,从而有效地创建一个拷贝。然而,该拷贝将仅限于参数的生命周期,即函数。函数返回后,它就变成了一个悬空指针。

尝试将函数签名更改为 T* getOutDataPtr(matlab::data::Array& arr) 。或者将代码内联到您的主函数中。

编辑

实际上,这种更改还不够,因为您构造了 TypedArray<T>来自Array 。这也算作共享拷贝。尝试使用 getWritableElements 来代替:

template <typename T>
T* getOutDataPtr(matlab::data::Array& arr) {
  auto range = matlab::data::getWritableElements<T>(arr);
  return range.begin().operator->();
}

关于c++ - 如何构建 Eigen::Map 到我打算用数据填充的 matlab::data::Array 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76393248/

相关文章:

c++ - Qt Bluetooth Low Energy - 使用非标准 GATT 的问题

c++ - 以具有复数元素和下三角方阵 A 矩阵的线性最小二乘法求解系统 Ax=b

c++ - Eigen 3.3.0 与 3.2.10 的性能回归?

matlab - 如何在 MATLAB 中将数字连接到变量名?

matlab - 在 matlab 中使用 parfor 来实现格子玻尔兹曼代码

c++ - Eigen是否假设混叠?

c++ - 为 std::vector 实现 '+' 运算符

c++ - 模板特化与函数重载

c++ - 函数和变量 "chicken or the egg"场景

MATLAB:在每行中查找第 n 个最小元素