2

I have a simple MATLAB code as

function val = mul( u, v )
u_v_bigger=( u > 255 )|( v > 255 );
if (u_v_bigger)
    error(['Input values larger than allowed!]);
end    
OCT_EXP = [1, 2, 4, 8, 16, 32, 64];
OCT_LOG = [ 0, 1, 25, 2, 50, 26, 198];    
u_v_zeros=( u == 0 )|( v == 0 );
if (u_v_zeros)
    val = 0;
else
    val = OCT_EXP( OCT_LOG(u) + OCT_LOG(v) + 1);     
end

I can call it by using

val(1:3)=mul( [1 3 5], [2 4 5] )

Now, I rewrite it by using MEX to speed up the code. My mex code mul_fast.cpp is

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray* prhs[])
{
    static const int OCT_LOG[] = {0, 1, 25, 2, 50, 26,198};
    static const int OCT_EXP[] ={1, 2, 4, 8, 16, 32, 64};
    double* u_vec = mxGetPr(prhs[0]);
    double* v_vec = mxGetPr(prhs[1]);
    int u;
    int v;    
    mwSize length_1 = mxGetN(prhs[0]);
    double *result = (double*) malloc(length_1*sizeof(double));    
    for (int i=0;i<length_1;i++){
        u=(int)u_vec[i];
        v=(int)v_vec[i];
        if (u>255 || v>255 )
            mexErrMsgTxt("Input values larger than allowed");
        else if (u==0 || v==0 )
            result[i] = 0;
        else {
            result[i] = OCT_EXP[OCT_LOG[u-1] + OCT_LOG[v-1]];
        }
    }
    plhs[0] = mxCreateDoubleMatrix(1, length_1, mxREAL);
    memcpy(mxGetPr(plhs[0]), result, length_1*sizeof(double));    
    // dellocate heap space
    free(result);
}

I compared two results from MATLAB and MEX codes and it worked well. However, in my MEX code, I found an issue that needs your suggestions. Because index u,v in the OCT_EXP and OCT_LOG must be an integer type, hence I need to convert from double to int by u=(int)u_vec[i]; in the loop. I think we can have a better way to pass an integer array to mex. Am I right?

Jame
  • 3,746
  • 6
  • 52
  • 101
  • 1
    The function you're looking for is `mxGetData` – Matt Oct 11 '17 at 02:26
  • Thanks Matt and rayryeng, I did try `int* u_vec=(int*)mxGetData(lhs[0]);`, but it shows wrong number and length of the `u_vec`. What should I used `mxGetData`? – Jame Oct 11 '17 at 02:42
  • Note that, my input will be `mul_fast([1 3 5], [2 4 5])`, instead of `mul_fast(int32([1 3 5]), int32([2 4 5]))` – Jame Oct 11 '17 at 03:13
  • Unless this is a simplified example of what you're actually doing, I'd be very surprised if this is a significant performance optimization. You're essentially doing a single element Look Up Table operation in MATLAB vs. C. I'm having a tough time imagining you're going to save significant run time this way. On the other hand, I could imagine maybe a slight advantage to using persistent to declare the LUTs. – Alex Taylor Oct 11 '17 at 11:53
  • Hi, you are right that MATLAB and C give similar performance in scale case. But in the vector case, C is faster 4 times – Jame Oct 11 '17 at 13:22

0 Answers0