如何通过 matlab::data::TypedArray<double> 作为指针在 MATLAB mex 文件中构造犰狳矩阵?

问题描述

请有更多经验的人建议我如何实现上述目标?

这肯定是小事;然而,经过无数个日日夜夜的尝试、研究和在互联网上阅读,我仍然无法理解它。

设置:

两个 C++ 源文件和一个头文件:

ma​​in.cpp

  • 包含 MATLAB 和 C++ 之间的通用 IO 接口
  • 将两个双精度数组(每个数组的维度:ncols: 168 和 nrows: 2)和两个双常量双精度输入 C++
  • 它通过调用 foo()
  • 执行一些基于犰狳的循环(这部分不是那么重要,因此省略)
  • 返回outp,它是一个“简单的”双精度标量
  • 没有什么花哨或复杂的东西。

sub.cpp

sub.hpp

  • 只是一个简单的头文件。

如果您提前提供任何帮助、提示或建设性意见,我将不胜感激。

// main.cpp
// MATLAB API Header Files
#include "mex.hpp"
#include "mexAdapter.hpp"

// Custom header
#include "sub.hpp"

// Overloading the function call operator,thus class acts as a functor
class MexFunction : public matlab::mex::Function {
    public:
        void operator()(matlab::mex::ArgumentList outputs,matlab::mex::ArgumentList inputs){
            
            matlab::data::ArrayFactory factory;
            // Validate arguments
            checkArguments(outputs,inputs);

            double* darrY = matlab::data::TypedArray<double>(std::move(inputs[0])).release().get();
            double* darrD = matlab::data::TypedArray<double>(std::move(inputs[1])).release().get();
            const double csT = inputs[2][0];
            const double csKy = inputs[3][0];

            // data type of outp is "just" a plain double,NOT a double array
            double outp = foo(darrY,darrD,csT,csKy);

            outputs[0] = factory.createScalar(outp);

            void checkArguments(matlab::mex::ArgumentList outputs,matlab::mex::ArgumentList inputs){
            // Create pointer to MATLAB engine
            std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
            // Create array factory,allows us to create MATLAB arrays in C++
            matlab::data::ArrayFactory factory;
            // Check input size and types
            if (inputs[0].getType() != ArrayType::DOUBLE ||
                inputs[0].getType() == ArrayType::COMPLEX_DOUBLE)
            {
                // Throw error directly into MATLAB if type does not match
                matlabPtr->feval(u"error",std::vector<Array>({ factory.createScalar("Input must be double array.") }));
            }
            // Check output size
            if (outputs.size() > 1) {
                matlabPtr->feval(u"error",std::vector<Array>({ factory.createScalar("Only one output is returned.") }));
                }
        }
};

// sub.cpp

#include "sub.hpp"
#include "armadillo"

double foo(double dY[],double dD[],const double T,const double Ky) {
    
    double sum = 0;

    // Conversion of inputs parameters to armadillo matrices using the armadillo's so called advanced matrix constructor:
    // mat(ptr_aux_mem,n_rows,n_cols,copy_aux_mem = true,strict = false)
    // Fixme: parameterize n_rows,n_colss
    arma::mat mY(&dY[0],2,168,false);
    arma::mat mD(&dD[0],false);

    // Armadillo calculations

    for(int t=0; t<int(T); t++){

        // some armadillo based calculation
        // each for cycle increments sum by its return value 
    }

    return sum;
}

// sub.hpp

#ifndef SUB_H_INCLUDED
#define SUB_H_INCLUDED

double foo(double dY[],const double Ky);

#endif // SUB_H_INCLUDED

解决方法

MATLAB Central 有一个类似的问题。换行

double* darrY = matlab::data::TypedArray<double>(std::move(inputs[0])).release().get();
double* darrD = matlab::data::TypedArray<double>(std::move(inputs[1])).release().get();

TypedArray<double> matrix1 = std::move(inputs[0]);
TypedArray<double> matrix2 = std::move(inputs[1]);
buffer_ptr_t<double> Y = matrix1.release();
buffer_ptr_t<double> D = matrix2.release();
double* darrY = Y.get();
double* darrD = D.get();

似乎解决了问题。当我调试您的代码时,看起来两个矩阵由于某种原因获得了相同的地址。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...