Calling c function (or mex c function) from MATLAB Function block operating on pointers

4 views (last 30 days)
In one of my projects I've to solve an iterative problem requiring an interpolation each step. Because the interp1 of MATLAB isn’t the fastest if you’ve to do that a few thousand to million of times, I would like to speed up the project with a c function for interpolation. A very fast 1D implementation nakeinterp1 exists from Bruno ( http://www.mathworks.com/matlabcentral/newsreader/view_thread/258413#672827 ) written as a mex function in C.
Because the code inside the MATLAB function block is called in a Simulink model or from another parent Matlab function, it has to be flexible an efficient for the Simulink and Matlab environment. With coder.target it’s possible to determine in which environment the code runs, so I can call the mex function directly in the Matlab environment and the speed gain compared to interp1 is dramatically. Sadly it’s not that easy to call the mex function from Simulink MATLAB function block. Therefore the coder.ceval(‘myFunction’,arguments…) has to be used.
Now to my question: How do I use coder.ceval for calling the nakeinterp1 function from Bruno (link see above, code below). The problem here is that the function works on pointers and not like the example doubleIt on doubles. And if this is possible, what I hope, will it be possible also in rapid accelerator mode?
Bruno’s nakeinterp1:
nakeinterp1.c:
/* mex Function nakeinterp1.c */
//////////////////////////////////////////////////////////////////////////
// mex function nakeinterp1.c
// Dichotomy search of indices
// Calling:
// idx=nakeinterp1(x, y, xi);
// where x, y and xi are double column vectors
// x must be sorted in ascending order; x and y have the same length
// NO ARGUMENT CHECKING
// Compile:
// mex -O -v nakeinterp1.c
// Author: Bruno Luong
// Original: 19/Feb/2009
//////////////////////////////////////////////////////////////////////////
#include "mex.h"
#include "matrix.h"
// Gateway routine
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
const mxArray *xi, *xgrid;
mxArray *idx;
size_t nx, m, k, i1, i9, imid;
double *xiptr, *yptr, *xgridptr, *idxptr;
double xik;
mwSize dims[2];
// Get inputs and dimensions
xgrid = prhs[0];
nx = mxGetM(xgrid);
xi = prhs[2];
m = mxGetM(xi);
// Create output idx
dims[0] = m; dims[1] = 1;
plhs[0] = idx = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
if (idx==NULL) // Cannot allocate memory
{
// Return empty array
dims[0] = 0; dims[1] = 0;
plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
return;
}
idxptr = mxGetPr(idx);
// Get pointers
xiptr = mxGetPr(xi);
yptr = mxGetPr(prhs[1]);
xgridptr = mxGetPr(xgrid);
// Loop over the points
for (k=m; k--;) // Reverse of for (k=0; k<m; k++) {...}
{
// Get data value
xik = xiptr[k];
i1=0;
i9=nx-1;
while (i9>i1+1) // Dichotomy search
{
imid = (i1+i9+1)/2;
if (xgridptr[imid]<xik) i1=imid;
else i9=imid;
} // of while loop
if (i1==i9)
idxptr[k] = yptr[i1];
else
idxptr[k] = yptr[i1] + (yptr[i9]-yptr[i1])*(xik-xgridptr[i1])/(xgridptr[i9]-xgridptr[i1]);
} // for loop
return;
}
nakeinterp1.h
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]);

Answers (0)

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!