Examples of Fortran Source MEX-Files

Introduction

The MATLAB® API provides a set of Fortran routines that handle double-precision data and strings in MATLAB. For each data type, there is a specific set of functions that you can use for data manipulation.

Source code for the examples in this chapter are located in the matlabroot/extern/examples/refbook directory of your MATLAB installation. To build these examples, make sure you have a Fortran compiler selected using the mex -setup command. Then at the MATLAB command prompt, type:

mex filename.F

where filename is the name of the example.

This section looks at source code for the examples. Unless otherwise specified, the term "MEX-file" refers to a source file.

A First Example — Passing a Scalar

Let's look at a simple example of Fortran code and its MEX-file equivalent. Here is a Fortran computational routine that takes a scalar and doubles it:

      subroutine timestwo(y, x)
      real*8 x, y
C     
      y = 2.0 * x
      return
      end

To see the same function written in the MEX-file format (timestwo.F), open the file in the MATLAB Editor.

To build this example, at the command prompt type:

mex timestwo.F

This command creates the binary MEX-file called timestwo with an extension corresponding to the machine type on which you're running. You can now call timestwo as if it were an M-function. Type:

x = 2;
y = timestwo(x)

MATLAB displays:

y =
     4

Passing Strings

Passing strings from MATLAB to a Fortran MEX-file is straightforward. The program revord.F accepts a string and returns the characters in reverse order. To see the example revord.F, open the file in the MATLAB Editor.

After checking for the correct number of inputs, the gateway routine mexFunction verifies that the input was a row vector string. It then finds the size of the string and places the string into a Fortran character array. Note that in the case of character strings, it is not necessary to copy the data into a Fortran character array using mxCopyPtrToCharacter. In fact, mxCopyPtrToCharacter works only with MAT-files. For more information, see Using MAT-Files.

To build this example, at the command prompt type:

mex revord.F

Type:

x = 'hello world';
y = revord(x)

MATLAB displays:

y =

dlrow olleh

Passing Arrays of Strings

Passing arrays of strings adds a complication to the example Passing Strings. Because MATLAB stores elements of a matrix by column instead of by row, the size of the string array must be correctly defined in the Fortran MEX-file. The key point is that the row and column sizes as defined in MATLAB must be reversed in the Fortran MEX-file. Consequently, when returning to MATLAB, the output matrix must be transposed.

This example places a string array/character matrix into MATLAB as output arguments rather than placing it directly into the workspace.

To build this example, at the command prompt type:

mex passstr.F

Type:

passstr;

to create the 5-by-15 mystring matrix. You need to do some further manipulation. The original string matrix is 5-by-15. Because of the way MATLAB reads and orients elements in matrices, the size of the matrix must be defined as M=15 and N=5 in the MEX-file. After the matrix is put into MATLAB, the matrix must be transposed. The program passstr.F illustrates how to pass a character matrix. To see the code passstr.F, open the file in the MATLAB Editor.

Type:

passstr

MATLAB displays:

ans =

MATLAB         
The Scientific 
Computing      
Environment    
   by TMW, Inc.

Passing Matrices

In MATLAB, you can pass matrices into and out of MEX-files written in Fortran. You can manipulate the MATLAB arrays by using mxGetPr and mxGetPi to assign pointers to the real and imaginary parts of the data stored in the MATLAB arrays. You can create new MATLAB arrays from within your MEX-file by using mxCreateDoubleMatrix.

The example matsq.F takes a real 2-by-3 matrix and squares each element. To see the source code, open the file in MATLAB Editor.

After performing error checking to ensure that the correct number of inputs and outputs was assigned to the gateway subroutine and to verify the input was in fact a numeric matrix, matsq.F creates a matrix. The matrix is copied to a Fortran matrix using mxCopyPtrToReal8. Now the computational subroutine can be called, and the return argument is placed into y_pr, the pointer to the output, using mxCopyReal8ToPtr.

To build this example, at the command prompt type:

mex matsq.F

For a 2-by-3 real matrix, type:

x = [1 2 3; 4 5 6];
y = matsq(x)

MATLAB displays:

y =
    1      4      9
   16     25     36

Passing Two or More Inputs or Outputs

The plhs and prhs parameters (see The Components of a Fortran MEX-File) are vectors containing pointers to the left-hand side (output) variables and right-hand side (input) variables. plhs(1) contains a pointer to the first left-hand side argument, plhs(2) contains a pointer to the second left-hand side argument, and so on. Likewise, prhs(1) contains a pointer to the first right-hand side argument, prhs(2) points to the second, and so on.

The example xtimesy.F multiplies an input scalar times an input scalar or matrix. To see the source code, open the file in MATLAB Editor.

As this example shows, creating MEX-file gateways that handle multiple inputs and outputs is straightforward. All you need to do is keep track of which indices of the vectors prhs and plhs correspond to which input and output arguments of your function. In this example, the input variable x corresponds to prhs(1) and the input variable y to prhs(2).

To build this example, at the command prompt type:

mex xtimesy.F

For an input scalar x and a real 3-by-3 matrix, type:

x = 3; y = ones(3);
z = xtimesy(x, y)

MATLAB displays:

z =
     3     3     3
     3     3     3
     3     3     3

Handling Complex Data

MATLAB stores complex double-precision data as two vectors of numbers—one vector contains the real data and the other contains the imaginary data. The functions mxCopyPtrToComplex16 and mxCopyComplex16ToPtr copy MATLAB data to a native complex*16 Fortran array.

The example convec.F takes two complex vectors (of length 3) and convolves them. To see the source code, open the file in the MATLAB Editor.

To build this example, at the command prompt type:

mex convec.F

Enter the following at the command prompt:

x = [3 - 1i, 4 + 2i, 7 - 3i];
y = [8 - 6i, 12 + 16i, 40 - 42i];

Type:

z = convec(x, y)

MATLAB displays:

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.

Dynamically Allocating Memory

To allocate memory dynamically in a Fortran MEX-file, use %val. (See Using the Fortran %val Construct.) The example dblmat.F takes an input matrix of real data and doubles each of its elements. To see the source code, open the file in the MATLAB Editor. compute.F is the subroutine dblmat calls to double the input matrix. (Open the file in the MATLAB Editor.)

To build this example, at the command prompt type:

mex dblmat.F compute.F

For the 2-by-3 matrix, type:

x = [1 2 3; 4 5 6];
y = dblmat(x)

MATLAB displays:

y =
     2     4     6
     8    10    12

Handling Sparse Matrices

MATLAB provides a set of functions that allow you to create and manipulate sparse matrices. There are special parameters associated with sparse matrices, namely ir, jc, and nzmax. For information on how to use these parameters and how MATLAB stores sparse matrices in general, see Sparse Matrices.

The fulltosparse.F example illustrates how to populate a sparse matrix. To see the source code, open the file in the MATLAB Editor. loadsparse.F is the subroutine fulltosparse calls to fill the mxArray with the sparse data. (Open the file in the MATLAB Editor.)

To build this example, at the command prompt type:

mex fulltosparse.F loadsparse.F

At the command prompt, typing:

full = eye(5)
full =
     1     0     0     0     0
     0     1     0     0     0
     0     0     1     0     0
     0     0     0     1     0
     0     0     0     0     1

creates a full, 5-by-5 identity matrix. Using fulltosparse on the full matrix produces the corresponding sparse matrix:

spar = fulltosparse(full)
spar =
   (1,1)        1
   (2,2)        1
   (3,3)        1
   (4,4)        1
   (5,5)        1

Calling Functions from Fortran MEX-Files

You can call MATLAB functions, operators, M-files, and even other binary MEX-files from within your Fortran source code by using the API function mexCallMATLAB. The sincall.F example creates an mxArray, passes various pointers to a subfunction to acquire data, and calls mexCallMATLAB to calculate the sine function and plot the results. To see the source code, open the file in the MATLAB Editor. fill.F is the subroutine sincall calls to fill the mxArray with data. (Open the file in the MATLAB Editor.)

It is possible to use mexCallMATLAB (or any other API routine) from within your computational Fortran subroutine. Note that you can only call most MATLAB functions with double-precision data. M-functions that perform computations, such as eig, do not work correctly with data that is not double precision.

To build this example, at the command prompt type:

mex sincall.F fill.F

Running this example:

sincall

displays the results:

Figure of a sine wave

This example creates an M-file that returns two variables but only assigns one of them a value:

function [a,b]=foo[c]
a=2*c;

MATLAB displays the following warning:

Warning: One or more output arguments not assigned during call to 
'foo'.

If you then call foo using mexCallMATLAB, the unassigned output variable is now of type mxUNKNOWN_CLASS.

  


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