我想运行一个名为" hello1.c"的两个C程序。和" hello2.c"来自matlab。
我的hello1.c
代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <mex.h>
#include <math.h>
#include "matrix.h"
void funcc(double **f, double **x, long n, long b, double lambda, double theta)
{
long i;
long j;
double u,v,y,z,w;
y = theta*lambda;
w = lambda*lambda;
z = 0.5*(theta+1.0)*w;
u = 0.0;
for(i=0;i<n;i++)
{
for(j=0;j<b;j++)
v = fabs(x[i][j]);
if (v <= lambda)
u += lambda*v;
else if (v > y)
u += z;
else
u += 0.5*(v*(2*y - v) - w)/(theta-1.0);
}
**f = u;
return;
}
void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
/*set up input arguments */
double **x = mxGetPr(prhs[0]);
long n = (long)mxGetScalar(prhs[1]);
long b = (long)mxGetScalar(prhs[2]);
double lambda = mxGetScalar(prhs[3]);
double theta = mxGetScalar(prhs[4]);
int type = (int)mxGetScalar(prhs[5]);
double **f;
/* set up output arguments */
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
f=mxGetPr(plhs[0]);
funcc(f, x, n, b, lambda, theta);
}
我的hello2.c
代码如下:
long mymin(double *x, long n)
{
long i, ind;
double temp;
temp = x[0];
ind = 0;
for (i=1;i<n;i++)
{
if (x[i] < temp)
{
ind = i;
temp = x[i];
}
}
return ind;
}
void funnn(double *x, double *d, long n, long b, double lambda, double theta)
{
long i;
long j;
double u,z,w;
double xtemp[3],ytemp[3];
z = theta*lambda;
w = lambda*lambda;
for(i=0;i<n;i++)
{
for(j=0;j<b;j++)
u = fabs(d[j*n + i]);
xtemp[0] = min(lambda,max(0,u - lambda));
xtemp[1] = min(z,max(lambda,(u*(theta-1.0)-z)/(theta-2.0)));
xtemp[2] = max(z,u);
ytemp[0] = 0.5*(xtemp[0] - u)*(xtemp[0] - u) + lambda*xtemp[0];
ytemp[1] = 0.5*(xtemp[1] - u)*(xtemp[1] - u) + 0.5*(xtemp[1]*(-xtemp[1] + 2*z) - w)/(theta-1.0);
ytemp[2] = 0.5*(xtemp[2] - u)*(xtemp[2] - u) + 0.5*(theta+1.0)*w;
x[j*n + i] = xtemp[mymin(ytemp,3)];
x[j*n + i] = d[j*n + i]>= 0 ? x[j*n + i] : -x[j*n + i];
}
//return;
}
void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
/*set up input arguments */
double* d = mxGetPr(prhs[0]);
long n = (long)mxGetScalar(prhs[1]);
long b = (long)mxGetScalar(prhs[2]);
double lambda = mxGetScalar(prhs[3]);
double theta = mxGetScalar(prhs[4]);
double *x;
/* set up output arguments */
plhs[0] = mxCreateDoubleMatrix(n,b,mxREAL);
x=mxGetPr(plhs[0]);
funnn(x, d, n, b, lambda, theta);
}
问题在于,当我编译我的MATLAB代码时,它调用了我的C函数(当然我已经编写了mex hello1.c
和mex hello2.c
),MATLAB返回显示MATLAB具有的屏幕遇到内部问题,需要关闭。事实上,在MEX文件运行时检测到了这个错误。
这是因为我的函数mexFunction
编写不正确吗?任何知道如何编写MEX功能的人都可以帮助我吗?
非常感谢任何帮助!
答案 0 :(得分:2)
对于hello1.c
,MEX中的mxGetPr
不会为您提供双指针。它为您提供单个指针,对于2D内存,它采用列主要布局。您必须通过以下语法访问2D数组中的正确值,前提是i
和j
是您要访问的2D数组中的行和列:
ind = j*rows + i;
...因此,如果您想在2D数组(i,j)
中找到位置x
,只需执行以下操作:
double val = x[j*rows + i];
rows
是2D数组中的总行数。因此,您必须在代码中更正此问题才能正确访问2D阵列。您还必须对f
执行相同的操作。另外,你在第二个for
循环周围缺少一对花括号,我将在后面解释原因。
因此,您的功能变为:
void funcc(double *f, double *x, long n, long b, double lambda, double theta) // Note change in function declaration
{
long i;
long j;
double u,v,y,z,w;
y = theta*lambda;
w = lambda*lambda;
z = 0.5*(theta+1.0)*w;
u = 0.0;
// n is the rows, b is the columns
for(i=0;i<n;i++)
{
for(j=0;j<b;j++) { // Added
v = fabs(x[j*n + i]); // Change here
if (v <= lambda)
u += lambda*v;
else if (v > y)
u += z;
else
u += 0.5*(v*(2*y - v) - w)/(theta-1.0);
} // Added
}
*f = u; // Change
//return; // Superfluous
}
您的mexFunction
现在变为:
void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
/*set up input arguments */
double *x = mxGetPr(prhs[0]); // Change
long n = (long)mxGetScalar(prhs[1]);
long b = (long)mxGetScalar(prhs[2]);
double lambda = mxGetScalar(prhs[3]);
double theta = mxGetScalar(prhs[4]);
int type = (int)mxGetScalar(prhs[5]);
double *f; // Change
/* set up output arguments */
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
f=mxGetPr(plhs[0]);
funcc(f, x, n, b, lambda, theta);
}
对于hello2.c
,除了第二个for
循环外,一切都很好。您只需要用花括号括起代码块:
for(i=0;i<n;i++)
{
for(j=0;j<b;j++) { // added
u = fabs(d[j*n + i]);
xtemp[0] = min(lambda,max(0,u - lambda));
xtemp[1] = min(z,max(lambda,(u*(theta-1.0)-z)/(theta-2.0)));
xtemp[2] = max(z,u);
ytemp[0] = 0.5*(xtemp[0] - u)*(xtemp[0] - u) + lambda*xtemp[0];
ytemp[1] = 0.5*(xtemp[1] - u)*(xtemp[1] - u) + 0.5*(xtemp[1]*(-xtemp[1] + 2*z) - w)/(theta-1.0);
ytemp[2] = 0.5*(xtemp[2] - u)*(xtemp[2] - u) + 0.5*(theta+1.0)*w;
x[j*n + i] = xtemp[mymin(ytemp,3)];
x[j*n + i] = d[j*n + i]>= 0 ? x[j*n + i] : -x[j*n + i];
} //added
}
为什么需要两个文件的额外大括号的原因是因为如果省略它们,C只会将循环后的第一行视为循环体。 for
循环结束后的其余代码将被执行,而不是循环的一部分,这就是您获得分段错误的原因。