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
。
我正在尝试在 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
。