I wrote a MATLAB script in which I am passing few scalars and one row vector as input arguments of a mex function and after doing some calculation, it is returning a scalar as output. This process has to be done for all the elements of an array whose size is 1 X 1638400. Below is the corresponding code:
ans=0;
for i=0:1638400-1
temp = sub_imed(r,i,diff);
ans = ans + temp*diff(i+1);
end
where r,i are scalars, diff is a vector of size 1 X 1638400 and sub_imed is a MEX function which does the below job:
void sub_imed(double r,mwSize base, double* diff, mwSize dim, double* ans)
{
mwSize i,k,l,k1,l1;
double d,g,temp;
for(i=0; i<dim; i++)
{
k = (base/200) + 1;
l = (base%200) + 1;
k1 = (i/200) + 1;
l1 = (i%200) + 1;
d = sqrt(pow((k-k1),2) + pow((l-l1),2));
g=(1/(2*pi*pow(r,2)))*exp(-(pow(d,2))/(2*(pow(r,2))));
temp = temp + diff[i]*g;
}
*ans = temp;
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
double *diff; /* Input data vectors */
double r; /* Value of r (input) */
double* ans; /* Output ImED distance */
size_t base,ncols; /* For storing the size of input vector and base */
/* Checking for proper number of arguments */
if(nrhs!=3)
mexErrMsgTxt("Error..Three inputs required.");
if(nlhs!=1)
mexErrMsgTxt("Error..Only one output required.");
/* make sure the first input argument(value of r) is scalar */
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxGetNumberOfElements(prhs[0])!=1)
mexErrMsgTxt("Error..Value of r must be a scalar.");
/* make sure that the input value of base is a scalar */
if( !mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || mxGetNumberOfElements(prhs[1])!=1)
mexErrMsgTxt("Error..Value of base must be a scalar.");
/* make sure that the input vector diff is of type double */
if(!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]))
mexErrMsgTxt("Error..Input vector must be of type double.");
/* check that number of rows in input arguments is 1 */
if(mxGetM(prhs[2])!=1)
mexErrMsgTxt("Error..Inputs must be row vectors.");
/* Get the value of r */
r = mxGetScalar(prhs[0]);
base = mxGetScalar(prhs[1]);
/* Getting the input vectors */
diff = mxGetPr(prhs[2]);
ncols = mxGetN(prhs[2]);
/* Creating link for the scalar output */
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
ans = mxGetPr(plhs[0]);
sub_imed(r,base,diff,(mwSize)ncols,ans);
}
For more details about the problem and the underlining algorithm please follow the thread Euclidean distance between images.
I did a profiling of my MATLAB script and got to know that it is taking 63 sec. just for 387 calls to sub_imed() mex function. So for 1638400 calls to sub_imed, ideally it will take around 74 hours which is just too long.
Can someone please help me to optimize the code by suggesting some alternative ways to reduce the time taken for computation.
Thanks in advance.