mexme automates the process of writing MEX files. You give mexme a snippet of C which just does numeric computations, as well a list of arguments, and it generates a valid MEX .cpp file. The generated code compiles in Linux (gcc) and in Windows (Visual Studio C++). New in version 1.1, it writes tedious input and output validation code for you. This way you can write a MEX file without manually coding calls to mx* API functions. It's inspired by SciPy's weave function.

Example: translate this piece of (non-vectorizable) .m code that applies a recursive filter into C:

function [y] = myrecursivefilter(x,alpha)

y = zeros(size(x));

y(1) = x(1)*alpha;

for ii = 2:length(x)

y(ii) = y(ii-1)*(1-alpha) + x(ii)*alpha;

end

end

Step 1: Write myrecursivefilter.csnip which does the same thing as the m file:

y[0] = x[0]*alpha;

for(mwSize i = 1; i < x_length; i++) {

y[i] = x[i]*alpha + y[i-1]*(1-alpha);

}

Step 2: Define arguments to your function (in Matlab):

inputargs = [InputNum('x'),...

InputNum('alpha',true,true,'double','alpha > 0 && alpha < 1)]; %scalar

%The last condition

outputarg = OutputNum('y','x_length,1');

Step 3: Generate a fully fledged .c file that can be compiled with mex:

cfile = mexme('myrecursivefilter.csnip',inputargs,outputarg)

writefile('myfilt.c',cfile);

mex myfilt.c

x = randn(1e6,1);

y = myfilt(x,.1);

plot([x,y])

cfile =

/*#include and #define not shown*/

#include "mexmetypecheck.c"

void mexFunction( int nlhs, mxArray *plhs[],

int nrhs, const mxArray *prhs[] )

{

/*Input output boilerplate*/

if(nlhs != 1 || nrhs != 2)

mexErrMsgTxt("Function must be called with 2 arguments and has 1 return values");

const mxArray *x_ptr = prhs[0];

const mwSize x_m = mxGetM(x_ptr);

const mwSize x_n = mxGetN(x_ptr);

const mwSize x_length = x_m == 1 ? x_n : x_m;

const mwSize x_numel = mxGetNumberOfElements(x_ptr);

const int x_ndims = mxGetNumberOfDimensions(x_ptr);

const mwSize *x_size = mxGetDimensions(x_ptr);

const double *x = (double *) mxGetData(x_ptr);

const mxArray *alpha_ptr = prhs[1];

if(mxGetNumberOfElements(alpha_ptr) != 1)

mexErrMsgTxt("Argument alpha (#2) must be scalar");

const double alpha = (double) mxGetScalar(alpha_ptr);

if(!(alpha > 0 && alpha < 1))

mexErrMsgTxt("Argument alpha (#2) did not pass test \"alpha > 0 && alpha < 1\"");



mwSize y_dims[] = {x_length,1};

plhs[0] = mxCreateNumericArray(2,y_dims,mxDOUBLE_CLASS,mxREAL);

mxArray **y_ptr = &plhs[0];

double *y = (double *) mxGetData(*y_ptr);



/*Actual function*/

#include "myfilt.csnip"

}

For every argument that you define, mexme generates extra "magic" variables. For example, if the variable is x, then in C:

x is the data

x_m is the size of the first dimension

x_n is the size of the second dimension

x_length is the length of a vector

x_numel is the number of elements in an array

x_ndims is the numer of dimensions

x_size is equivalent to the Matlab code size(x)

x_ptr is a reference to the mxArray that contains the x data

And if x is complex, x_r and x_i are the real and imaginary components of the data.

mexme currently does not support sparse data or non-numeric types but it does support full numeric arrays of any type (int8, single, double, etc.).