【发布时间】:2016-08-26 21:32:29
【问题描述】:
我编写了一个 MATLAB 脚本,其中我传递了几个标量和一个行向量作为 mex 函数的输入参数,在进行一些计算之后,它返回一个标量作为输出。必须对大小为 1 X 1638400 的数组的所有元素执行此过程。下面是相应的代码:
ans=0;
for i=0:1638400-1
temp = sub_imed(r,i,diff);
ans = ans + temp*diff(i+1);
end
其中 r,i 是标量,diff 是大小为 1 X 1638400 的向量,sub_imed 是执行以下工作的 MEX 函数:
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);
}
有关问题和下划线算法的更多详细信息,请关注线程Euclidean distance between images。
我对我的 MATLAB 脚本进行了分析,发现它需要 63 秒。仅用于对 sub_imed() mex 函数的 387 次调用。因此,对于 sub_imed 的 1638400 次调用,理想情况下需要大约 74 小时,这太长了。
有人可以通过建议一些替代方法来帮助我优化代码以减少计算时间。
提前致谢。
【问题讨论】:
-
这个 mex 函数是你写的吗?你为什么使用 mex 而不是 MATLAB?
-
是的..实际上没有 mex 需要更长的时间..所以我认为为内部循环编写一个 mex 函数是个好主意,它可能会降低我的运行成本。
-
好的,
dim是什么?我猜是size(diff)? -
是的..你是对的。
-
几个计算:例如。
l = (base%200) + 1;或(1/(2*pi*pow(r,2)))/(2*pow(r,2))可以移到 for 循环之外...
标签: arrays matlab optimization