本文介绍了如何写这个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好几年了。
昨天晚上,我完成了它和编译。最后一件事是调用它。

I am new for the interface between Matlab and C. And I have not use C for several years. Last night, I finished it and compile. The last thing is to call it.

#include "mex.h" 


#include "nrutil.h"

#define FREE_ARG char*
#define NR_END 1


#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#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<=n;j++) {
gam[j]=c[j-1]/bet;
bet=b[j]-a[j]*gam[j];
if (bet == 0.0) nrerror("Error 2 in tridag"); 
        u[j]=(r[j]-a[j]*u[j-1])/bet; 
}
for (j=(n-1);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"); 
    } 

最后,我成功编译它循环(A,B,C,α,β,R,X,N); 。但得到的答复是不正确的。我的事情,这是因为研究是一个虚构的载体。所以我的问题是我应该如何改变 C Matlab的

Finally I successfully compile itcyclic(a,b,c, alpha, beta,r,x,n) ;. But the answer is not right. I thing this is because r is an imaginary vector. So my question is how should I transform r between C and Matlab?

推荐答案

C函数循环期望浮动 S,但 mexFunction 正在传递双* 。在不改变 cyclic.c ,你有两个选择:

The C function cyclic expects arrays of floats, but mexFunction is passing a double*. Without changing cyclic.c, you have two options:


  • 将数据转换为 MATLAB和获得浮法* mxGetData

  • Convert the data to single in MATLAB and get a float* with mxGetData.

mexFunction

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

在MATLAB:

mexFunction(single(a),...)


  • 在转换 mexFunction (复制,不投!)中的数据。

  • Convert (copy, not cast!) the data in mexFunction.

    mexFunction ,分配新的浮动数组,每个元素从双输入数组(<$ C复制$ C> mxGetPr(prhs [0]))到临时浮动阵列。

    In mexFunction, allocate new float arrays, and copy each element from the double input array (mxGetPr(prhs[0])) into the temporary float array.

    呼叫 mexFunction 与正常双击数组在MATLAB。

    Call mexFunction with a normal double array in MATLAB.

    它可能更容易做了前者。

    It's probably easier to do the former.

    在任何情况下,你应该简单地把指针,而不是你打算这样做。

    Under no circumstances should you simply cast the pointer, not that you were planning to do that.

    此外,标量字母测试版 N 需要从 prhs 的标量读取并传递到循环的标量。在 mexFunction ,使用:

    Also, the scalars alpha, beta and n need to be read from prhs as scalars and passed to cyclic as scalars. In mexFunction, use:

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


    您已经完全忘记 C 研究 mexFunction

    这篇关于如何写这个C文件的mexFunction的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 09-25 00:28