二维矩阵求逆函数结果异常,求问题排查与修正方案
问题分析与修正
你的矩阵逆函数结果错误的核心原因是多执行了一次行列式倒数的乘法操作,导致最终结果为正确逆矩阵的1/4(你的输入矩阵行列式为4,乘以1/4后结果被错误缩小)。
错误原因详解
高斯消元法求逆的逻辑是:对增广矩阵[A | I]执行初等行变换,当左侧的A被转换为单位矩阵I时,右侧的单位矩阵I就会变成A⁻¹。你的代码在消元循环中已经完成了这个转换,但最后额外添加了将B矩阵乘以1/det的步骤——这完全是多余的,因为此时的B已经是正确的逆矩阵,不需要再做行列式缩放。
你代码中记录的det是原矩阵的行列式,但这是伴随矩阵求逆法的需要,和高斯消元法求逆无关,这一步乘法直接导致结果错误。
修正后的代码
移除最后乘以行列式倒数的部分即可:
#include <iostream> #include <algorithm> #include <cmath> using namespace std; const int MAX = 100; void inverse(double A[][MAX], int n) { double B[MAX][MAX]; int i, j, k; // 初始化B为单位矩阵 for(i = 0; i < n; i++) for(j = 0; j < n; j++) B[i][j] = (i == j) ? 1 : 0; // 执行行变换将A转换为单位矩阵 for(k = 0; k < n; k++) { // 寻找主元行(部分选主元) int max_row = k; for (i = k + 1; i < n; i++) { if (abs(A[i][k]) > abs(A[max_row][k])) { max_row = i; } } // 交换当前行和主元行 if (max_row != k) { for (int col = 0; col < n; col++) { swap(A[k][col], A[max_row][col]); swap(B[k][col], B[max_row][col]); } } // 将当前行除以主元,使主元变为1 double pivot = A[k][k]; if (pivot == 0) { cout << "Error: Singular matrix." << endl; return; } for(j = 0; j < n; j++) { A[k][j] /= pivot; B[k][j] /= pivot; } // 消除其他行的主元位置元素 for(i = 0; i < n; i++) { if(i == k) continue; double factor = A[i][k]; for(j = 0; j < n; j++) { A[i][j] -= A[k][j] * factor; B[i][j] -= B[k][j] * factor; } } } // 将逆矩阵复制回A for(i = 0; i < n; i++) for(j = 0; j < n; j++) A[i][j] = B[i][j]; } // 测试示例 int main() { double A[MAX][MAX] = {{2,1,0}, {1,2,1}, {0,1,2}}; int n = 3; inverse(A, n); // 输出结果 for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { cout << A[i][j] << "\t"; } cout << endl; } return 0; }
验证结果
修正后运行代码,输入你提供的矩阵,会得到正确的逆矩阵:
0.75 -0.5 0.25 -0.5 1 -0.5 0.25 -0.5 0.75
对应分数形式就是:
3/4 -1/2 1/4 -1/2 1 -1/2 1/4 -1/2 3/4
内容的提问来源于stack exchange,提问作者Ahmed Kahil
相关产品推荐
相关产品推荐

