octave: Working with Matrices and Arrays in Mex-Files

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