Return mex 函数中的双指针二维矩阵
Return double pointer 2D matrix in mex function
我正在使用用双指针定义的二维数组,e.g,
double** array;
array = (double**) calloc(numRows, sizeof(double*));
for (int i = 0; i < numRows; i++)
{
array[i] = (double*) calloc(numCols, sizeof(double));
/* then array[i][j] = values */
}
// code to return matlab array
plhs[0] = mxCreateDoubleMatrix(numRows, numCols, mxREAL);
// memory copy
// ?????????
for (i = 0; i < numRows; i++){
free(array[i]);
}
free(array);
我想在 matlab 中 return array
。到目前为止,我对 // memory copy
部分进行了执行,我认为它很好,请更正 我是:
stacked1D = mxGetPr(plhs[0]);
int n = 0;
for ( int r = 0; r < max_degree; r++ )
for ( int c = 0; c < n_vars; c++ )
stacked1D[n++] = stacked2D[r][c];
我想知道我们是否可以使用像这样 mxSetPr(OUT, *stacked2D);
这样的 mem-copy
函数来完成它,它在这种语法中不起作用。
能否请您给出提示解释或可能的答案?
行和列迭代应该在您的代码中反转,PaulMcKenzie 的建议虽然原则上是个好主意,但不适用于 Mex 矩阵(它们是逐列布局的,因此使用该方法您将不得不使用 M[column][row]
访问您的矩阵,这是不自然且令人困惑的)。
或者,您可以使用如下所示的简单包装器:
template <class T, class I = unsigned>
struct MatrixWrapper
{
T *data;
I nrows, ncols;
MatrixWrapper()
{ clear(); }
MatrixWrapper( T *data_, I nrows_, I ncols_ )
{ set(data_,nrows_,ncols_); }
inline void clear()
{ data = NULL; nrows = ncols = 0; }
inline void set( T *data_, I nrows_, I ncols_ )
{ data = data_; nrows = nrows_; ncols = ncols_; }
inline T& operator() ( I r, I c ) const
{ return data[ r + nrows*c ]; }
};
您的 Mex 函数将如下所示:
// allocate a temporary matrix
double *M_data = new double[ nrows*ncols ];
MatrixWrapper<double> M( M_data, nrows, ncols );
// access values with M(i,j) as a "normal" matrix
// allocate a Mex output
plhs[0] = mxCreateDoubleMatrix( nrows, ncols, mxREAL );
MatrixWrapper<double> out0( mxGetPr(plhs[0]), nrows, ncols );
// copy to the Mex output
for ( unsigned c = 0; c < ncols; c++ )
for ( unsigned r = 0; r < nrows; r++ )
out0(r,c) = M(r,c);
// free temporary allocation
M.clear();
delete[] M_data;
我正在使用用双指针定义的二维数组,e.g,
double** array;
array = (double**) calloc(numRows, sizeof(double*));
for (int i = 0; i < numRows; i++)
{
array[i] = (double*) calloc(numCols, sizeof(double));
/* then array[i][j] = values */
}
// code to return matlab array
plhs[0] = mxCreateDoubleMatrix(numRows, numCols, mxREAL);
// memory copy
// ?????????
for (i = 0; i < numRows; i++){
free(array[i]);
}
free(array);
我想在 matlab 中 return array
。到目前为止,我对 // memory copy
部分进行了执行,我认为它很好,请更正 我是:
stacked1D = mxGetPr(plhs[0]);
int n = 0;
for ( int r = 0; r < max_degree; r++ )
for ( int c = 0; c < n_vars; c++ )
stacked1D[n++] = stacked2D[r][c];
我想知道我们是否可以使用像这样 mxSetPr(OUT, *stacked2D);
这样的 mem-copy
函数来完成它,它在这种语法中不起作用。
能否请您给出提示解释或可能的答案?
行和列迭代应该在您的代码中反转,PaulMcKenzie 的建议虽然原则上是个好主意,但不适用于 Mex 矩阵(它们是逐列布局的,因此使用该方法您将不得不使用 M[column][row]
访问您的矩阵,这是不自然且令人困惑的)。
或者,您可以使用如下所示的简单包装器:
template <class T, class I = unsigned>
struct MatrixWrapper
{
T *data;
I nrows, ncols;
MatrixWrapper()
{ clear(); }
MatrixWrapper( T *data_, I nrows_, I ncols_ )
{ set(data_,nrows_,ncols_); }
inline void clear()
{ data = NULL; nrows = ncols = 0; }
inline void set( T *data_, I nrows_, I ncols_ )
{ data = data_; nrows = nrows_; ncols = ncols_; }
inline T& operator() ( I r, I c ) const
{ return data[ r + nrows*c ]; }
};
您的 Mex 函数将如下所示:
// allocate a temporary matrix
double *M_data = new double[ nrows*ncols ];
MatrixWrapper<double> M( M_data, nrows, ncols );
// access values with M(i,j) as a "normal" matrix
// allocate a Mex output
plhs[0] = mxCreateDoubleMatrix( nrows, ncols, mxREAL );
MatrixWrapper<double> out0( mxGetPr(plhs[0]), nrows, ncols );
// copy to the Mex output
for ( unsigned c = 0; c < ncols; c++ )
for ( unsigned r = 0; r < nrows; r++ )
out0(r,c) = M(r,c);
// free temporary allocation
M.clear();
delete[] M_data;