我正在尝试在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()
函数验证了这一点。我已经选择了代码,似乎无法找到我出错的地方。一些建议将不胜感激。
谢谢。
答案 0 :(得分:1)
那是因为您没有返回点积的结果。 z
在您的dotProd
函数中制作了自己的本地副本。即使您要对z
进行修改,这些更改也不会反映,因为z
内dotProd
的范围是本地范围。您需要将计算点积的函数更新为返回。此外,您正在设置功能的输出计算点积。
同样,这样做:
// 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
。