A.2.2 Working with Matrices and Arrays in Mex-Files

The basic mex type of all variables is mxArray. Any object, such as a matrix, cell array, or structure, is stored in this basic type. mxArray serves essentially the same purpose as the octave_value class in oct-files in that it acts as a container for all the more specialized types.

The mxArray structure contains at a minimum, the name of the variable it represents, its dimensions, its type, and whether the variable is real or complex. It can also contain a number of additional fields depending on the type of the mxArray. There are a number of functions to create mxArray structures, including mxCreateDoubleMatrix, mxCreateCellArray, mxCreateSparse, and the generic mxCreateNumericArray.

The basic function to access the data in an array is mxGetPr. Because the mex interface assumes that real and imaginary parts of a complex array are stored separately, there is an equivalent function mxGetPi that gets the imaginary part. Both of these functions are only for use with double precision matrices. The generic functions mxGetData and mxGetImagData perform the same operation for all matrix types. For example:

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);

There are also the functions mxSetPr, etc., that perform the inverse, and set the data of an array to use the block of memory pointed to by the argument of mxSetPr.

Note the type mwSize used above, and also mwIndex, are defined as the native precision of the indexing in Octave on the platform on which the mex-file is built. This allows both 32- and 64-bit platforms to support mex-files. mwSize is used to define array dimensions and the maximum number or elements, while mwIndex is used to define indexing into arrays.

An example that demonstrates how to work with arbitrary real or complex double precision arrays is given by the file mypow2.c shown below.

#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];
    }
}

An example of its use is

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

The example above uses the functions mxGetDimensions, mxGetNumberOfElements, and mxGetNumberOfDimensions to work with the dimensions of multi-dimensional arrays. The functions mxGetM, and mxGetN are also available to find the number of rows and columns in a 2-D matrix (MxN matrix).

© 1996–2020 John W. Eaton
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://octave.org/doc/v6.3.0/Working-with-Matrices-and-Arrays-in-Mex_002dFiles.html