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.