Summary: This is a basic guide to writing mex files for MATLAB in C. This guide gives a simple background of some the MATLAB mex features so that learning to write mex files can be quick and easy.
//You can include any C libraries that you normally use
#include "math.h"
#include "mex.h" //--This one is required
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
//All code and internal function calls go in here!
return;
}
[z0,z1] = jasonsFunction(x,y,z);)
nlhs (Type = int): This paramter represents the number of "left hand side" arguments. So in my example
function call, nlhs = 2 (the outputs are z0 and z1).plhs (Type = array of pointers to mxArrays): This parameter is the actual output arguments. As we will see
later, an mxArray is MATLAB's structure for holding data and each element in plhs holds an mxArray of data.nrhs (Type = int): Similar to nlhs, this paramter holds the number of "right hand side" arguments.prhs (Type = const array of pointers to mxArrays): This array hold all of the pointers to the mxArrays of input data
for instance, prhs[0] holds the mxArray containing x, prhs[1] holds the mxArray containing y, etc).[z0,z1] = jasonsFunction(x,y,z);).
Assume that x is a 2-D matrix, y is a string, and z is an integer. Here we wills ee how to extract
and use these different types of data.
//---Inside mexFunction---
//Declarations
mxArray *xData;
double *xValues;
int i,j;
int rowLen, colLen;
double avg;
//Copy input pointer x
xData = prhs[0];
//Get matrix x
xValues = mxGetPr(xData);
rowLen = mxGetN(xData);
colLen = mxGetM(xData);
//Print the integer avg of each col to matlab console
for(i=0;i<rowLen;i++)
{
avg=0;
for(j=0;j<colLen;j++)
{
avg += xValues[(i*colLen)+j];
//Another Method:
//
//avg += *xValues++;
}
avg = avg/colLen;
printf("The average of row %d, is %d",i,(int)avg);
}
mxGetPr is used to get a pointer to the real data xData. This function takes a
pointer to an mxArray as the intput paramter, and returns a pointer array of doubles. A similar function
mxGetPi can be used for complex data. mxGetN and mxGetM return
integers of the lengths of the row and column in the matrix. If this were an array of data, one of these
return values would be zero. MATLAB gives the matrix as rows first, then columns (if you were to traverse
the matrix linearly) so to jump by position, (x,y) maps to x*colLen+y. MATLAB organizes
its arrays this way to reduce cache misses when the row traversal is on the outside loop. It is good to
code it this way if you are working for efficiency. printf()
will print out to the MATLAB command prompt.
//---Inside mexFunction---
//Declarations
mxArray *yData;
int yLength;
char *TheString;
//Copy input pointer y
yData = prhs[1];
//Make "TheString" point to the string
yLength = mxGetN(yData)+1;
TheString = mxCalloc(yLength, sizeof(char)); //mxCalloc is similar to malloc in C
mxGetString(yData,TheString,yLength);
//---Inside mexFunction---
//Declarations
mxArray *zData;
int Num;
//Copy input pointer z
zData = prhs[2];
//Get the Integer
Num = (int)(mxGetScalar(zData));
//print it out on the screen
printf("Your favorite integer is: %d",Num);
//---Inside mexFunction---
//Declarations
mxArray *xData;
double *xValues, *outArray;
int i,j;
int rowLen, colLen;
//Copy input pointer x
xData = prhs[0];
//Get matrix x
xValues = mxGetPr(xData);
rowLen = mxGetN(xData);
colLen = mxGetM(xData);
//Allocate memory and assign output pointer
plhs[0] = mxCreateDoubleMatrix(colLen, rowLen, mxREAL); //mxReal is our data-type
//Get a pointer to the data space in our newly allocated memory
outArray = mxGetPr(plhs[0]);
//Copy matrix while multiplying each point by 2
for(i=0;i<rowLen;i++)
{
for(j=0;j<colLen;j++)
{
outArray[(i*colLen)+j] = 2*xValues[(i*colLen)+j];
}
}
//---Inside mexFunction---
//Declarations
mxArray *result;
mxArray *arguments[2];
//Fill in the input parameters with some trash
arguments[0] = mxCreateDoubleMatrix(1, 20, mxREAL);
arguments[1] = mxCreateDoubleMatrix(1, 10, mxREAL);
//In the real world I imagine you would want to actually put
//some useful data into the arrays above, but for this example
//it doesnt seem neccesary.
//Call the Function
mexCallMATLAB(1,&result,2,arguments,"conv");
//Now result points to an mxArray and you can extract the data as you please!
mex filename.c into the MATLAB
command window. MATLAB may ask you to choose a compiler. Choose the compiler with MATLAB in its directory path.
Your function will be called with the same name as your file. (ex: mex jasonsFunction.c
produces a function that can be called from MATLAB as [z0,z1] = jasonsFunction(x,y,z);)
Comments, questions, feedback, criticisms?