Mex文件点积

时间:2015-02-13 15:53:35

标签: c matlab mex

我正在尝试在C语言的MEX文件中实现一些基本的线性代数例程来练习,而且我坚持使用点积。这是我到目前为止所做的:

#define char16_t UINT16_T //shenanigans with the compiler
#include "mex.h"

void dotProd(double *a, double *b, double z, mwSize n)
{
mwSize i;

for(i=0;i<n;i++){
        z+=a[i] * b[i];

    }
}

/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
              int nrhs, const mxArray *prhs[])
{

double z=0; //Output scalar
double *b, *a; //Input vectors

int n;

a = mxGetPr(prhs[0]); //pointer to a
b = mxGetPr(prhs[1]); //pointer to b

n = mxGetM(prhs[0]);

// Create output
plhs[0] = mxCreateDoubleScalar(z);

dotProd(a,b,z,(mwSize)n);
}

问题是当我测试这段代码时:

a=rand(2,1);
b=rand(2,1);
z=dotProd(a,b);

我明白了:

z=0

即使a和b不是正交的。我用MATLAB dot()函数验证了这一点。我已经选择了代码,似乎无法找到我出错的地方。一些建议将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:1)

那是因为您没有返回点积的结果。 z在您的dotProd函数中制作了自己的本地副本。即使您要对z进行修改,这些更改也不会反映,因为zdotProd的范围是本地范围。您需要将计算点积的函数更新为返回。此外,您正在设置功能的输出计算点积。

同样,这样做:

// Change - Remove z as input
double dotProd(double *a, double *b, mwSize n)
{
mwSize i;
double z = 0.0; // Initialize z to 0.0
for(i=0;i<n;i++){
        z+=a[i] * b[i];    
    }
return z; // Return z
}

然后只需:

void mexFunction( int nlhs, mxArray *plhs[],
              int nrhs, const mxArray *prhs[])
{

double z; //Output scalar - Change - don't need to initialize
double *b, *a; //Input vectors

int n;

a = mxGetPr(prhs[0]); //pointer to a
b = mxGetPr(prhs[1]); //pointer to b

n = mxGetM(prhs[0]);

// Create output
z = dotProd(a,b, (mwSize)n); // Change - returning output
plhs[0] = mxCreateDoubleScalar(z);


}

如果您坚持更改功能中的z并且不让该功能返回任何内容,则您需要将指针传递给{ {1}}并更改z所指的内容。换句话说,你会这样做:

z

现在,做:

// Change - Make z point to a double
void dotProd(double *a, double *b, double *z, mwSize n)
{
mwSize i;
for(i=0;i<n;i++){
        *z+=a[i] * b[i];    // Change - Refer to pointer
    }
}

顺便说一下,您仍然需要在设置输出之前致电void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double z = 0.0; double *b, *a; //Input vectors int n; a = mxGetPr(prhs[0]); //pointer to a b = mxGetPr(prhs[1]); //pointer to b n = mxGetM(prhs[0]); // Create output dotProd(a,b, &z, (mwSize)n); // Change - Pass pointer of z to function plhs[0] = mxCreateDoubleScalar(z); } 。这就是为什么你在设置输出之前dotProd为0时保持0的原因,然后你之后调用了z