Mon Jan 4 13:44:30 EST 2010

Programming MATLAB Mex files

Last night I began my first attempt at programming c-routines (so-called mex files) that can be called natively from MATLAB to speed up specific tasks. It’s realy cool!

Here’s some quick code and hints to get you started.

/* [output1 output2] = mymexfile( input1, input2)*/

#include <mex.h>
#include <math.h>

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

    mexPrintf("Hello, world!\n"); 

}

Thee’s no main() function in a mex file. Rather everything goes in the mexFunction routine. Here are the arguments:

  • nlhs: The number of output (left hand size) elements, 2 in this case (output1 and output2).
  • plhs[]: An array of pointers to each of the output data structures.
  • nrhs: The number of input (right hand size) arguments, 2 in thse case (input1 and input2)
  • prhs[]: An array of points to each of the input data structures.

Input and output data structures are of type mxArray. I like to assign the inputs to something more understandable like this.

mxArray *pinput1, *pinput2;
double *input1, *input2;
pinput1 = prhs[0];
pinput2 = prhs[1];
input1 = mxGetPr(pinput1);
input2 = mxGetPr(pinput2);

Here I've given the input pointer list more meaningful names (pinput1, pinput2) and extracted a pointer to each input array (input1 and input2). This allows one to address the input as input1[0], input1[2], etc.

To write data back out, you have to create variables of mxArray type and assign them to the output pointer list. Here’s how:

plhs[0] = mxCreateDoubleMatrix(1, N, mxREAL);   /*output1*/
plhs[1] = mxCreateDoubleMatrix(1, N, mxREAL);   /*output2*/

output1 = mxGetPr(plhs[0]);
output2 = mxGetPr(plhs[1]);

output1[0] = 10.5;
output2[0] = 13.3;

Here we create output matrices. A pointer to each is stored in plhs. Then we get pointers to the data within each. These now look like arrays which can be indexed as normal and assigned output values as makes sense.

An example error message:

mexErrMsgTxt("Duplicate sound speed depth values. Exiting...\n");

An example print statement (prints into MATLAB):

mexPrintf("Starting Point: %f,%f\n",xo[0],zo[0]);

Finally to compile the code you simply navigate to the directory form within MATLAB and type:

mex mymexfile.c

You'll get an executable which you can run just like a MATLAB m-file.

[output1 output2] = mymexfile(input1,input2);

I'm coding up a ray-tracing algorithm to expedite processing of sonar data in MATLAB. Although it is not exactly an apples to apples comparison, the mex c-code I've written executes more than 45 times faster than the same basic algorithm as a native MATLAB script.


Posted by Val Schmidt | Permanent link | File under: matlab