MIT 18.06 - Lecture 4

A = LU 分解

04723d1c01594335bfaa844bc09ecbb0.png

$L$ 矩阵是一个下三角矩阵,$U$ 矩阵是一个上三角矩阵。这种表示方式相对于 $EA = U$ 而言更加合适。

1db18512ba9bf311e6916de8aabd2cff.png

$$
\quad
$$

高斯消元的时间复杂度是 $O(n ^ 3)$ 级别的,编程难度不算很大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>
const int N = 150;
const double eps = 1e-7;
using namespace std;

int n;
double ans[N], a[N][N];

int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
freopen("in","r", stdin);
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n + 1; j++) cin >> a[i][j];
}
for (int i = 1; i <= n; i++) {
int pos = i;
for (int k = i + 1; k <= n; k++) {
if (fabs(a[i][i]) < fabs(a[k][i])) pos = k;
}
if (fabs(a[pos][i]) < eps) {
cout << "No Solution" << endl;
return 0;
}
if (pos != i) swap(a[i], a[pos]);
double div = a[i][i];
for (int j = i; j <= n + 1; j++) a[i][j] /= div;
for (int k = i + 1; k <= n; k++) {
div = a[k][i];
for (int l = i; l <= n + 1; l++) a[k][l] -= div * a[i][l];
}
}
ans[n] = a[n][n + 1];
for (int i = n - 1; i >= 1; i--) {
ans[i] = a[i][n + 1];
for (int j = i + 1; j <= n; j++) ans[i] -= ans[j] * a[i][j];
}
for (int i = 1; i <= n; i++) cout << fixed << setprecision(2) << ans[i] << endl;
return 0;
}

e49b2a7119d3383516e721cb371713df.png

对于消元过程中碰到 pivot 为 0 的情况,需要进行行交换。行交换等价于在原矩阵的左边乘一个置换矩阵(permutation matrix)。因此,$A = LU$ 分解写成 $PA = LU$ 的形式将更完整。

置换矩阵 $P$ 的一个重要性质: $P ^ {-1} = P ^ T$。

作者

Zylll

发布于

2024-02-26

更新于

2024-03-01

许可协议