External Interfaces

Handling Complex Data

MATLAB stores complex double-precision data as two vectors of numbers -- one contains the real data and one contains the imaginary data. The API provides two functions, `mxCopyPtrToComplex16` and `mxCopyComplex16ToPtr`, which allow you to copy the MATLAB data to a native `complex*16` Fortran array.

This example takes two complex vectors (of length 3) and convolves them.

• ```C==============================================================
=
C     convec.f
C     Example for illustrating how to pass complex data from
C     MATLAB to FORTRAN (using COMPLEX data type) and back
C     again.
C
C     Convolves two complex input vectors.
C
C     This is a MEX-file for MATLAB.
C     Copyright (c) 1984-2000 The MathWorks, Inc.
C     \$Revision: 1.15 \$
C==============================================================
=

C     Computational subroutine
subroutine convec(x, y, z, nx, ny)
complex*16 x(*), y(*), z(*)
integer nx, ny

C     Initialize the output array
do 10 i=1,nx+ny-1
z(i) = (0.0,0.0)
10   continue

do 30 i=1,nx
do 20 j=1,ny
z(i+j-1) = z(i+j-1) + x(i) * y(j)
20      continue
30   continue
return
end

C     The gateway routine.
subroutine mexFunction(nlhs, plhs, nrhs, prhs)

integer mxGetPr, mxGetPi, mxGetM, mxGetN
integer mxIsComplex, mxCreateDoubleMatrix
integer plhs(*), prhs(*)
integer nlhs, nrhs
integer mx, nx, my, ny, nz
complex*16 x(100), y(100), z(199)

C     Check for proper number of arguments.
if (nrhs .ne. 2) then
call mexErrMsgTxt('Two inputs required.')
elseif (nlhs .gt. 1) then
call mexErrMsgTxt('Too many output arguments.')
endif

C     Check that inputs are both row vectors.
mx = mxGetM(prhs(1))
nx = mxGetN(prhs(1))
my = mxGetM(prhs(2))
ny = mxGetN(prhs(2))
nz = nx+ny-1

C     Only handle row vector input.
if(mx .ne. 1 .or. my .ne. 1) then
call mexErrMsgTxt('Both inputs must be row vector.')

C     Check sizes of the two inputs.
elseif(nx .gt. 100 .or. ny .gt. 100) then
call mexErrMsgTxt('Inputs must have less than 100
elements.')

C     Check to see both inputs are complex.
elseif ((mxIsComplex(prhs(1)) .ne. 1) .or.
+        (mxIsComplex(prhs(2)) .ne. 1)) then
call mexErrMsgTxt('Inputs must be complex.')
endif

C     Create the output array.
plhs(1) = mxCreateDoubleMatrix(1, nz, 1)

C     Load the data into Fortran arrays(native COMPLEX data).
call mxCopyPtrToComplex16(mxGetPr(prhs(1)),
mxGetPi(prhs(1)), x, nx)
call mxCopyPtrToComplex16(mxGetPr(prhs(2)),
mxGetPi(prhs(2)), y, ny)

C     Call the computational subroutine.
call convec(x, y, z, nx, ny)

C     Load the output into a MATLAB array.
call mxCopyComplex16ToPtr(z, mxGetPr(plhs(1)),
mxGetPi(plhs(1)), nz)
return
end
```

Entering these numbers at the MATLAB prompt

• ```x = [3 - 1i, 4 + 2i, 7 - 3i]

x =

3.0000 - 1.0000i   4.0000 + 2.0000i   7.0000 - 3.0000i
y = [8 - 6i, 12 + 16i, 40 - 42i]

y =

8.0000 - 6.0000i  12.0000 +16.0000i  40.0000 -42.0000i
```

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 the built-in MATLAB function `conv.m` produces.

 Passing Two or More Inputs or Outputs Dynamically Allocating Memory

© 1994-2005 The MathWorks, Inc.