6.13. Aljabar Linear¶
Aljabar linear pada kamera adalah pekerjaan matriks kecil: rotasi 3x3 yang memadukan sampel IMU ke bingkai dunia, matriks kalibrasi yang memperbaiki lensa, pembaruan kovariansi-state filter Kalman, pemasangan polinomial yang persamaan normalnya menjadi penyelesaian linear kecil. Submodul numpy.linalg dan scipy.linalg mencakup skala tersebut dengan tepat.
Fungsi-fungsi tersebut tersebar di dua modul. Operasi perkalian matriks berada di tingkat atas numpy; dekomposisi dan invers matriks berada di bawah numpy.linalg; pemecah sistem linear khusus berada di bawah scipy.linalg. Perkalian matriks 2-kali-2, misalnya:
from ulab import numpy as np
A = np.array([[1, 2], [3, 4]], dtype=np.float)
B = np.array([[5, 6], [7, 8]], dtype=np.float)
np.dot(A, B)
# array([[19.0, 22.0],
# [43.0, 50.0]])
6.13.1. Apa yang tersedia¶
dot()-- perkalian matriks atau vektor.cross()-- perkalian silang vektor 3-D.trace()-- jumlah elemen diagonal.inv()-- invers matriks.det()-- determinan.cholesky()-- dekomposisi Cholesky (input simetris positif-definit).eig()-- nilai eigen dan vektor eigen dari matriks simetris nyata.norm()-- norma-2 dari vektor atau matriks.qr()-- dekomposisi QR denganmode='reduced'(default) ataumode='complete'.solve_triangular()-- selesaikanA @ x = bketikaAsegitiga.cho_solve()-- selesaikanA @ x = bdiberikan faktor Cholesky dariA.
6.13.2. dot, cross, trace¶
dot() adalah cara penulisan perkalian matriks pada kamera. Operator @ yang disediakan numpy desktop untuk pekerjaan yang sama tidak diimplementasikan pada ndarray, sehingga setiap perkalian matriks-vektor, matriks-matriks, dan titik vektor melewati panggilan dot()
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
np.dot(a, b) # 32.0 (scalar product)
np.cross(a, b) # array([-3.0, 6.0, -3.0])
m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
np.dot(m, a) # matrix-vector product
np.dot(m, m) # matrix-matrix product
np.trace(m) # 1 + 5 + 9 = 15.0
Hasil dari dot() selalu bertipe dtype float. cross() adalah perkalian silang dua 3-vektor, trace() adalah jumlah diagonal utama dari matriks persegi.
6.13.3. inv dan det¶
m = np.array([[1, 2, 3, 4],
[4, 5, 6, 4],
[7, 9, 9, 4],
[3, 4, 5, 6]])
print(np.linalg.inv(m))
print(np.linalg.det(m))
Invers dihitung dengan eliminasi Gauss-Jordan, sehingga inv() memunculkan ValueError ketika matriks singular (entri diagonal menjadi nol selama eliminasi). Biaya RAM kira-kira dua kali ukuran input.
Determinan menggunakan eliminasi yang sama -- waktu eksekusinya pada dasarnya sama dengan invers.
Ketika tujuan aplikasi adalah menyelesaikan sistem linear, jangan membalik dan mengalikan -- lebih baik gunakan pemecah khusus di bawah. Keduanya lebih cepat dan lebih baik secara numerik.
6.13.4. cholesky¶
Untuk matriks simetris positif-definit A, cholesky() mengembalikan L segitiga-bawah sehingga A = L @ L.T
a = np.array([[25, 15, -5],
[15, 18, 0],
[-5, 0, 11]])
L = np.linalg.cholesky(a)
Jika input tidak positif-definit atau tidak simetris, ValueError dimunculkan.
Faktor Cholesky adalah setengah pekerjaan dari faktorisasi LU dan merupakan titik awal yang tepat untuk masalah yang matriksnya diketahui simetris positif-definit (pembaruan kovariansi, persamaan normal dari pemasangan kuadrat terkecil).
6.13.5. eig¶
eig() hanya bekerja pada matriks simetris nyata. Matriks non-simetris memunculkan ValueError. Fungsi ini mengembalikan tuple-2 (eigenvalues, eigenvectors)
a = np.array([[1, 2, 1, 4],
[2, 5, 3, 5],
[1, 3, 6, 1],
[4, 5, 1, 7]], dtype=np.uint8)
x, y = np.linalg.eig(a)
Catatan:
Nilai eigen dikembalikan tanpa urutan tertentu. Terapkan
sort()(dan permutasi yang sama pada vektor eigen melaluiargsort()) ketika urutan yang terurut diperlukan.Vektor eigen unik hanya hingga skalar tak-nol, sehingga tanda vektor eigen individual tidak didefinisikan secara unik. Dua eksekusi yang benar dapat menghasilkan vektor bertanda berlawanan; ini tidak berbahaya.
6.13.6. norm¶
Norma Euclidean (Frobenius) dari vektor atau matriks:
v = np.array([1, 2, 3, 4, 5])
m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
np.linalg.norm(v) # 7.416...
np.linalg.norm(m) # 16.881...
Kata kunci opsional axis= mengambil norma sepanjang satu sumbu alih-alih seluruh array.
6.13.7. qr¶
qr() memfaktorkan matriks persegi panjang A (bentuk (M, N)) menjadi Q ortonormal dan R segitiga atas sehingga A == Q @ R
A = np.arange(6).reshape((3, 2))
q, r = np.linalg.qr(A)
# mode='reduced' (default): q is (3, 2), r is (2, 2)
q, r = np.linalg.qr(A, mode='complete')
# q is (3, 3), r is (3, 2)
Dekomposisi diimplementasikan melalui rotasi Givens berurutan. Pilihan yang tepat untuk masalah kuadrat terkecil di mana matriks tidak simetris.
6.13.8. Menyelesaikan sistem¶
Dua pemecah khusus di bawah ulab.scipy.linalg keduanya lebih cepat dan lebih akurat daripada np.dot(np.linalg.inv(A), b):
solve_triangular(a, b, lower=False)()-- selesaikana @ x = bdengan asumsiaadalah segitiga:A = np.array([[3, 0, 0, 0], [2, 1, 0, 0], [1, 0, 1, 0], [1, 2, 1, 8]]) b = np.array([4, 2, 4, 2]) x = sp.linalg.solve_triangular(A, b, lower=True)
cho_solve(L, b)()-- diberikan faktor CholeskyL, selesaikanA @ x = bdi manaA = L @ L.TL = np.linalg.cholesky(A) x = sp.linalg.cho_solve(L, b)
Gunakan ini alih-alih membalik kapan pun struktur A memungkinkan -- keduanya menghemat pekerjaan eliminasi dan invers eksplisit.
6.13.9. Menyelesaikan sistem linear kecil¶
A = np.array([[3, 0, 1, 1],
[0, 1, 0, 2],
[1, 0, 1, 1],
[1, 2, 1, 8]])
b = np.array([4, 2, 4, 2])
x = np.dot(np.linalg.inv(A), b)
print(x)
print(np.dot(A, x)) # should equal b
Masalah yang sama dapat diekspresikan dengan memfaktorkan A dan memanggil pemecah yang sesuai -- lebih cepat dan lebih akurat ketika A memiliki struktur yang tepat.
Untuk referensi lengkap tingkat argumen, lihat numpy.linalg --- Rutin Aljabar Linear dan scipy.linalg --- Rutin aljabar linear.