A Short MEX Tutorial and Demo
Matlab is a great programming language/environment because of its ease of use, great visualization, and rapid prototyping abilities. Raw speed is not one of its strong suits. MEX (Matlab Executables) are the answer. These functions allow you to program in C or C++ (ultra fast languages), but be able to call and use them from Matlab programs. This post is a short intro to mex files which should get you up and running.
What This Post Teaches
In this post, I show how to create a mex file, how to set up inputs and outputs, how to get access to Matlab objects, and how to manipulate them. I also give a skeleton mex program that might be helpful. There is a lot more to learn, and I’d refer you to the mex manual regardless.
What You Should Already Know
I’m going to assume you already know how to program in C, and already know how to program in Matlab. This post does not teach either language, but will show you how to use them together to get the best of both worlds.
Hello world!
Lets get started. First, type:
>>mex -setup
Then go through the menus to select a compiler that you have installed on your system. I use gcc on linux, visual studios on windows, and mexopts on mac. Now, create a file called, “helloworld.cpp” and we’ll start coding. In this first example, pay attention to the signature of the mexFunction. This signature is always the same.
#include <math.h>
#include <matrix.h>
#include <mex.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mexPrintf("Hello World!\n");
}
Save the file, and in the Matlab prompt type,
>>mex helloworld.cpp
If all goes well, you should get the following when you run helloworld:
>>helloworld
>>Hello World!
Setting Up Inputs and Outputs
Now that we have a working program, the next step is to get inputs and outputs going so we can do something useful. The mxArray pointers plhs and prhs represent a pointer to the left hand sside and a pointer to the right hand sside respectively. The left hand side are the outputs and the right hand side are the inputs.
put something like this in the top of mexFunction:
//declare variables
mxArray *a_in_m, *b_in_m, *c_out_m, *d_out_m;
const mwSize *dims;
double *a, *b, *c, *d;
int dimx, dimy, numdims;
//associate inputs
a_in_m = mxDuplicateArray(prhs[0]);
b_in_m = mxDuplicateArray(prhs[1]);
//figure out dimensions
dims = mxGetDimensions(prhs[0]);
numdims = mxGetNumberOfDimensions(prhs[0]);
dimy = (int)dims[0]; dimx = (int)dims[1];
//associate outputs
c_out_m = plhs[0] = mxCreateDoubleMatrix(dimy,dimx,mxREAL);
d_out_m = plhs[1] = mxCreateDoubleMatrix(dimy,dimx,mxREAL);
Accessing and Manipulating Matlab Objects
To access the variables, you need to associate a pointer to the data in the mxArray. Once you do this, accessing the variables is very simple.
a = mxGetPr(a_in_m);
b = mxGetPr(b_in_m);
c = mxGetPr(c_out_m);
d = mxGetPr(d_out_m);
Now it is possible to access the arrays with standard C or C++ [] notation. There are three important things to remember though:
- You use 0-based indexing as always in C
- You still use column-first indexing like in Matlab, though
- To access the arrays, you use linear indexing (you can’t use [x][y], you have to use [y+x*dimy]
With those three things in mind, go crazy. You can use standard C libraries (as long as you include them). You can use for loops as much as your heart desires, and your code will be much, much faster than its Matlab equivalent.
Downloads
Download this starter file (demo.cpp). This has all of the features discussed in this post, and should be a good primer for any mex function. Give it a try. Tell me what you think, and let me know if any improvements are needed.
To run the demo, download the .cpp file, then at the prompt run:
>>mex demo.cpp
>>a = round(rand(2)*10)
>>b = round(rand(2)*10)
>>[c,d] = demo(a,b)
It was great help, thanks for nice demo.
Could you please inform me on possible mex file references, or a user guide?
Pejman
Thank you for your short MEX tutorial
If I have 10 file.c connect between them, what will be written in the MATLAB command to compile the file that I want to execute.
for example for one file you have written “mex demo.cpp”
Thank you
To compile multiple c files use
>>mex file1.c file2.c file3.c
im using ubuntu 9.04 jaunty. gcc only failed to compile the *.cpp because it needs g++ compiler. so i installed the compiler and it worked well. thx
Interesting. I’m glad you got it working, though!
Thank you for this great tutorial :)
Hi lankton:
Your briefly written tutorial is very helpful, but I believe that you had missed something: “Free up the dynamically located memory.” which is:
mxDestroyArray(a_in_m);
mxDestroyArray(b_in_m);
@Dongcai su
Great addition.
mxFree is used in conjunction with mxCalloc
mxDestroyArray is used in conjunction with Array objects such as those created by mxCreateDoubleArray.
Hi Shawn, Why if Matlab stores matrices as column major is the ‘linear’ scheme to address specific values of a matrix in row major fashion; e.g. [x][y], you have to use [y+x*dimy], assuming x = Nrows and y = Ncols.
I have written a code to add two numbers in mex. but the code complies successfully but cannot run it can some help me
thanks in regard
#include
#include “mex.h”
#define a_IN prhs[0]
#define b_IN prhs[1]
#define c_OUT plhs[0]
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray*prhs[] )
{
double *a,*b,*c;
a = mxGetPr(a_IN);
b = mxGetPr(b_IN);
c = mxGetPr(c_OUT);
*c = *a + *b;
return;
}