External Interfaces/API

Handling Complex Data

Complex data from MATLAB is separated into real and imaginary parts. The MATLAB API provides two functions, `mxGetPr` and `mxGetPi`, that return pointers (of type `double *`) to the real and imaginary parts of your data.

This example takes two complex row vectors and convolves them.

• ```/*
* =============================================================
* convec.c
* Example for illustrating how to pass complex data
* from MATLAB to C and back again
*
* Convolves two complex input vectors.
*
* This is a MEX-file for MATLAB.
* Copyright (c) 1984-2000 The MathWorks, Inc.
* =============================================================
*/

/* \$Revision: 1.9 \$ */

#include "mex.h"

/* Computational subroutine */
void convec(double *xr, double *xi, int nx, double *yr,
double *yi, int ny, double *zr, double *zi)
{
int i,j;

zr[0] = 0.0;
zi[0] = 0.0;
/* Perform the convolution of the complex vectors. */
for (i = 0; i < nx; i++) {
for (j = 0; j < ny; j++) {
*(zr+i+j) = *(zr+i+j) + *(xr+i) * *(yr+j) - *(xi+i)
* *(yi+j);
*(zi+i+j) = *(zi+i+j) + *(xr+i) * *(yi+j) + *(xi+i)
* *(yr+j);
}
}
}
```

Below is the gateway routine that calls this complex convolution.

• ```/* The gateway routine. */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double  *xr, *xi, *yr, *yi, *zr, *zi;
int     rows, cols, nx, ny;

/* Check for the proper number of arguments. */
if (nrhs != 2)
mexErrMsgTxt("Two inputs required.");
if (nlhs > 1)
mexErrMsgTxt("Too many output arguments.");

/* Check that both inputs are row vectors. */
if (mxGetM(prhs[0]) != 1 || mxGetM(prhs[1]) != 1)
mexErrMsgTxt("Both inputs must be row vectors.");
rows = 1;

/* Check that both inputs are complex. */
if (!mxIsComplex(prhs[0]) || !mxIsComplex(prhs[1]))
mexErrMsgTxt("Inputs must be complex.\n");

/* Get the length of each input vector. */
nx = mxGetN(prhs[0]);
ny = mxGetN(prhs[1]);

/* Get pointers to real and imaginary parts of the inputs. */
xr = mxGetPr(prhs[0]);
xi = mxGetPi(prhs[0]);
yr = mxGetPr(prhs[1]);
yi = mxGetPi(prhs[1]);

/* Create a new array and set the output pointer to it. */
cols = nx + ny - 1;
plhs[0] = mxCreateDoubleMatrix(rows, cols, mxCOMPLEX);
zr = mxGetPr(plhs[0]);
zi = mxGetPi(plhs[0]);

/* Call the C subroutine. */
convec(xr, xi, nx, yr, yi, ny, zr, zi);

return;
}
```

Entering these numbers at the MATLAB prompt

• ```x = [3.000 - 1.000i, 4.000 + 2.000i, 7.000 - 3.000i];
y = [8.000 - 6.000i, 12.000 + 16.000i, 40.000 - 42.000i];
```

and invoking the new MEX-file

• ```z = convec(x,y)
```

results in

• ```z =
1.0e+02 *

Columns 1 through 4

0.1800 - 0.2600i 0.9600 + 0.2800i 1.3200 - 1.4400i 3.7600 - 0.1200i

Column 5

1.5400 - 4.1400i
```

which agrees with the results that the built-in MATLAB function `conv.m` produces.

 Passing Structures and Cell Arrays Handling 8-,16-, and 32-Bit Data