高斯消元法求逆矩阵要求矩阵为满秩方阵,通过同步行变换将[a|i]化为[i|a⁻¹];实现时须部分选主元防除零,且行变换顺序不可颠倒。

高斯消元法求逆矩阵的核心逻辑
只有方阵才可能有逆矩阵,且必须满秩(行列式不为零)。高斯消元法的本质是把原矩阵 A 通过初等行变换变成单位矩阵 I,同时对增广矩阵右侧的 I 施加完全相同的行变换,最终右侧就变成 A⁻¹。关键不是“解方程”,而是“同步做行变换”。
用 vector> 实现时的常见错误
很多人写完发现结果全是 nan 或 inf,大概率出在以下环节:
- 没判断主元是否为零或接近零,直接除 —— 必须做**部分选主元**(即当前列中找绝对值最大的行交换)
- 行变换顺序写反:先用第
i行消第j行,但没确保i 或没跳过自身,导致把已归一化的主元又破坏了 - 浮点比较用
== 0.0判断奇异,应改用abs(pivot) - 没初始化增广矩阵右侧为单位阵,或单位阵构造错(比如
mat[i][j] = (i == j)写成mat[i][i] = 1后忘了设其余为 0)
一个安全可用的 C++ 实现片段
以下代码只处理 double 类型方阵,含选主元和数值容错,可直接嵌入项目:
#include <vector>
#include <iostream>
#include <cmath>
#include <iomanip>
<p>using Matrix = std::vector<std::vector<double>>;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/ai/2101" title="Keeva AI"><img
src="https://img.php.cn/upload/ai_manual/000/000/000/175680079922248.png" alt="Keeva AI" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/ai/2101" title="Keeva AI">Keeva AI</a>
<p>AI一键生成数字人营销视频</p>
</div>
<a href="/ai/2101" title="Keeva AI" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/6e7abc4abb9f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">C++免费学习笔记(深入)</a>”;</p><p>Matrix inverse(const Matrix& A) {
int n = A.size();
Matrix aug(n, std::vector<double>(2 * n, 0.0));</p><pre class='brush:php;toolbar:false;'>// 构造增广矩阵 [A | I]
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
aug[i][j] = A[i][j];
}
aug[i][n + i] = 1.0;
}
// 高斯-约旦消元
for (int col = 0; col < n; ++col) {
// 选主元:找当前列中绝对值最大的行
int pivot_row = col;
for (int i = col + 1; i < n; ++i) {
if (std::abs(aug[i][col]) > std::abs(aug[pivot_row][col])) {
pivot_row = i;
}
}
if (std::abs(aug[pivot_row][col]) < 1e-12) {
throw std::runtime_error("Matrix is singular");
}
// 交换行
aug[col].swap(aug[pivot_row]);
// 归一化当前行(主元变 1)
double pivot = aug[col][col];
for (int j = 0; j < 2 * n; ++j) {
aug[col][j] /= pivot;
}
// 消去该列其他行
for (int i = 0; i < n; ++i) {
if (i == col) continue;
double factor = aug[i][col];
for (int j = 0; j < 2 * n; ++j) {
aug[i][j] -= factor * aug[col][j];
}
}
}
// 提取逆矩阵(右半部分)
Matrix inv(n, std::vector<double>(n));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
inv[i][j] = aug[i][n + j];
}
}
return inv;}
性能与精度注意事项
这个实现适合中小规模(n ≤ 500)矩阵。更大的矩阵建议用 LAPACK(如 dgetrf + dgetri)或 Eigen 库:MatrixXd::inverse()。手写高斯消元容易因累积舍入误差导致逆矩阵验证失败(即 A * A⁻¹ 不够接近 I),尤其当矩阵条件数大时。如果只需要解线性方程组 Ax = b,别真算逆矩阵 —— 直接 LU 分解后前代后代更快更稳。










