Selain SVD pada Chapter Singular Value Decomposition, numpy.linalg menyediakan dua dekomposisi lain yang kerap dipakai sebagai alat kerja sehari-hari: QR dan Cholesky. QR memfaktorkan matriks A menjadi Q @ R dengan Q orthogonal dan R segitiga atas; Cholesky memfaktorkan matriks simetris positif-definit S menjadi L @ L.T dengan L segitiga bawah. Keduanya lebih murah daripada SVD dan masing-masing punya panggung favorit: QR untuk least squares yang stabil, Cholesky untuk matriks kovarians dan sampling berkorelasi.

Bab ini memverifikasi kedua dekomposisi lewat rekonstruksi, memakai QR untuk menyelesaikan ulang persoalan struk belanja pada Chapter Least Squares, lalu menutup dengan pemanfaatan Cholesky yang paling terasa manfaatnya: menghasilkan data acak yang berkorelasi sesuai keinginan.

Dekomposisi QR #

np.linalg.qr mengembalikan pasangan (Q, R). Kolom Q orthonormal — ujiannya Q.T @ Q sama dengan matriks identitas — sementara R segitiga atas dengan entri nol di bawah diagonal:

python
import numpy as np

A = np.array([[1.0, 2.0],
              [3.0, 4.0]])
Q, R = np.linalg.qr(A)
print(Q)
print(R)
print(np.allclose(Q @ R, A))
print(np.allclose(Q.T @ Q, np.eye(2)))

Output yang Dihasilkan:

text
[[-0.31622777 -0.9486833 ]
 [-0.9486833   0.31622777]]
[[-3.16227766 -4.42718872]
 [ 0.         -0.63245553]]
True
True
  1. Baris 5 (Q, R = np.linalg.qr(A)): mode default reduced mengembalikan Q dan R sekecil mungkin yang tetap merekonstruksi A.
  2. Baris 6 (print(Q)): Q berbentuk (2, 2) dengan kolom orthonormal; panjang tiap kolom 1 dan saling tegak lurus.
  3. Baris 7 (print(R)): R segitiga atas — perhatikan entri 0. di posisi (1, 0).
  4. Baris 8: rekonstruksi Q @ R mengembalikan A; np.allclose bernilai True.
  5. Baris 9: Q.T @ Q menyamai identitas — definisi keter-orthogonalan kolom Q.
Sifat yang diujiEkspresiHasil
Rekonstruksi A = Q @ Rnp.allclose(Q @ R, A)True
Kolom Q orthonormalnp.allclose(Q.T @ Q, np.eye(2))True
R segitiga atasentri di bawah diagonal0.

QR untuk Least Squares #

Sistem A x = b yang overdetermined tidak bisa diselesaikan dengan solve biasa. Namun begitu A = Q R, persoalan min ||A x - b|| menyusut menjadi sistem segitiga kecil R x = Q.T @ b, yang dijawab solve dengan cepat. Kita ulangi persoalan harga gula dan kopi dari Chapter Least Squares lewat jalur QR:

python
import numpy as np

A = np.array([[2.0, 1.0],
              [1.0, 3.0],
              [3.0, 2.0]])
b = np.array([35000.0, 60000.0, 70000.0])
Q, R = np.linalg.qr(A)
beta = np.linalg.solve(R, Q.T @ b)
print(beta)
print(np.linalg.lstsq(A, b, rcond=None)[0])
print(np.allclose(beta, np.linalg.lstsq(A, b, rcond=None)[0]))

Output yang Dihasilkan:

text
[11400. 16400.]
[11400. 16400.]
True
  1. Baris 7: QR dari matriks 3x2 menghasilkan Q (3, 2) dan R (2, 2) — bentuk reduced.
  2. Baris 8 (beta = ...): Q.T @ b memproyeksikan b ke arah kolom A; solve lalu menyelesaikan sistem segitiga R x = Q.T @ b.
  3. Baris 9-11: hasilnya [11400. 16400.] — identik dengan keluaran lstsq pada bab sebelumnya, dibuktikan np.allclose bernilai True.

Jalur QR ini bukan sekadar variasi: ia menghindari pembentukan A.T @ A yang menggandakan condition number matriks. Itulah sebabnya pustaka numerik memilih dekomposisi — bukan inverse biasa — sebagai mesin least squares; dampak condition number kita ukur pada Chapter Stabilitas Numerik.

Cholesky untuk Matriks Simetris Positif-Definit #

Cholesky hanya berlaku untuk matriks simetris positif-definit — kabar baiknya, matriks semacam itu muncul alami: A.T @ A untuk A full-rank selalu memenuhinya. NumPy mengembalikan faktor L dalam bentuk segitiga bawah:

python
import numpy as np

A = np.array([[1.0, 2.0],
              [3.0, 4.0]])
S = A.T @ A
print(S)
L = np.linalg.cholesky(S)
print(L)
print(np.allclose(L @ L.T, S))

Output yang Dihasilkan:

text
[[10. 14.]
 [14. 20.]]
[[3.16227766 0.        ]
 [4.42718872 0.63245553]]
True
  1. Baris 5 (S = A.T @ A): matriks Gram — simetris pasti, karena entri (0, 1) dan (1, 0) sama-sama 14.
  2. Baris 7 (L = np.linalg.cholesky(S)): faktor segitiga bawah; seluruh entri di atas diagonal 0..
  3. Baris 8-9: L @ L.T mengembalikan S, diverifikasi np.allclose bernilai True.

Cholesky untuk Sampling Berkorelasi #

Matriks kovarians memang simetris positif-definit, dan di situlah Cholesky paling sering dipakai: mengubah sampel acak yang saling bebas menjadi sampel dengan korelasi yang kita inginkan. Ide mekanismenya sederhana — jika z berdistribusi normal standar dan cov = L @ L.T, maka z @ L.T berkovarians persis cov:

python
import numpy as np

cov = np.array([[4.0, 2.4],
                [2.4, 9.0]])
L = np.linalg.cholesky(cov)
print(L)
rng = np.random.default_rng(42)
z = rng.standard_normal((5000, 2))
sampel = z @ L.T
print(np.round(np.cov(sampel.T), 2))

Output yang Dihasilkan:

text
[[2.         0.        ]
 [1.2        2.74954542]]
[[3.91 2.44]
 [2.44 9.44]]
  1. Baris 3-4 (cov): matriks kovarians target — varian 4 dan 9, kovarians 2.4.
  2. Baris 5-6: Cholesky memecah cov menjadi L; entri diagonalnya 2.0 dan 2.74954542 (akar dari 4 dan sisa varian kedua sumbu).
  3. Baris 7-8 (rng, z): generator ber-seed 42 menghasilkan 5000 pasang bilangan normal standar yang saling bebas — seed menjaga output deterministik.
  4. Baris 9 (sampel = z @ L.T): transformasi linear; di sinilah korelasi ditanamkan.
  5. Baris 10: kovarians sampel [[3.91 2.44] [2.44 9.44]] mendekati cov target — penyimpangan kecil wajar karena jumlah sampel terbatas.

Pola dua baris terakhir ini (z @ L.T) adalah resep standar simulasi portofolio, data uji sintetis, dan metode Monte Carlo. Bersama QR dan SVD, Cholesky melengkapi kotak alat dekomposisi numpy.linalg; bab terakhir section ini, Stabilitas Numerik, membahas kapan hasil semua alat tersebut layak dipercaya.