將 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
陣列的指標,其中包含每個索引中維度的大小。