Faktorisasi
Dekomposisi menyimpan eliminasi Gauss dalam dua matriks segitiga. Dengan pivoting parsial, matriks persegi nonsingular difaktorkan sebagai
Ketiga faktor memiliki peran berikut:
- adalah matriks permutasi yang mencatat pertukaran baris
- adalah matriks segitiga bawah dengan diagonal satu
- adalah matriks segitiga atas
Pada langkah eliminasi , pivoting parsial memilih entri dengan nilai mutlak terbesar pada kolom yang berada pada atau di bawah diagonal. Langkah ini mencegah pembagian dengan pivot nol dan biasanya membatasi pertumbuhan galat numerik.
Untuk matriks permutasi, berlaku . Kesamaan hanya berlaku pada permutasi khusus, misalnya satu pertukaran baris, dan tidak benar untuk setiap permutasi gabungan.
Cara eliminasi membentuk faktor
Setelah memilih pivot pada kolom , hilangkan setiap entri di bawahnya dengan pengali
Kemudian terapkan pembaruan baris berikut.
Pengali disimpan di bawah diagonal . Jika dua baris ditukar setelah beberapa langkah eliminasi, kolom yang sudah terisi juga harus ditukar. Jika tidak, kesamaan tidak lagi terpenuhi.
Memfaktorkan Matriks dengan Pivoting Parsial
Kita akan mencatat kedua pertukaran baris agar permutasi akhir sesuai dengan faktor.
Pivot pertama
Entri terbesar pada kolom pertama memiliki magnitudo . Tukar baris pertama dan ketiga, lalu hilangkan entri baris kedua dengan pengali . Baris ketiga sudah diawali nol.
Pivot kedua
Pivot berikutnya memiliki magnitudo di baris ketiga, sehingga tukar baris kedua dan ketiga. Tukar juga pengali kolom pertama yang sudah disimpan pada . Pengali untuk baris terakhir kemudian menjadi .
Faktor yang dihasilkan adalah
Perkalian kedua faktor memverifikasi dekomposisi:
Menyelesaikan sistem linear
Dari , persamaan berubah menjadi
Kita menyelesaikan sistem ini dalam dua tahap menggunakan matriks segitiga.
Substitusi maju
Pertama, selesaikan . Pada contoh ini,
Untuk matriks segitiga bawah umum,
Entri diagonal pada dekomposisi ini semuanya satu.
Substitusi mundur
Kemudian selesaikan dari baris terakhir ke atas:
Untuk contoh tersebut,
Substitusi langsung mengonfirmasi .
Biaya dan penggunaan ulang
Faktorisasi padat membutuhkan sekitar
Jumlah tersebut menyatakan operasi titik mengambang ketika perkalian dan pengurangan dihitung secara terpisah. Setelah faktor tersedia, setiap ruas kanan baru hanya membutuhkan kerja untuk dua substitusi. Pemakaian ulang faktor menghindari faktorisasi untuk setiap ruas kanan.
Determinan juga dapat diperoleh dari faktor:
Implementasi NumPy dengan Pemeriksaan Pivot
import numpy as np
def plu_factor(matrix, tolerance=1e-12):
"""Return P, L, U such that P @ matrix == L @ U."""
A = np.asarray(matrix)
if np.iscomplexobj(A):
raise ValueError("this example requires real entries")
A = A.astype(float)
if A.ndim != 2 or A.shape[0] != A.shape[1] or A.shape[0] == 0:
raise ValueError("PLU factorization requires a nonempty square matrix")
if not np.all(np.isfinite(A)):
raise ValueError("matrix entries must be finite")
if not np.isfinite(tolerance) or tolerance < 0:
raise ValueError("relative tolerance must be finite and nonnegative")
threshold = tolerance * np.linalg.norm(A, ord=np.inf)
n = A.shape[0]
U = A.copy()
L = np.eye(n)
P = np.eye(n)
for k in range(n - 1):
pivot = k + np.argmax(np.abs(U[k:, k]))
if abs(U[pivot, k]) <= threshold:
raise np.linalg.LinAlgError("matrix is singular to working precision")
if pivot != k:
U[[k, pivot]] = U[[pivot, k]]
P[[k, pivot]] = P[[pivot, k]]
L[[k, pivot], :k] = L[[pivot, k], :k]
for i in range(k + 1, n):
L[i, k] = U[i, k] / U[k, k]
U[i, k:] -= L[i, k] * U[k, k:]
if abs(U[-1, -1]) <= threshold:
raise np.linalg.LinAlgError("matrix is singular to working precision")
return P, L, U
def forward_substitution(L, right_hand_side):
b = np.asarray(right_hand_side, dtype=float)
y = np.empty_like(b)
for i in range(len(b)):
y[i] = (b[i] - L[i, :i] @ y[:i]) / L[i, i]
return y
def backward_substitution(U, right_hand_side, tolerance=1e-12):
y = np.asarray(right_hand_side, dtype=float)
x = np.empty_like(y)
threshold = tolerance * np.linalg.norm(U, ord=np.inf)
for i in range(len(y) - 1, -1, -1):
if abs(U[i, i]) <= threshold:
raise np.linalg.LinAlgError("singular triangular system")
x[i] = (y[i] - U[i, i + 1:] @ x[i + 1:]) / U[i, i]
return x
def plu_solve(matrix, right_hand_side):
P, L, U = plu_factor(matrix)
b = np.asarray(right_hand_side)
if np.iscomplexobj(b):
raise ValueError("this example requires a real right-hand side")
b = b.astype(float)
if b.shape != (len(P),) or not np.all(np.isfinite(b)):
raise ValueError("right-hand side must be a finite vector of matching size")
y = forward_substitution(L, P @ b)
x = backward_substitution(U, y)
return x, P, L, U
A = np.array([[0, 2, 1], [1, 1, 0], [2, 1, 1]], dtype=float)
b = np.array([7, 3, 7], dtype=float)
x, P, L, U = plu_solve(A, b)
assert np.allclose(P @ A, L @ U)
assert np.allclose(A @ x, b)
assert np.allclose(x, np.array([1, 2, 3], dtype=float))Pemeriksaan tersebut menjadi bagian dari contoh karena urutan faktor dan pencatatan pertukaran baris merupakan sumber kesalahan implementasi yang umum.
Toleransi pivot dihitung relatif terhadap norma tak hingga matriks. Karena itu, penskalaan seragam pada sistem berkondisi baik tidak menyebabkan kegagalan hanya karena semua entri kecil. Ambang ini merupakan keputusan numerik, bukan bukti singularitas eksak.
Batas penggunaan metode
Implementasi ini hanya menyelesaikan sistem dengan matriks persegi yang dapat dibalik. Program menganggap pivot numerik nol sebagai kegagalan. Gunakan untuk masalah kuadrat terkecil dengan matriks persegi panjang. Untuk matriks yang tidak berperingkat penuh, gunakan dengan pivot kolom atau . Faktorisasi masih dapat dibuat untuk matriks persegi singular, tetapi program ini tidak dapat memakainya untuk memperoleh satu solusi unik.