Mex Files – 2

So continuing from the previous post, (1), we shall see how to start writing Mex code, by considering the following simple example of a uniform quantizer. Setup is assumed ready and done.

First and foremost, the filename should be “function_name.c” and not a “.m”. Once compiled, its this function_name that you will call in your other simulation running codes. Instead of the usual includes, we now use the “mex.h” header file. Note that other header files also may work, as this example will present the usage of “math.h” for the round() function.

Then, instead of the standard void main() we now start with a special type of function called mexFunction() and it can be used as follows. Note that the mexFunction is a generic name given to all mex file codes, it’s not the name of the function you want to write. So the first few lines look like this

#include "mex.h"
#include "math.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

nlhs and nrhs are the number of arguments, and *plhs and *prhs are Matlab compatible pointer array references on the output (left) and input (right) side respectively. All this seems quite complicated at first, but it’s not once you actually write one code. Just one!

So, we now need to obtain the location of the data, which is passed on to the function during the call. This is done by using the function mxGetPr(prhs[i]). For example

double *X, *nbits, *Xmax;
X = mxGetPr(prhs[0]);
nbits = mxGetPr(prhs[1]);
Xmax = mxGetPr(prhs[2]);

As this indicates, the vector to be quantized to nbits (2nd input variable) is X, the first input variable; and the maximum quantization value is Xmax, the third input variable.

More information about the dimensions of the vector or matrix can be found by using functions like Xdim = (int)mxGetM(prhs[0]) for no. of rows and mxGetN() for columns.

In case you need to create any temporary variables, typically mxMalloc() is used. However, be sure to free the memory at the end of the program by mxFree(), but we will cover this in the next post. Now we need to allocate memory for the output arguments, and assign them to pointers. Note the usage of mxCreateDoubleMatrix().

double *y, *step;
plhs[0] = mxCreateDoubleMatrix(Xdim, 1, mxREAL);
y = mxGetPr(plhs[0]);
plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL);
step = mxGetPr(plhs[1]);

where our first output argument y is the quantized vector, and the second is the computed step-size (using nbits and Xmax). The easy part of this is, the function is always mxCreateDoubleMatrix() with changes in the dimensions. Indicating Real or Complex is done by using mxREAL or mxCOMPLEX.

Once this is done, the rest of the code is like any other C code using pointers. One word of caution would be to take care of the dimensions, not to confuse between rows and columns, as this could mess up your code and take a long time to debug.

Try it out, and notice the speed-up! There are many more points, but this post is too long already 🙂 More on this, some time later. Although, at this point, the reader has sufficient knowledge to write simple mex codes on their own. Find the code here.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s