Mex 文件点积

Mex File dot product

我正在尝试在 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() 函数验证了这一点。我已经挑选了代码,但似乎无法找到我要出错的地方。一些建议将不胜感激。

谢谢。

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

因此,这样做:

// 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并且不让函数return任何东西,你需要传递指向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 的原因,因为 z 在你设置输出之前是 0,然后你在之后调用了 dotProd