Creating MEX files - Part 1
I've recently been working on some slightly more elaborate codes that are quite time intensive (several hours). When I took a look at the results running the profiler, I found that the majority of this time was being consumed by a single function that contained a quite large, yet unavoidable FOR loop. In these cases, it makes sense to try and dig out your old C books and have a go at making a MEX file.
I am no C programmer. I can just about work out what a block of C code is doing if I need to reproduce an algorithm but I see and use it so infrequently that I am certainly at level basic. The following is provided as a kind of beginners guide to how MEX functions work for those who don't really know a great deal about C.
To start with, we are going to create a MEX file that takes an MxN array of doubles and outputs them to file with a user defined separator.
The basics of a MEX file looks like this:
int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* C code goes here */
}
What does this mean?
- void mexFunction: the name of the gateway routine; Basically a wrapper function that tells MATLAB to get ready to work with C code
- int nlhs: 'number of parameters, left hand side'
- mxArray plhs: an array of 'parameters, left-hand side'. In other words, the function outputs just like you'd see on the left hand side of any function definition in a standard .M file
- int nrhs: 'number of parameters, right hand side'
- mxArray prhs: an array of 'parameters, right-hand side'. In other words, the function inputs just like you'd see on the right hand side of a function definition in any standard .M file
Now for the C code. Open a blank text file called 'dumptofile.c'. Our first few lines will now tell MATLAB which libraries must be included in order for our MEX file to work. We don't need any extra libraries here. Put the following lines to your file:
#include "mex.h"
void mexFunction(
int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* C code goes here */
}
The first line is extremely important in that it gives us access to the mx* and mex* routines that we will use to communicate with MATLAB.
All that is left to do now is add the necessary C code to get the input parameters (prhs) and loop through the array of doubles. Take note of the functions that are used that begin 'mx'; these are functions that are specific to MEX files. If you can't work out what they are doing, I suggest you take a bit of time to do some reading on each of them.
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// ============================================
// Declarations
// ============================================
mxArray *inputArrayData; // array for input array pointers
double *inputArrayValues; // input array
mxArray *filepathData; // array for filepath pointers
int filepathLength; // length of the filename in characters
char *filepath; // path for output file
mxArray *seperatorData; // array for seperator pointers
int seperatorLength; // length of seperator
char *seperator; // seperator
int M, N; // dimensions of the input array
int i,j; // counters for looping through array
double value; // variable to hold array value
FILE *fid; // File identifier
/* Check number of input arguments */
if(nrhs!=3) {
mexErrMsgTxt("Three arguements are required for dumptofile") ;
}
/* Check first input argument is numeric */
if(!mxIsNumeric(prhs[0]) ) {
mexErrMsgTxt("First input must be numeric") ;
}
/* Check second input argument is a string (filepath) */
if( mxIsChar(prhs[1]) != 1) {
mexErrMsgTxt("Second input must be a string") ;
}
// copy pointers
inputArrayData = prhs[0];
filepathData = prhs[1];
seperatorData = prhs[2];
// Get input array and its dimensions
inputArrayValues = mxGetPr(inputArrayData);
M = mxGetM(inputArrayData);
N = mxGetN(inputArrayData);
//Get the filename
filepathLength = mxGetN(filepathData)+1;
filepath = mxCalloc(filepathLength, sizeof(char)); //mxCalloc is similar to malloc in C
mxGetString(filepathData,filepath,filepathLength);
// Get the seperator
seperatorLength = mxGetN(seperatorData)+1;
seperator = mxCalloc(seperatorLength, sizeof(char)); //mxCalloc is similar to malloc in C
mxGetString(seperatorData,seperator,seperatorLength);
// Try and create the file
fid = fopen(filepath, "wt");
// print in the order they are in memory
for(i=0; i < M; i++) {
for(j=0; j < N; j++) {
// Get the corrisponding value
value = inputArrayValues[i + j*M];
// Write the value to file
fprintf(fid, "%f",value);
if (j < N-1) {
fprintf(fid, "%s",seperator);
}
}
fprintf(fid, "\n");
}
// Close the file
fclose(fid);
}
Now we need to turn this C code into a MEX file. Open MATLAB and make sure dumptofile.c is in the working directory. On the command line, run "mex dumptofile.c". This should produce a new file with an extension that looks something like ".mexw32".
That's it. Lets test it by comparing it to dlmwrite::
double_array = rand(10000,1);
tic
dlmwrite('C:\output\test.txt', double_array, ',');
times.dlmwrite = toc;
tic;
dumptofile(double_array, 'C:\output\test.txt', ',');
times.dumptofile = toc
Did you find this useful? Do you have comments on how it could be improved? Please leave your comments below

The United States would only
The United States would only benefit from the reconnection with the Native Americans because there is far more to the world that could be better pass4sure 642-456 understood through their eyes rather than the shallow opinions of today's society. Native Americans have always been known to be earthy people who maintain a healthy relationship with the earth. If society would reconnect with the Indians it pass4sure CISA would help in better understanding the present because in order to understand the present fully one must know the past and understand it completely. The society of United States would greatly benefit from learning from the past mistakes done by either United States or Native Americans. Americans and Native Americans didn't get along very well in the past, but with a little more help and determination a bond may form pass4sure 642-262 through personal matters. Personal matters affect all people no matter what race they are. All humans are affected by their surroundings in some way and this is a way in which all humans relate. To reconnect with the Native Americans would mean that the United States would become closer to the environment and in a way more spiritual towards the world. Indians teaching Americans to be more spiritual isn't like a pass4sure 642-357 religious spiritual; it is a strong relationship that is constantly growing.
Native Ame