C:矩阵向量乘积,两个双数相乘给出错误符号
Posted
技术标签:
【中文标题】C:矩阵向量乘积,两个双数相乘给出错误符号【英文标题】:C: matrix-vector product, multiplying two double numbers gives wrong sign 【发布时间】:2019-03-10 15:04:47 【问题描述】:我正在尝试执行一个简单的矩阵乘以向量乘法,但由于某种原因,我的几次乘法结果中出现了错误的符号。我不知道为什么会这样,任何指针将不胜感激。
这是我的全部代码,即来自 mex 的矩阵 * 向量函数和调用者函数(或任何它被调用的函数) - 我正在通过 mex 从 Matlab 运行代码。
#include "mex.h"
void mxv(int m, int n, double *A, double *b, double *c)
double sum;
int i, j;
for (i = 0; i < m; i++)
sum = 0.0;
for (j = 0; j < n; j++)
sum += A[i * n + j] * b[j];
c[i] = sum;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
double *A, *b, *c;
int i, j, Am, An;
A = mxGetPr(prhs[0]);
Am = (int)mxGetM(prhs[0]);
An = (int)mxGetN(prhs[0]);
c = malloc(Am * sizeof(double));
b = mxGetPr(prhs[1]);
mxv(Am, An, A, b, c);
for (i = 0; i < Am; i++)
printf("c[%d] = %1.4f\n", i, c[i]);
我使用以下输入调用 mex 函数:
A = [-865.6634 0 0 0;
0 -17002.6822 0 0;
0 0 -1726.2421 2539.6267;
0 0 -2539.6267 -1726.2421;]
b = [-0.00153521; -0.00011165; -0.00037659; 0.00044981]
正确的结果应该是:
1.3290
1.8983
1.7924
0.1799
但我明白了
c[0] = 1.3290
c[1] = 1.8983
c[2] = -0.4923
c[3] = -1.7329
所以前两个是正确的(c[0] 和 c[1]),但不是后两个。
我在我的代码中添加了一堆打印语句来尝试找出错误发生的位置:
#include "mex.h"
void mxv(int m, int n, double *A, double *b, double *c)
double sum;
int i, j;
for (i = 0; i < m; i++)
sum = 0.0;
printf("********\n");
for (j = 0; j < n; j++)
printf("A[%d][%d] = %1.10f\nb[%d] = %1.10f\n", i , j, A[i + n * j], j, b[j]);
printf("A[%d][%d]*b[%d] = %1.10f\n", i, j, j, A[i * n + j] * b[j]);
sum += A[i * n + j] * b[j];
printf("sum = %1.10f\n", sum);
c[i] = sum;
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
double *A, *b, *c;
int i, j, Am, An;
A = mxGetPr(prhs[0]);
Am = (int)mxGetM(prhs[0]);
An = (int)mxGetN(prhs[0]);
printf("size(A) = (%d,%d)\n", Am, An);
for (i = 0; i < Am; i++)
for (j = 0; j < An; j++)
printf("A[%d][%d] = %1.4f\n", i, j, A[i + Am * j]);
c = malloc(Am *sizeof(double));
b = mxGetPr(prhs[1]);
for (i = 0; i < Am; i++)
printf("b[%d] = %1.4f\n", i, b[i]);
mxv(Am, An, A, b, c);
for (i = 0; i < Am; i++)
printf("c[%d] = %1.4f\n", i, c[i]);
我非常有信心从 Matlab 获得正确的输入:
size(A) = (4,4)
A[0][0] = -865.6634
A[0][1] = 0.0000
A[0][2] = 0.0000
A[0][3] = 0.0000
A[1][0] = 0.0000
A[1][1] = -17002.6822
A[1][2] = 0.0000
A[1][3] = 0.0000
A[2][0] = 0.0000
A[2][1] = 0.0000
A[2][2] = -1726.2421
A[2][3] = 2539.6267
A[3][0] = 0.0000
A[3][1] = 0.0000
A[3][2] = -2539.6267
A[3][3] = -1726.2421
b[0] = -0.0015
b[1] = -0.0001
b[2] = -0.0004
b[3] = 0.0004
但是当我查看矩阵向量乘法时,我发现乘法结果由于某种原因在某些情况下具有错误的符号。这是它为 i = 2 打印的内容:
********
A[2][0] = 0.0000000000
b[0] = -0.0015352100
A[2][0]*b[0] = -0.0000000000
sum = 0.0000000000
A[2][1] = 0.0000000000
b[1] = -0.0001116500
A[2][1]*b[1] = -0.0000000000
sum = 0.0000000000
A[2][2] = -1726.2421000000
b[2] = -0.0003765900
A[2][2]*b[2] = 0.6500855124
sum = 0.6500855124
A[2][3] = 2539.6267000000
b[3] = 0.0004498100
A[2][3]*b[3] = -1.1423494859 <- THIS SHOULD BE 1.142349... (no minus sign)
sum = -0.4922639735
********
在 i=3 的情况下也会发生类似的情况。
提前致谢!
【问题讨论】:
您是否使用了正确的索引?考虑到A[2][3]
应该是2539.6267
而A[3][2]
是-2539.6267
。所以结果是正确的,如果A
的索引被切换了。
是的,没错!代表我犯了愚蠢的错误。感谢您的观看!
【参考方案1】:
在:
printf("A[%d][%d] = %1.10f\nb[%d] = %1.10f\n", i , j, A[i + n * j], j, b[j]);
printf("A[%d][%d]*b[%d] = %1.10f\n", i, j, j, A[i * n + j] * b[j]);
第一个printf
使用A[i + n*j]
,而第二个使用A[i*n + j]
。这些是数组中的转置位置。
【讨论】:
啊!当然,愚蠢的错误!将所有索引更改为 A[i + m*j] 就可以了。感谢您的帮助!以上是关于C:矩阵向量乘积,两个双数相乘给出错误符号的主要内容,如果未能解决你的问题,请参考以下文章