The simple solution would be to convert the inputs in MATLAB to a consistent type (presumably double), but if you would like to have your MEX function handle multiple types, here is one way.
Check the input type with mxIsSingle
and mxIsDouble
(or mxIsClass
) and handle it accordingly. You might have an if
statement in mexFunction
that sets up the inputs and outputs and then calls a template function. See the example below, which thresholds all the values in an array using the C++ standard library function template std::min<T>
without requiring any data conversion.
flexibleFunction.cpp
#include "mex.h"
#include <algorithm> // std::min
template <typename T>
void threshArrayLT(T *out, const T *arr, mwSize n, T c)
{ // you allocate out
for (mwSize i = 0; i < n; ++i)
out[i] = std::min<T>(arr[i], c);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (nlhs > 1 || nrhs != 2)
mexErrMsgTxt("Syntax:\n\tH = flexibleFunction(arr,c)");
if (!mxIsDouble(prhs[0]) && !mxIsSingle(prhs[0]))
mexErrMsgTxt("Array must be double or single.");
if ((mxIsDouble(prhs[0]) && !mxIsDouble(prhs[1])) ||
(mxIsSingle(prhs[0]) && !mxIsSingle(prhs[1])))
mexErrMsgTxt("Arguments must have same type.");
const mwSize* dims = mxGetDimensions(prhs[0]);
int ndims = static_cast<int>(mxGetNumberOfDimensions(prhs[0]));
size_t numel = mxGetNumberOfElements(prhs[0]);
if (mxIsDouble(prhs[0])) {
double *arr = mxGetPr(prhs[0]);
double c = mxGetScalar(prhs[1]);
plhs[0] = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL);
threshArrayLT(mxGetPr(plhs[0]),arr,numel,c);
// In reality, if it's this simple, use std::transform with lambda or bind:
//std::transform(arr, arr+numel, mxGetPr(plhs[0]),
// [&](double s){ return std::min(s,c); });
} else if (mxIsSingle(prhs[0])) {
float *arr = (float*)mxGetData(prhs[0]);
float c = static_cast<float>(mxGetScalar(prhs[1]));
plhs[0] = mxCreateNumericArray(ndims,dims,mxSINGLE_CLASS,mxREAL);
threshArrayLT((float*)mxGetData(plhs[0]),arr,numel,c);
}
}
You can also use function overloading in C++ (same name, different argument types).
Example
>> v = rand(1,8); c = 0.5;
>> whos v c
Name Size Bytes Class Attributes
c 1x1 8 double
v 1x8 64 double
>> flexibleFunction(v,c)
ans =
0.2760 0.5000 0.5000 0.1626 0.1190 0.4984 0.5000 0.3404
>> flexibleFunction(single(v),single(c))
ans =
0.2760 0.5000 0.5000 0.1626 0.1190 0.4984 0.5000 0.3404