两个基本错误,一个轻微错误:
您正在使用指向从MATLAB传递到MEX包装器的内存的指针的double指针,并使用该指针将数据写入输出。 在墨西哥,当你的阵列和矩阵分配内存,或者当你访问一个MATLAB传递给MEX封装数据,它只是一个指针。 要访问大于一维的MEX中的数据,MATLAB实际上会将所有数据交织到单个一维数组中,因此您需要使用正确的索引来获取所需的数据。 您还需要使用列优先顺序访问元素。 因此,您不能使用2D索引。 我还将使用mxGetPr而不是mxGetData因为您的数据由所有实数组成。
您的for循环略有错别字。 您忘记了用花括号将所有语句括在for循环内。 没有它,您将仅运行第一条语句,而其他两个语句仅运行一次。
计算叉积的第二行在计算3D向量的y值时略有错误。 您需要颠倒条款。 具体来说,您必须执行以下操作:C[i][1] = A[i][2]*B[i][0] - A[i][0]*B[i][2];
但是,上述访问方法不正确,我们将尽快修复。
因此,您需要将MEX文件更改为:
// [C] = crossprod(A,B)
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
size_t m;
double *A, *B; // Change
double *C;
int i;
m = mxGetM(prhs[0]);
A = mxGetPr(prhs[0]); // Change
B = mxGetPr(prhs[1]); // Change
plhs[0] = mxCreateDoubleMatrix((int) m, 3, mxREAL);
C = mxGetPr(plhs[0]);
// Major change - Using column major indexing
for(i = 0; i < m; i++) {
C[i] = A[i + m]*B[i + 2*m] - A[i + 2*m]*B[i + m];
C[i + m] = A[i + 2*m]*B[i] - A[i]*B[i + 2*m]; // Change here too
C[i + 2*m] = A[i]*B[i + m] - A[i + m]*B[i];
}
}
除了for循环外,其他一切都很简单。 在MATLAB中访问2D数组时,我们使用一个指针指向内存,但是内存是1D交错的。 您以列为主格式访问内存。 这样,对于第i行和第j列,您将在此位置访问2D矩阵A ,如下所示:
A[i + j*m]
m是行的总数。 因此, A[i][0]将简单地为A[i] , A[i][1]将为A[i + m] ,最后A[i][2]将为A[i + 2*m] 。 我用它来翻译上面的代码。
为了显示此工作原理,我决定在计算机上进行编译,并通过示例A和B矩阵对其进行运行:
>> A = [1 2 3; 4 5 6; 7 8 9]
>> B = [7 8 9; 5 6 2; 5 5 6]
>> C = crossprod(A, B)
C =
-6 12 -6
-26 22 -1
3 3 -5
与MATLAB的cross命令相比,我们可以通过在每行被视为3D矢量的列上进行操作来做到这一点:
>> C2 = cross(A, B, 2)
C2 =
-6 12 -6
-26 22 -1
3 3 -5
如您所见,MEX代码和MATLAB的cross函数都匹配。
祝好运!