将 3D 矩阵从 MATLAB 传递到 C.

在这个例子中,我们将说明如何从 MATLAB 中获取双实型 3D 矩阵,并将其传递给 C double*数组。

此示例的主要目标是展示如何从 MATLAB MEX 阵列获取数据,并突出显示矩阵存储和处理中的一些小细节。

matrixIn.cpp

#include "mex.h"

void mexFunction(int  nlhs , mxArray *plhs[],
        int nrhs, mxArray const *prhs[]){
   // check amount of inputs
   if (nrhs!=1) {
        mexErrMsgIdAndTxt("matrixIn:InvalidInput", "Invalid number of inputs to MEX file.");
    }
   
   // check type of input
   if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])){
        mexErrMsgIdAndTxt("matrixIn:InvalidType",  "Input matrix must be a double, non-complex array.");
   }
   
   // extract the data
   double const * const matrixAux= static_cast<double const *>(mxGetData(prhs[0]));

   // Get matrix size
   const mwSize *sizeInputMatrix= mxGetDimensions(prhs[0]);

   // allocate array in C. Note: its 1D array, not 3D even if our input is 3D
   double*  matrixInC= (double*)malloc(sizeInputMatrix[0] *sizeInputMatrix[1] *sizeInputMatrix[2]* sizeof(double));

  
   // MATLAB is column major, not row major (as C). We need to reorder the numbers
   // Basically permutes dimensions   

   // NOTE: the ordering of the loops is optimized for fastest memory access! 
   // This improves the speed in about 300% 

    const int size0 = sizeInputMatrix[0]; // Const makes compiler optimization kick in
    const int size1 = sizeInputMatrix[1];
    const int size2 = sizeInputMatrix[2];
    
    for (int j = 0; j < size2; j++)
    {
        int jOffset = j*size0*size1; // this saves re-computation time
        for (int k = 0; k < size0; k++)
        {
            int kOffset = k*size1; // this saves re-computation time
            for (int i = 0; i < size1; i++)
            {
                int iOffset = i*size0; 
                matrixInC[i + jOffset + kOffset] = matrixAux[iOffset + jOffset + k];
            }
        }
    }

    // we are done!

    // Use your C matrix here

    // free memory
    free(matrixInC);
    return;
}

需要注意的相关概念:

  • MATLAB 矩阵在内存中都是 1D,无论它们在 MATLAB 中使用多少维度。对于 C / C++库中的大多数(如果不是全部)主矩阵表示也是如此,因为它允许优化和更快的执行。

  • 你需要在循环中将矩阵从 MATLAB 显式复制到 C.

  • MATLAB 矩阵按列主要顺序存储,如 Fortran,但 C / C++和大多数现代语言都是行主要。置换输入矩阵很重要,否则数据看起来会完全不同。

此示例中的相关功能是:

  • mxIsDouble 检查输入是否为 double 类型。
  • mxIsComplex 检查输入是实数还是虚数。
  • mxGetData 返回指向输入数组中实际数据的指针。NULL 如果没有真实数据。
  • mxGetDimensions 返回一个指向 mwSize 数组的指针,其中包含每个索引中维度的大小。