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
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
void mexFunction(int nlhs, mxArray *plhs, int nrhs, const mxArray *prhs)
nrhs are the number of arguments, 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);
nbits = mxGetPr(prhs);
Xmax = mxGetPr(prhs);
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) 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
double *y, *step;
plhs = mxCreateDoubleMatrix(Xdim, 1, mxREAL);
y = mxGetPr(plhs);
plhs = mxCreateDoubleMatrix(1, 1, mxREAL);
step = mxGetPr(plhs);
where our first output argument
y is the quantized vector, and the second is the computed step-size (using
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
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.