Main Content

Pass Separate Complex Numbers to Fortran Functions

MATLAB® stores complex numbers the same way as Fortran, in one vector, pa, with the real and imaginary parts interleaved.

Before MATLAB Version 9.4 (R2018a), MATLAB stored complex numbers differently than Fortran, in separate, equal length vectors pr and pi. As a result, complex variables exchanged between those versions of MATLAB and a Fortran function are incompatible. MATLAB provides example conversion routines mat2fort and fort2mat that change the storage format of complex numbers to address this incompatibility. The fort.h header file defines the mat2fort and fort2mat functions. The source code is in the fort.c file.

  • mat2fort — Convert MATLAB separate complex matrix to Fortran complex storage.

  • fort2mat — Convert Fortran complex storage to MATLAB separate real and imaginary parts.

To use these routines:

  1. Include the fort.h header file in your source file, using the statement #include "fort.h".

  2. Link the fort.c file with your program. Specify the full path, matlabroot/extern/examples/refbook for fort.c in the build command.

  3. To indicate the header file, use the -Ipathname switch. Specify the full path, matlabroot/extern/examples/refbook for fort.h in the build command.

  4. When you specify the full path, replace the term matlabroot with the actual folder name.

  5. Build the function using the mex -R2017b option.

Handling Complex Number Input Values

It is unnecessary to copy arguments for functions that use complex number input values. The mat2fort conversion routine creates a copy of the arguments for you. For information, see Preserve Input Values from Modification.

Handling Complex Number Output Arguments

For complex variables returned by a Fortran function, do the following:

  1. When allocating storage for the variable, allocate a real variable with twice as much space as you would for a variable of the same size. Do this because the returned variable uses the Fortran format, which takes twice the space. See the allocation of zout in the example.

  2. To make the variable compatible with MATLAB, use the fort2mat function.

Pass Complex Variables — matrixDivideComplex

This example shows how to call a function, passing complex prhs[0] as input and receiving complex plhs[0] as output. Temporary variables zin and zout contain the input and output values in Fortran format. To see the example, open matrixDivideComplex.c in the MATLAB Editor. To create the MEX file, copy the source file to a writable folder.

copyfile(fullfile(matlabroot,'extern','examples','refbook','matrixDivideComplex.c'),'.','f')

Create variables locating the fort.c file and its header file.

fortfile = fullfile(matlabroot,'extern','examples','refbook','fort.c');
fortheaderdir = fullfile(matlabroot,'extern','examples','refbook');

Build the MEX function.

mex('-R2017b',['-I' fortheaderdir],'matrixDivideComplex.c',fortfile,'-lmwlapack')

Test the function.

Areal = [1 2; 3 4];
Aimag = [1 1; 0 0];
Breal = [5; 6];
Bimag = [0; 0];
Acomplex = complex(Areal,Aimag);
Bcomplex = complex(Breal,Bimag);
X = matrixDivideComplex(Acomplex,Bcomplex)
X =
  -4.4000 + 0.8000i
   4.8000 - 0.6000i

Handle Fortran Complex Return Type — dotProductComplex

Some level 1 BLAS functions (for example, zdotu and zdotc) return a double complex type, which the C language does not support. The following C MEX file, dotProductComplex.c, shows how to handle the Fortran complex return type for function zdotu. To see the example, open dotProductComplex.c in the MATLAB Editor.

The calling syntax for a C program calling a Fortran function that returns a value in an output argument is platform-dependent. On the Windows® and Mac platforms, pass the return value as the first input argument. MATLAB provides a macro, FORTRAN_COMPLEX_FUNCTIONS_RETURN_VOID, to handle these differences.

The dotProductComplex example computes the dot product X of each element of two complex vectors A and B. The calling syntax is:

X = dotProductComplex(A,B)

where A and B are complex vectors of the same size and X is a complex scalar.

For example, to build:

copyfile(fullfile(matlabroot,'extern','examples','refbook','dotProductComplex.c'),'.','f')
fortfile = fullfile(matlabroot,'extern','examples','refbook','fort.c');
fortheaderdir = fullfile(matlabroot,'extern','examples','refbook');
mex('-R2017b',['-I' fortheaderdir],'dotProductComplex.c',fortfile,'-lmwblas')

To test, type;

a1 = [1+2i; 2+3i];
b1 = [-1+2i; -1+3i];
X = dotProductComplex(a1,b1)
X =
  -16.0000 + 3.0000i

Symmetric Indefinite Factorization Using LAPACK — utdu_slv

The example utdu_slv.c calls LAPACK functions zhesvx and dsysvx. To see the example, open utdu_slv.c in the MATLAB Editor. To create the MEX file, copy the source file to a writable folder.

copyfile(fullfile(matlabroot,'extern','examples','refbook','utdu_slv.c'),'.','f')

To build:

fortheaderdir = fullfile(matlabroot,'extern','examples','refbook');
mex('-R2017b',['-I' fortheaderdir],'utdu_slv.c',fortfile,'-lmwlapack')