Products & Services Industries Academia Support User Community Company

Learn more about MATLAB   

Advanced Topics

Help Files

Because the MATLAB interpreter chooses the binary MEX-file when both an M-file and a MEX-file with the same name are encountered in the same folder, it is possible to use M-files for documenting the behavior of your binary MEX-files. The help command automatically finds and displays the appropriate M-file when help is requested and the interpreter finds and executes the corresponding binary MEX-file when the function is invoked.

Linking Multiple Files

You can combine multiple source files, object files, and file libraries to build a binary MEX-file. To do this, list the additional files, with their file extensions, separated by spaces. The name of the resulting MEX-file is the name of the first file in the list.

The following command combines multiple files of different types into a binary MEX-file called circle.ext, where ext is the extension corresponding to the current platform:

mex circle.c square.obj rectangle.c shapes.lib

You may find it useful to use a software development tool like MAKE to manage MEX-file projects involving multiple source files. Simply create a MAKEFILE that contains a rule for producing object files from each of your source files, and then invoke the mex build script to combine your object files into a binary MEX-file. This way you can ensure that your source files are recompiled only when necessary.

Workspace for MEX-File Functions

Unlike M-file functions, MEX-file functions (binary MEX-files) do not have their own variable workspace. MEX-file functions operate in the caller's workspace. mexEvalString evaluates the string in the caller's workspace. In addition, you can use the mexGetVariable and mexPutVariable routines to get and put variables into the caller's workspace.

Handling Large mxArrays

Binary MEX-files built on 64-bit platforms can handle 64-bit mxArrays. These large data arrays can have up to 248–1 elements. The maximum number of elements a sparse mxArray can have is 248-2.

Using the following instructions creates platform-independent binary MEX-files as well.

Your system configuration can impact the performance of MATLAB. The 64-bit processor requirement enables you to create the mxArray and access data in it. However, your system's memory, in particular the size of RAM and virtual memory, determine the speed at which MATLAB processes the mxArray. The more memory available, the faster the processing.

The amount of RAM also limits the amount of data you can process at one time in MATLAB. For guidance on memory issues, see Strategies for Efficient Use of Memory in the Programming Fundamentals documentation. Memory management within source MEX-files can have special considerations, as described in Memory Management.

Using the 64-Bit API

To work with a 64-bit mxArray, your source code must comply with the 64-bit API, which consists of the functions in the following table.

mxCalcSingleSubscriptmxCreateSparseLogicalMatrix
mxCallocmxCreateStructArray
mxCopyCharacterToPtrmxCreateStructMatrix
mxCopyComplex16ToPtrmxGetCell
mxCopyComplex8ToPtrmxGetDimensions
mxCopyInteger1ToPtrmxGetElementSize
mxCopyInteger2ToPtrmxGetField
mxCopyInteger4ToPtrmxGetFieldByNumber
mxCopyPtrToCharactermxGetIr
mxCopyPtrToComplex16mxGetJc
mxCopyPtrToComplex8mxGetM
mxCopyPtrToInteger1mxGetN
mxCopyPtrToInteger2mxGetNumberOfDimensions
mxCopyPtrToInteger4mxGetNumberOfElements
mxCopyPtrToPtrArraymxGetNzmax
mxCopyPtrToReal4mxGetProperty
mxCopyPtrToReal8mxGetString
mxCopyReal4ToPtrmxMalloc
mxCopyReal8ToPtrmxRealloc
mxCreateCellArraymxSetCell
mxCreateCellMatrixmxSetDimensions
mxCreateCharArraymxSetField
mxCreateCharMatrixFromStringsmxSetFieldByNumber
mxCreateDoubleMatrixmxSetIr
mxCreateLogicalArraymxSetJc
mxCreateLogicalMatrixmxSetM
mxCreateNumericArraymxSetN
mxCreateNumericMatrixmxSetNzmax
mxCreateSparsemxSetProperty

Functions in this API use the mwIndex and mwSize types. For information about using these macros, see Required Header Files.

Building the Binary MEX-File

Use the mex build script option -largeArrayDims with the 64-bit API.

Example

The example, arraySize.c in matlabroot/extern/examples/mex, illustrates memory requirements of large mxArrays. To see the example, open the file in MATLAB Editor.

This function requires one positive scalar numeric input, which it uses to create a square matrix. It checks the size of the input to make sure your system can theoretically create a matrix of this size. If the input is valid, it displays the size of the mxArray in kilobytes.

To build this MEX-file, type:

mex -largeArrayDims arraySize.c

To run the MEX-file, type:

arraySize(2^10)

If your system has enough available memory, MATLAB displays:

Dimensions: 1024 x 1024
Size of array in kilobytes: 1024

If your system does not have enough memory to create the array, MATLAB displays an Out of memory error.

You can experiment with this function to test the performance and limits of handling large arrays on your system.

Caution Using Negative Values

When using the 64-bit API, mwSize and mwIndex are equivalent to size_t in C or INTEGER*8 in Fortran. These types are unsigned, unlike int and INTEGER*4, which are the types used in the 32-bit API. Be careful not to pass any negative values to functions that take mwSize or mwIndex arguments. Do not cast negative int or INTEGER*4 values to mwSize or mwIndex; the returned value cannot be predicted. Instead, change your code to avoid using negative values.

Building Cross-Platform Applications

If you develop cross-platform applications (programs that can run on both 32- and 64-bit architectures), you must pay attention to the upper limit of values you use for mwSize and mwIndex. The 32-bit application reads these values and assigns them to variables declared as int in C or INTEGER*4 in Fortran. Be careful to avoid assigning a large mwSize or mwIndex value to an int, INTEGER*4, or other variable that might be too small.

Memory Management

Memory management in MEX-files is similar to memory management in any C or Fortran application. However, there are special considerations because a binary MEX-file exists within the context of a larger application, i.e., MATLAB.

To avoid common problems related to memory management, see Memory Management Issues.

Automatic Cleanup of Temporary Arrays

When a binary MEX-file returns control to MATLAB, it returns the results of its computations in the output arguments—the mxArrays contained in the left-hand side arguments plhs[]. MATLAB destroys any mxArray created by the MEX-file that is not in this argument list. In addition, MATLAB frees any memory that was allocated in the MEX-file using the mxCalloc, mxMalloc, or mxRealloc functions.

In general, we recommend that MEX-file functions destroy their own temporary arrays and free their own dynamically allocated memory. It is more efficient to perform this cleanup in the source MEX-file than to rely on the automatic mechanism. However, there are several circumstances in which the MEX-file does not reach its normal return statement.

The normal return is not reached if:

A careful MEX-file programmer can ensure safe cleanup of all temporary arrays and memory before returning in the first two cases, but not in the last two cases. In the last two cases, the automatic cleanup mechanism is necessary to prevent memory leaks.

Persistent Arrays

You can exempt an array, or a piece of memory, from the MATLAB automatic cleanup by calling mexMakeArrayPersistent or mexMakeMemoryPersistent. However, if a binary MEX-file creates such persistent objects, there is a danger that a memory leak could occur if the MEX-file is cleared before the persistent object is properly destroyed. To prevent this from happening, a source MEX-file that creates persistent objects should register a function, using the mexAtExit function, which disposes of the objects. (You can use a mexAtExit function to dispose of other resources as well; for example, you can use mexAtExit to close an open file.)

For example, here is a simple source MEX-file that creates a persistent array and properly disposes of it.

#include "mex.h"

static int initialized = 0;
static mxArray *persistent_array_ptr = NULL;

void cleanup(void) {
    mexPrintf("MEX-file is terminating, destroying array\n");
    mxDestroyArray(persistent_array_ptr);
}

void mexFunction(int nlhs,
    mxArray *plhs[],
    int nrhs,
    const mxArray *prhs[])
{
  if (!initialized) {
    mexPrintf("MEX-file initializing, creating array\n");
        
    /* Create persistent array and register its cleanup. */
    persistent_array_ptr = mxCreateDoubleMatrix(1, 1, mxREAL);
    mexMakeArrayPersistent(persistent_array_ptr);
    mexAtExit(cleanup);
    initialized = 1;

    /* Set the data of the array to some interesting value. */
    *mxGetPr(persistent_array_ptr) = 1.0;
  } else {
    mexPrintf("MEX-file executing; value of first array 
        element is %g\n", *mxGetPr(persistent_array_ptr));
  }
}

Hybrid Arrays

Functions such as mxSetPr, mxSetData, and mxSetCell allow the direct placement of memory pieces into an mxArray. mxDestroyArray destroys these pieces along with the entire array. Because of this, it is possible to create an array that cannot be destroyed, i.e., an array on which it is not safe to call mxDestroyArray. Such an array is called a hybrid array, because it contains both destroyable and nondestroyable components.

For example, it is not legal to call mxFree (or the ANSI free() function, for that matter) on automatic variables. Therefore, in the following code fragment, pArray is a hybrid array.

mxArray *pArray = mxCreateDoubleMatrix(0, 0, mxREAL);
double data[10];

mxSetPr(pArray, data);
mxSetM(pArray, 1);
mxSetN(pArray, 10);

Another example of a hybrid array is a cell array or structure, one of whose children is a read-only array (an array with the const qualifier, such as one of the inputs to the MEX-file). The array cannot be destroyed because the input to the MEX-file would also be destroyed.

Because hybrid arrays cannot be destroyed, they cannot be cleaned up by the automatic mechanism outlined in Automatic Cleanup of Temporary Arrays. As described in that section, the automatic cleanup mechanism is the only way to destroy temporary arrays in case of a user interrupt. Therefore, temporary hybrid arrays are illegal and can cause your binary MEX-file to crash. Although persistent hybrid arrays are viable, it is best to avoid using them whenever possible.

Large File I/O

MATLAB supports the use of 64-bit file I/O operations in your MEX-file programs. This enables you to read and write data to files that are up to and greater than 2 GB (2 31-1 bytes) in size. Note that some operating systems or compilers might not support files larger than 2 GB.

This section covers the following topics on large file I/O:

Prerequisites to Using 64-Bit I/O

This section describes the components you need to use 64-bit file I/O in your MEX-file programs:

Header File.   Header file io64.h defines many of the types and functions required for 64-bit file I/O. The statement to include this file must be the first #include statement in your source file and must also precede any system header include statements:

#include "io64.h"
#include "mex.h"
        .
        .
        .

Type Declarations.   Use the following types to declare variables used in 64-bit file I/O.

MEX Type

Description

POSIX

fpos_T

Declares a 64-bit int type for setFilePos() and getFilePos(). Defined in io64.h.

fpos_t

int64_T, uint64_T

Declares 64-bit signed and unsigned integer types. Defined in tmwtypes.h.

long, long

structStat

Declares a structure to hold the size of a file. Defined in io64.h.

struct stat

FMT64

Used in mexPrintf to specify length within a format specifier such as %d. See example in the section Printing Formatted Messages. FMT64 is defined in tmwtypes.h.

%lld

LL, LLU

Suffixes for literal int constant 64-bit values (C Standard ISO/IEC 9899:1999(E) Section 6.4.4.1). Used only on UNIX[a] systems.

LL, LLU

[a] UNIX is a registered trademark of The Open Group in the United States and other countries.

Functions.   Here are the functions you need for 64-bit file I/O. All are defined in the header file io64.h.

Function

Description

POSIX

fileno()

Gets a file descriptor from a file pointer

fileno()

fopen()

Opens the file and obtains the file pointer

fopen()

getFileFstat()

Gets the file size of a given file pointer

fstat()

getFilePos()

Gets the file position for the next I/O

fgetpos()

getFileStat()

Gets the file size of a given filename

stat()

setFilePos()

Sets the file position for the next I/O

fsetpos()

Specifying Constant Literal Values

To assign signed and unsigned 64-bit integer literal values, use type definitions int64_T and uint64_T.

On UNIX systems, to assign a literal value to an integer variable where the value to be assigned is greater than 2 31-1 signed, you must suffix the value with LL. If the value is greater than 2 32-1 unsigned, then use LLU as the suffix. These suffixes apply only to UNIX systems and are considered invalid on the Microsoft Windows systems.

The following example declares a 64-bit integer variable initialized with a large literal int value, and two 64-bit integer variables:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, 
                  const mxArray *prhs[])
{
#if defined(_MSC_VER) || defined(__BORLANDC__)     /* Windows */
   int64_T large_offset_example = 9000222000;
#else                                              /* UNIX    */
   int64_T large_offset_example = 9000222000LL;
#endif

int64_T offset   = 0;
int64_T position = 0;

Opening a File

To open a file for reading or writing, use the C fopen function as you normally would. As long as you have included io64.h at the start of your program, fopen works correctly for large files. No changes at all are required for fread, fwrite, fprintf, fscanf, and fclose.

To open an existing file for read and update in binary mode:

fp = fopen(filename, "r+b");
if (NULL == fp)
   {
   /* File does not exist. Create new file for writing 
    * in binary mode.
    */
   fp = fopen(filename, "wb");
   if (NULL == fp)
      {
      sprintf(str, "Failed to open/create test file '%s'",
              filename);
      mexErrMsgTxt(str);
      return;
      }
   else
      {
      mexPrintf("New test file '%s' created\n",filename);
      }
   }
else mexPrintf("Existing test file '%s' opened\n",filename);

Printing Formatted Messages

You cannot print 64-bit integers using the %d conversion specifier. Instead, use FMT64 to specify the appropriate format for your platform. FMT64 is defined in the header file tmwtypes.h. The following example shows how to print a message showing the size of a large file:

int64_T large_offset_example = 9000222000LL;

mexPrintf("Example large file size: %" FMT64 "d bytes.\n",
           large_offset_example);

Replacing fseek and ftell with 64-Bit Functions

The ANSI C fseek and ftell functions are not 64-bit file I/O capable on most platforms. The functions setFilePos and getFilePos, however, are defined as the corresponding POSIX fsetpos and fgetpos, (or fsetpos64 and fgetpos64), as required by your platform/OS. These functions are 64-bit file I/O capable on all platforms.

The following example shows how to use setFilePos instead of fseek, and getFilePos instead of ftell. It uses getFileFstat to find the size of the file, and then uses setFilePos to seek to the end of the file to prepare for adding data at the end of the file.

getFileFstat(fileno(fp), &statbuf);
fileSize = statbuf.st_size;
offset = fileSize;

setFilePos(fp, (fpos_T*) &offset);
getFilePos(fp, (fpos_T*) &position );

Unlike fseek, setFilePos supports only absolute seeking relative to the beginning of the file. If you want to do a relative seek, first call getFileFstat to obtain the file size, and then convert the relative offset to an absolute offset that you can pass to setFilePos.

Determining the Size of an Open File

Getting the size of an open file involves two steps:

  1. Refresh the record of the file size stored in memory using getFilePos and setFilePos.

  2. Retrieve the size of the file using getFileFstat.

Refreshing the File Size Record.   Before attempting to retrieve the size of an open file, you should first refresh the record of the file size residing in memory. If you skip this step on a file that is opened for writing, the file size returned might be incorrect or 0.

To refresh the file size record, seek to any offset in the file using setFilePos. If you do not want to change the position of the file pointer, you can seek to the current position in the file. This example obtains the current offset from the start of the file, and then seeks to the current position to update the file size without moving the file pointer:

getFilePos( fp, (fpos_T*) &position);
setFilePos( fp, (fpos_T*) &position);

Getting the File Size.   The getFileFstat function takes a file descriptor input argument (that you can obtain from the file pointer of the open file using fileno) and returns the size of that file in bytes in the st_size field of a structStat structure:

structStat statbuf;
int64_T fileSize = 0;

if (0 == getFileFstat(fileno(fp), &statbuf))
   {
   fileSize = statbuf.st_size;
   mexPrintf("File size is %" FMT64 "d bytes\n", fileSize);
   }

Determining the Size of a Closed File

The getFileStat function takes the filename of a closed file as an input argument and returns the size of the file in bytes in the st_size field of a structStat structure:

structStat statbuf;
int64_T fileSize = 0;

if (0 == getFileStat(filename, &statbuf))
   {
   fileSize = statbuf.st_size;
   mexPrintf("File size is %" FMT64 "d bytes\n", fileSize);
   }

Calling LAPACK and BLAS Functions from MEX-Files

What You Need to Know

LAPACK is a large, multiauthor Fortran subroutine library that MATLAB uses for numerical linear algebra. MATLAB uses BLAS, which stands for Basic Linear Algebra Subroutines, to speed up matrix multiplication and the LAPACK routines.

If you want to call a specific LAPACK or BLAS function, you can call the function using a MEX-file. To create a MEX-file, you need C/C++ or Fortran programming experience and the software resources (compilers and linkers) to build an executable file. It also is helpful to understand how to use Fortran subroutines. MATLAB provides the mwlapack and mwblas libraries in the matlabroot/extern/lib folder. To work with complex numbers, MATLAB provides conversion routines in the fort.c and fort.h files in the matlabroot/extern/examples/refbook folder. To help you get started, there are source code examples in the matlabroot/extern/examples/refbook folder.

If you do not know how to use MEX-files, start with the following sections:

For an overview showing how to create and build sample MEX-files, start with the following sections:

Creating a MEX-File Using LAPACK and BLAS Functions

To call LAPACK or BLAS functions:

  1. Create a source MEX-file containing the mexFunction gateway routine, as described in the following topics:

  2. Select a supported compiler for your platform, as described in the following topics:

  3. Build a binary MEX-file using the mex command with one or more of the following options:

    • Link your source file to one or both of the libraries, mwlapack and mwblas.

    • Use the -largeArrayDims option because the mwlapack and mwblas libraries support 64-bit integers for matrix dimensions.

    • If your function uses complex numbers, build your source file with fort.c and include the fort.h header file.

The following topics show how to use the mex command using the example matrixMultiply.c. To work with this file, copy it to a local directory. For example:

copyfile(fullfile(matlabroot, 'extern', 'examples', 'refbook', ...
  'matrixMultiply.c'), fullfile('c:', 'work'));

The example files are read-only files. To modify an example, ensure the file is writable by typing:

fileattrib('matrixMultiply.c','+w');

Building on Windows Platforms.   MATLAB provides compiler-specific versions of the libraries on the Windows platform. To link to a specific library, look at the matlabroot/extern/lib/ folder and choose the path for your architecture and compiler. For example, type:

cc = mex.getCompilerConfigurations('Any','Selected');
cc.Manufacturer
computer

If you selected a Microsoft C compiler on a 32-bit platform, MATLAB displays:

ans =
Microsoft
ans =
PCWIN

Link to the libraries in the matlabroot/extern/lib/win32/microsoft/ folder. To simplify the build command, create variables lapacklib and blaslib, which identify the full path and file name of each library.

lapacklib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
blaslib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwblas.lib');

When you use a variable to identify the library, you must use the function syntax of the mex command. To build matrixMultiply.c, which uses functions from the BLAS library, type:

mex('-v', '-largeArrayDims', 'matrixMultiply.c', blaslib)

To build a MEX-file with functions that use complex numbers, see Handling Complex Numbers in LAPACK and BLAS Functions.

Building on UNIX Platforms.   To build the MEX-file matrixMultiply.c, which uses functions from the BLAS library, type:

mex -v -largeArrayDims matrixMultiply.c -lmwblas

To build a MEX-file with functions that use complex numbers, see Handling Complex Numbers in LAPACK and BLAS Functions.

Testing the matrixMultiply MEX-File.   To run the matrixMultiply MEX-file, type:

A = [1 3 5; 2 4 7];
B = [-5 8 11; 3 9 21; 4 0 8];
X = matrixMultiply(A,B)

MATLAB displays:

X =
    24    35   114
    30    52   162

Preserving Input Values from Modification

Many LAPACK and BLAS functions modify the values of arguments passed to them. It is good practice to make a copy of arguments you can modify before passing them to these functions. For information about how MATLAB handles arguments to the mexFunction, see Managing Input and Output Parameters.

Example — matrixDivide.c.   The following example calls the LAPACK function dgesv that modifies its input arguments. The code in this example makes copies of prhs[0] and prhs[1], and passes the copies to dgesv to preserve the contents of the input arguments.

To see the example, open the file in the MATLAB Editor. To create the MEX-file, copy the source file to a working directory:

copyfile(fullfile(matlabroot, 'extern', 'examples', 'refbook', ...
  'matrixDivide.c'), fullfile('c:', 'work'));

To build the file on Windows, type:

lapacklib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
mex('-v', '-largeArrayDims', 'matrixDivide.c', lapacklib)

To build the file on UNIX type:

mex -v matrixDivide.c -lmwlapack

To test, type:

A = [1 2; 3 4];
B = [5; 6];
X = matrixDivide(A,B)

MATLAB displays:

X =
   -4.0000
    4.5000

Passing Arguments to Fortran Functions from C Programs

The LAPACK and BLAS functions are written in Fortran. Be aware that C and Fortran use different conventions for passing arguments to and from functions. Fortran functions expect the arguments to be passed by reference, while arguments to C functions are passed by value. When you pass by value, you pass a copy of the value. When you pass by reference, you pass a pointer to the value. A reference is also the address of the value.

When you call a Fortran subroutine, like a function from LAPACK or BLAS, from a C program, be sure to pass the arguments by reference. To do this, precede the argument with an ampersand (&), unless that argument is already a reference. For example, when you create a matrix using the mxGetPr function, you create a reference to the matrix and do not need the ampersand before the argument.

In the following code snippet, variables m, n, p, one, and zero need the & character to make them a reference. Variables A, B, C, and chn are pointers, which are references.

/* pointers to input & output matrices*/
double *A, *B, *C;
/* matrix dimensions */
mwSignedIndex m,n,p;
/* other inputs to dgemm */
char *chn = "N";
double one = 1.0, zero = 0.0;

/* call BLAS function */
dgemm(chn, chn, &m, &n, &p, &one, A, &m, B, &p, &zero, C, &m);

Example — matrixMultiply.c.   The matrixMultiply.c example calls dgemm, passing all arguments by reference. To see the source code, open the file in the MATLAB Editor. To build and run this example, see Creating a MEX-File Using LAPACK and BLAS Functions.

Passing Arguments to Fortran Functions from Fortran Programs

You can call LAPACK and BLAS functions from Fortran MEX files. The following example takes two matrices and multiplies them by calling the BLAS routine dgemm:

#include "fintrf.h"

subroutine mexFunction(nlhs, plhs, nrhs, prhs)
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
mwPointer mxcreatedoublematrix
mwPointer mxgetpr
mwPointer A, B, C
mwSignedIndex mxgetm, mxgetn
mwSignedIndex m, n, p, numel
double precision one, zero, ar, br
character ch1, ch2

ch1 = 'N'
ch2 = 'N'
one = 1.0
zero = 0.0

A = mxgetpr(prhs(1))
B = mxgetpr(prhs(2))
m = mxgetm(prhs(1))
p = mxgetn(prhs(1))
n = mxgetn(prhs(2))

plhs(1) = mxcreatedoublematrix(m, n, 0.0)
C = mxgetpr(plhs(1))
numel = 1
call mxcopyptrtoreal8(A, ar, numel)
call mxcopyptrtoreal8(B, br, numel)

call dgemm(ch1, ch2, m, n, p, one, %val(A), m,
     +           %val(B), p, zero, %val(C), m)

return
end

Handling Complex Numbers in LAPACK and BLAS Functions

MATLAB stores complex numbers differently than Fortran. MATLAB stores the real and imaginary parts of a complex number in separate, equal length vectors, pr and pi. Fortran stores the same complex number in one location with the real and imaginary parts interleaved.

As a result, complex variables exchanged between MATLAB and a Fortran function are incompatible. MATLAB provides conversion routines, mat2fort and fort2mat, that change the storage format of complex numbers to address this incompatibility.

MATLAB supplies the files fort.c and fort.h, which provide routines for conversion between MATLAB and Fortran complex data structures. These files define the mat2fort and fort2mat routines.

To use these routines, you need to:

  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. Use the -Ipathname switch to indicate the header file. 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.

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 Preserving 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. Use the fort2mat function to make the variable compatible with MATLAB.

Example — Passing Complex Variables.   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 the file in the MATLAB Editor. To create the MEX-file, copy the source file to a working directory:

copyfile(fullfile(matlabroot, 'extern', 'examples', 'refbook', ...
  'matrixDivideComplex.c'), fullfile('c:', 'work'));

To build the file on a Windows platform, type:

lapacklib = fullfile(matlabroot, ...
    'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
fortfile = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook', 'fort.c');
fortheaderdir = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook');
mex('-v', '-largeArrayDims', ['-I' fortheaderdir], ...
    'matrixDivideComplex.c', fortfile, lapacklib)

To build on a UNIX platform, type:

fortfile = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook', 'fort.c');
fortheaderdir = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook');
mex('-v', '-largeArrayDims', ['-I' fortheaderdir], ...
    'matrixDivideComplex.c', fortfile, '-lmwlapack')

To test:

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)

MATLAB displays:

X =
  -4.4000 + 0.8000i
   4.8000 - 0.6000i

Example — Symmetric Indefinite Factorization Using LAPACK.   The example utdu_slv.c calls LAPACK functions zhesvx and dsysvx. To see the example, open the file in the MATLAB Editor. To create the MEX-file, copy the source file to a working directory:

copyfile(fullfile(matlabroot, 'extern', 'examples', 'refbook', ...
  'utdu_slv.c'), fullfile('c:', 'work'));

To build the file on Windows, type:

lapacklib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
fortheaderdir = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook');
mex('-v', '-largeArrayDims', ['-I' fortheaderdir], ...
    'utdu_slv.c', fortfile, lapacklib)

To build on a UNIX platform, type:

mex -v utdu_slv.c -lmwlapack

Modifying the Function Name on UNIX Systems

Add an underscore character following the function name when calling LAPACK or BLAS functions on a UNIX system. For example, to call dgemm, use:

dgemm_(arg1, arg2, ..., argn);

Or add these lines to your source code:

#if !defined(_WIN32)
#define dgemm dgemm_
#endif

[a] UNIX is a registered trademark of The Open Group in the United States and other countries.

  


Recommended Products

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.

 © 1984-2009- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS