将 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
数组的指针,其中包含每个索引中维度的大小。