A.2.2 在Mex文件中使用矩阵和数组

所有变量的基本mex类型是mxArray。任何对象,如矩阵、元胞数组或结构体,都存储在此基本类型中。mxArray的作用本质上与oct文件中的octave_value类相同,都是作为所有更专业类型的容器。

mxArray结构体至少包含:它所代表的变量名称、维度、类型,以及该变量是实数还是复数。它还可以包含许多附加字段,具体取决于mxArray的类型。有许多函数可用于创建mxArray结构体,包括mxCreateDoubleMatrixmxCreateCellArraymxCreateSparse以及通用函数mxCreateNumericArray

访问数组中数据的基本函数是mxGetPr。由于mex接口假设复数数组的实部和虚部分别存储,因此存在一个等效的函数mxGetPi用于获取虚部。这两个函数都仅适用于双精度矩阵。通用函数mxGetDatamxGetImagData对所有矩阵类型执行相同的操作。例如:

mxArray *m;
mwSize *dims;
UINT32_T *pr;

dims = (mwSize *) mxMalloc (2 * sizeof (mwSize));
dims[0] = 2; dims[1] = 2;
m = mxCreateNumericArray (2, dims, mxUINT32_CLASS, mxREAL);
pr = (UINT32_T *) mxGetData (m);

还存在诸如mxSetPr之类的函数,它们执行相反的操作,将数组的数据设置为mxSetPr参数所指向的内存块。

注意上面使用的类型mwSize以及mwIndex,它们被定义为Octave在构建mex文件的平台上进行索引的原生精度。这允许32位和64位平台都支持mex文件。mwSize用于定义数组维度和最大元素数量,而mwIndex用于定义数组索引。

下面给出的文件mypow2.c展示了一个示例,演示如何处理任意实数或复数双精度数组。

#include "mex.h"

void
mexFunction (int nlhs, mxArray *plhs[],
             int nrhs, const mxArray *prhs[])
{
  mwSize n;
  mwIndex i;
  double *vri, *vro;

  if (nrhs != 1 || ! mxIsDouble (prhs[0]))
    mexErrMsgTxt ("ARG1 must be a double matrix");

  n = mxGetNumberOfElements (prhs[0]);
  plhs[0] = mxCreateNumericArray (mxGetNumberOfDimensions (prhs[0]),
                                  mxGetDimensions (prhs[0]),
                                  mxGetClassID (prhs[0]),
                                  mxIsComplex (prhs[0]));
  vri = mxGetPr (prhs[0]);
  vro = mxGetPr (plhs[0]);

  if (mxIsComplex (prhs[0]))
    {
      double *vii, *vio;
      vii = mxGetPi (prhs[0]);
      vio = mxGetPi (plhs[0]);

      for (i = 0; i < n; i++)
        {
          vro[i] = vri[i] * vri[i] - vii[i] * vii[i];
          vio[i] = 2 * vri[i] * vii[i];
        }
    }
  else
    {
      for (i = 0; i < n; i++)
        vro[i] = vri[i] * vri[i];
    }
}

其使用示例如下:

b = randn (4,1) + 1i * randn (4,1);
all (b.^2 == mypow2 (b))
⇒  1

上面的示例使用了函数mxGetDimensionsmxGetNumberOfElementsmxGetNumberOfDimensions来处理多维数组的维度。函数mxGetMmxGetN也可用于获取二维矩阵(M×N矩阵)的行数和列数。


版权所有 © 2024-2026 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号-2