image thumbnail

mexme - write MEX files in no time

version 1.8.0.0 (9.75 KB) by Patrick Mineault
writes fully valid MEX .cpp files including mexFunction boilerplate based on numeric C/C++ snippet

949 Downloads

Updated 13 Nov 2012

View License

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.).

Cite As

Patrick Mineault (2021). mexme - write MEX files in no time (https://www.mathworks.com/matlabcentral/fileexchange/31257-mexme-write-mex-files-in-no-time), MATLAB Central File Exchange. Retrieved .

MATLAB Release Compatibility
Created with R2008b
Compatible with any release
Platform Compatibility
Windows macOS Linux
Acknowledgements

Inspired by: verbatim: Get the text of a block comment.

Inspired: Fast B-spline class

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!