Wednesday, March 23, 2016

working with mex c++ files in MATLAB

I found this good tutorial for hello world mex file together with good demo to deal with matrices

http://www.shawnlankton.com/2008/03/getting-started-with-mex-a-short-tutorial/

For debugging I used the instructions in the following link

http://www.mathworks.com/help/matlab/matlab_external/debugging-on-microsoft-windows-platforms.html

The following link contains setup of How to work with mex files in visual studio 2008

http://comisef.wikidot.com/tutorial:using-c-c-under-matlab-part-2

An introductory example multiply vector by scalar (Multiply a scalar times 1xN matrix.) can be found in the following list of examples

http://www.mathworks.com/help/matlab/matlab_external/table-of-mex-file-source-code-files.html

Here is a working example named arrExample.cpp of extracting sub-array(B or block) from big array (Img or Image).
Example : Extracting sub-matrix at location 6,6 with block size = 3 x 3

>> a=[10:19];a=repmat(a,10,1)
a =

    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
    10    11    12    13    14    15    16    17    18    19
>> k=arrExample(a)

k =

    16    17    18
    16    17    18
    16    17    18

The c++ source code of arrExample is shown here

#include
#include "mex.h"
#define m 10
#define n 10 

void blockExtract(double *B,mwSize b_i_start,mwSize b_j_start,mwSize b_size,double *Img)
{
  mwSize i,j;
  mwSize r=-1,c=0;
  
  for (i=b_i_start; i
      r++;
      for(j=b_j_start; j
      {
           B[r*b_size+c]=Img[i*m+j];
           c++;
      }
      c=0;
  }
}

void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    if(nrhs != 1)
    {
        mexErrMsgIdAndTxt("myToolBox:nrhs","Osama:Only one input is needed");
    }
    if(nlhs != 1)
    {
        mexErrMsgIdAndTxt("myToolBox:nrhs","Osama: must have one output");
    }
    if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxGetNumberOfElements(prhs[0]) != m*n )
    {
        mexErrMsgIdAndTxt("myToolBox:nrhs","Osama: Invalid input matrix size,it must by 256 x 256");
    }
    if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])) 
    {
         mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble","Osama:Input matrix must be type double.");
    }
    const mxArray *inMatrix; 
    mxArray *outMatrix;
    double *inPtr,*outPtr;
    
    inMatrix = mxDuplicateArray(prhs[0]);
    inPtr = mxGetPr(prhs[0]);
    
    outMatrix=plhs[0] = mxCreateDoubleMatrix(3,3,mxREAL);
    outPtr = mxGetPr(outMatrix);
    
    blockExtract(outPtr,6,6,3,inPtr);
    
    return;
}

No comments:

Post a Comment