如何编写这个c文件的mexFunction

该函数是cyclic.c

  void cyclic(float a[], float b[], float c[], float alpha, float beta, float r[], float x[], unsigned long n) // Solves for a vector x[1..n] the “cyclic” set of linear equations. a, //b, c, and r are input vectors, all dimensioned as [1..n], while alpha and beta are //the corner // entries in the matrix. 

我是Matlab和C之间接口的新手。我已经好几年没用C了。 昨晚,我完成了它并编译。 最后一件事是打电话给它。

 #include "mex.h" #include "nrutil.h" #define FREE_ARG char* #define NR_END 1 #include  #include  #include  #define NR_END 1 #define FREE_ARG char* void nrerror(char error_text[]) /* Numerical Recipes standard error handler */ {fprintf(stderr,"Numerical Recipes run-time error...\n"); fprintf(stderr,"%s\n",error_text); fprintf(stderr,"...now exiting to system...\n"); exit(1); } float *vector(long nl, long nh) /* allocate a float vector with subscript range v[nl..nh] */ { float *v; v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float))); if (!v) nrerror("allocation failure in vector()"); return v-nl+NR_END; } void free_vector(float *v, long nl, long nh) /* free a float vector allocated with vector() */ { free((FREE_ARG) (v+nl-NR_END)); } void tridag(float a[], float b[], float c[], float r[], float u[], unsigned long n) { unsigned long j; float bet,*gam; gam=vector(1,n); if (b[1] == 0.0) nrerror("Error 1 in tridag"); u[1]=r[1]/(bet=b[1]); for (j=2;j=1;j--) u[j] -= gam[j+1]*u[j+1]; free_vector(gam,1,n); } void cyclic(float a[], float b[], float c[], float alpha, float beta, float r[], float x[], unsigned long n) { void tridag(float a[], float b[], float c[], float r[], float u[], unsigned long n); unsigned long i; float fact,gamma,*bb,*u,*z; if (n <= 2) nrerror("n too small in cyclic"); bb=vector(1,n); u=vector(1,n); z=vector(1,n); gamma = -b[1]; //Avoid subtraction error in forming bb[1]. bb[1]=b[1]-gamma; //Set up the diagonal of the modified tridiagonal bb[n]=b[n]-alpha*beta/gamma; //system. for (i=2;i<n;i++) bb[i]=b[i]; tridag(a,bb,c,r,x,n);// Solve A · x = r. u[1]=gamma;// Set up the vector u. u[n]=alpha; for (i=2;i<n;i++) u[i]=0.0; tridag(a,bb,c,u,z,n);// Solve A · z = u. fact=(x[1]+beta*x[n]/gamma)/ //Form v · x/(1 + v · z). (1.0+z[1]+beta*z[n]/gamma); for (i=1;i<=n;i++) x[i] -= fact*z[i]; //Nowget the solution vector x. free_vector(z,1,n); free_vector(u,1,n); free_vector(bb,1,n); } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { float *a,*b,*c,*x,*r; float alpha,beta; unsigned long n = (unsigned long) mxGetScalar(prhs[6]); // a=mxGetPr(prhs[0]); // b=mxGetPr(prhs[1]); // c=mxGetPr(prhs[2]); // r=mxGetPr(prhs[5]); a = (float*) mxGetData(prhs[0]); b = (float*) mxGetData(prhs[1]); c = (float*) mxGetData(prhs[2]); r = (float*) mxGetData(prhs[5]); // alpha=*(mxGetPr(prhs[3])); // beta=*(mxGetPr(prhs[4])); alpha = (float) mxGetScalar(prhs[3]); beta = (float) mxGetScalar(prhs[4]); plhs[0]= mxCreateDoubleMatrix(n, 1, mxREAL); x = mxGetPr(plhs[0]); mexPrintf("%f ",alpha); mexPrintf("\n"); mexPrintf("%f ",beta); mexPrintf("\n"); mexPrintf("%d ",n); mexPrintf("\n"); cyclic(a,b,c, alpha, beta,r,x,n) ; mexPrintf("%d ",n); mexPrintf("\n"); } 

最后我成功地将它编译成cyclic(a,b,c, alpha, beta,r,x,n) ; 。 但答案是不对的。 我认为这是因为r是一个虚构的向量。 所以我的问题是如何在CMatlab之间转换r?

C函数cyclic期望float s的数组,但mexFunction传递double* 。 在不更改cyclic.c ,您有两种选择:

  • 在MATLAB中将数据转换为single数据,并使用mxGetData获取float*

    mexFunction

     float *a = (float*) mxGetData(prhs[0]); 

    在MATLAB中:

     mexFunction(single(a),...) 
  • 转换(复制,而不是mexFunction转换!) mexFunction的数据。

    mexFunction ,分配新的float数组,并将双输入数组( mxGetPr(prhs[0]) )中的每个元素复制到临时float数组中。

    在MATLAB中使用普通的double数组调用mexFunction

做前者可能更容易。

在任何情况下你都不应该简单地使用指针,而不是你计划这样做。


此外,标量alphabetan需要从prhs读取为标量并作为标量传递给cyclic 。 在mexFunction ,使用:

 float alpha = (float) mxGetScalar(prhs[...]); float beta = (float) mxGetScalar(prhs[...]); unsigned long n = (unsigned long) mxGetScalar(prhs[...]); 

你完全忘记了mexFunction cr