矩陣求逆是線性代數計算的核心任務。Gauss-Jordan 消去法通過將增廣矩陣 [A | I] 變換為 [I | A⁻¹] 實現求逆。結合列主元選擇,可顯著提升數值穩定性。本文深度解析一個完整的 C++ 實現,涵蓋主元選擇、行交換、歸一化、消去、逆序恢復等關鍵步驟。
k 列中尋找絕對值最大元素所在行 p[k]< 1e-10 判定奇異k 行k 列其餘元素歸零Aᵢⱼ ← Aᵢⱼ + Aᵢₖ × Aₖⱼ (i,j ≠ k)k = k+1 循環p[k] 逆序交換行,還原原始順序#define a(u,v) a[(u)*n + (v) - w] // w = n+1
// 增廣矩陣 [A|I] 為 n × 2n,但程式僅存儲 n×n 係數矩陣
// 實際操作隱含單位矩陣列操作
索引映射技巧:a(u,v) 將二維訪問轉為一維,w 偏移處理擴展列。
for (k=1; k fabs(a(p[k],k))) p[k] = i;
if (a(p[k],k) < 1e-10) { // 奇異判定
cout << "A is singular!";
exit(1);
}
if (p[k] != k) // 行交換
for (i=1; i
a(k,k) = 1 / a(k,k); // 歸一化主元
for (i=1; i
for (k=n; k>0; k--)
if (k != p[k])
for (i=1; i
這步至關重要:消去過程中行交換改變了矩陣行序,必須逆序撤銷才能得到正確的逆矩陣。
// input: 10 階矩陣,每行循環左移
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 1
...
// output
各步主行行號: 10 9 8 7 6 6 7 8 9 10
A的逆矩陣:
-0.0981818 0.00181818 ... 0.101818
0.00181818 0.00181818 ... -0.0981818
... (循環對稱結構)
主元行號呈現對稱分佈(10→1→10),反映矩陣的循環結構特性。逆矩陣呈現循環對稱模式,驗證算法正確性。
O(n²)O(n³)class MatrixInverter {
std::vector a_;
std::vector pivot_;
int n_;
public:
MatrixInverter(int n) : n_(n), a_(n*n), pivot_(n+1) {}
bool invert(std::vector& inv) const;
// 使用 std::vector 自動管理記憶體
// 加入條件數估計、反向誤差檢查
// 支援塊狀矩陣優化快取
};
a(u,v) 邊界檢查缺失,建議改用內聯函數1e-10 過於固定,應依條件數動態調整delete 未執行,RAII 解決Gauss-Jordan 列主元求逆展示了直接法線性代數的經典美感:通過初等行變換將求逆轉化為矩陣變換序列。關鍵在於主元選擇保證穩定、全矩陣更新傳播資訊、逆序恢復還原順序。理解這套流程,不僅能實現矩陣求逆,更能建立「數值線性代數」的工程直覺——這是科學計算、機器學習、圖形學等領域的核心內功。