Vectơ và ma trận
Vectơ là danh sách phẳng các số, chẳng hạn biểu diễn hướng trong không gian hoặc một bộ đại lượng. Ma trận là danh sách các hàng. Trang này hướng dẫn tích vô hướng, tích có hướng, nhân ma trận, định thức, ma trận nghịch đảo, giải hệ phương trình tuyến tính và các công cụ đại số tuyến tính bằng phương pháp số: giá trị riêng cùng các phép phân rã QR, LU và phân rã giá trị suy biến.
Tiếp cận nó cho các môn học đại số tuyến tính, hình học và biến đổi, hoặc bất kỳ vấn đề nào với một số ẩn số được liên kết với nhau bằng phương trình đường thẳng. Vectơ và ma trận là các danh sách thông thường, vì vậy mọi thứ trong Danh sách và thống kê, chẳng hạn như lập chỉ mục, cũng được áp dụng.
Các vectơ
dot([1, 2, 3], [4, 5, 6]) cho kết quả 32dot([3, 4], [4, -3]) cho kết quả 0cross([1, 0, 0], [0, 1, 0]) cho kết quả [0, 0, 1]cross([1, 2, 3], [4, 5, 6]) cho kết quả [-3, 6, -3]v = [3, 4]sqrt(dot(v, v)) cho kết quả 5dot nhân các phần tử tương ứng rồi cộng kết quả. Tích vô hướng bằng không cho biết hai vectơ vuông góc, như [3, 4] và [4, -3]. cross trả về vectơ vuông góc với cả hai vectơ đầu vào: tích có hướng của vectơ theo chiều x với vectơ theo chiều y cho vectơ theo chiều z. Độ dài vectơ bằng căn bậc hai của tích vô hướng của nó với chính nó.
dot cần hai vectơ có cùng độ dài, và cross cần hai vectơ gồm ba phần tử. Để thêm vectơ hoặc chia tỷ lệ chúng, hãy sử dụng số học danh sách thông thường: [1, 2] + [3, 4] là [4, 6] và 2 * [3, 4] là [6, 8].
Viết và nhân ma trận
Viết một ma trận dưới dạng danh sách các hàng, mỗi hàng trong dấu ngoặc vuông riêng của nó:
shape([[1, 2, 3], [4, 5, 6]]) cho kết quả [2, 3]transpose([[1, 2, 3], [4, 5, 6]]) cho kết quả [[1, 4], [2, 5], [3, 6]]identity(3) cho kết quả [[1, 0, 0], [0, 1, 0], [0, 0, 1]][[1, 2], [3, 4]] * [[5, 6], [7, 8]] cho kết quả [[19, 22], [43, 50]]shape trả về [rows, columns]. transpose hoán đổi hàng và cột. identity(n) là ma trận đơn vị kích thước n × n: nhân một ma trận với nó sẽ giữ nguyên ma trận kia.
* giữa hai ma trận là phép nhân ma trận, cần ma trận bên trái có nhiều cột như ma trận bên phải có hàng. Để nhân một ma trận với một vectơ, hãy viết vectơ dưới dạng một cột, một phần tử trên mỗi hàng:
# Rotate the point (3, 1) by 90° anticlockwiserotate = [[0, -1], [1, 0]]rotate * [[3], [1]] cho kết quả [[-1], [3]]rotate * rotate cho kết quả [[-1, 0], [0, -1]]Việc xoay hai lần 90° sẽ tạo ra một vòng quay nửa, đó là lý do tại sao rotate * rotate đảo ngược cả hai dấu. Một danh sách phẳng như [3, 1] không được chấp nhận ở phía bên phải của ma trận. Nếu bạn có một danh sách phẳng trong một tên, transpose([v]) sẽ chuyển nó thành một cột.
Các ma trận có cùng hình dạng có thể được cộng và trừ, và nhân hoặc chia với một giá trị số, giống như các danh sách khác.
Một vài quy tắc áp dụng cho mọi thao tác ma trận:
- Mỗi hàng phải có cùng số lượng phần tử.
- Các yếu tố phải là những con số đơn giản. Đơn vị và tiền không được chấp nhận.
- Một ma trận có thể có tối đa 32 hàng và 32 cột.
- Không có dấu chấm phẩy. Viết
[[1, 2], [3, 4]], không phải[1, 2; 3, 4].
Định thức, nghịch đảo, vết và hạng
M = [[2, 1], [5, 3]]det(M) cho kết quả 1inverse(M) cho kết quả [[3, -1], [-5, 2]]M * inverse(M) cho kết quả [[1, 0], [0, 1]]trace(M) cho kết quả 5inverse([[2, 1], [1, 3]]) cho kết quả [[0.6, -0.2], [-0.2, 0.4]]det([[1, 2], [2, 4]]) cho kết quả 0rank([[1, 2, 3], [2, 4, 6]]) cho kết quả 1det, inverse và trace (tổng các phần tử trên đường chéo chính) cần ma trận vuông. Định thức bằng không nghĩa là ma trận suy biến: các hàng không độc lập tuyến tính, nên không có ma trận nghịch đảo và inverse([[1, 2], [2, 4]]) gây lỗi. rank đếm số hàng độc lập tuyến tính và cũng chấp nhận ma trận không vuông. Ở dòng cuối, hàng thứ hai gấp đôi hàng thứ nhất, nên hạng bằng 1.
Bốn hàm này dùng phân số chính xác thay cho số thập phân, nên M * inverse(M) trả về đúng ma trận đơn vị.
Giải hệ tuyến tính
Giả sử ba ly cà phê và hai ly trà có giá 13,50 bảng Anh, và một ly cà phê và bốn ly trà có giá 11,50 bảng Anh. Đặt số lượng của mỗi đồ uống trong một hàng cho mỗi phương trình, với các cột theo thứ tự cố định (cà phê, trà) và tổng số trong danh sách phù hợp:
solve_system([[3, 2], [1, 4]], [13.5, 11.5]) cho kết quả [3.1, 2.1]Câu trả lời theo thứ tự như các cột: một ly cà phê có giá 3,10 bảng Anh và một ly trà có giá 2,10 bảng Anh. Tắt các ký hiệu tiền tệ, vì các phần tử ma trận phải là số thuần túy.
solve_system(A, b) tìm x thỏa A * x = b. Hàm cần ma trận vuông với một hàng cho mỗi ẩn số, cùng danh sách phẳng các giá trị vế phải có cùng độ dài. Hàm dùng phân số chính xác nên kết quả không có sai số làm tròn.
Nếu các phương trình không đưa ra một đáp án duy nhất, bạn sẽ nhận được lỗi thông báo hệ thống không có nghiệm duy nhất. Ví dụ, solve_system([[1, 2], [2, 4]], [3, 6]) không hoạt động vì phương trình thứ hai là phương trình đầu tiên được nhân đôi. solve_system chỉ xử lý các phương trình đường thẳng (hàm tuyến tính); đối với phương trình như x^2 = 2, hãy sử dụng solve từ Tổng, giải phương trình và giải tích.
Giá trị riêng
eigenvalues([[2, 1], [1, 2]]) cho kết quả [1, 3]eigenvalues([[4, 1], [2, 3]]) cho kết quả [5, 2]eigenvalues([[0, -1], [1, 0]]) cho kết quả [i, -i]eigenvalues nhận ma trận vuông và trả về danh sách phẳng. Phép quay 90° không giữ nguyên hướng nào, nên các giá trị riêng là cặp số phức i và -i; xem Số phức. Đừng dựa vào thứ tự các phần tử trong danh sách.
Phân rã: QR, LU và SVD
Mỗi phân tích trả về một danh sách các ma trận. Sử dụng các chỉ mục để lấy ra các bộ phận:
A = [[3, 0], [4, 5]]parts = qr(A)q = parts[0] cho kết quả [[0.6, -0.8], [0.8, 0.6]]r = parts[1] cho kết quả [[5, 4], [0, 3]]q * r cho kết quả [[3, 0], [4, 5]]Nhân các thừa số lại cho kết quả A, giúp bạn kiểm tra phép phân rã ngay. Tính toán bằng số dấu phẩy động nhị phân để lại sai số làm tròn rất nhỏ, khoảng 10⁻¹⁵; Varlig hiển thị chúng là 0 trong danh sách và ma trận. Các giá trị được lưu vẫn giữ mọi chữ số, nên hãy kiểm tra kết quả phân rã bằng mắt hoặc xét hiệu, không dùng ==.
lu([[2, 1], [4, 3]]) cho kết quả [[[0, 1], [1, 0]], [[1, 0], [0.5, 1]], [[4, 3], [0, -0.5]]]lu trả về [P, L, U], trong đó P ghi lại bất kỳ hoán đổi hàng nào và P * A bằng L * U. Ở đây các hàng được hoán đổi để số lớn hơn, 4, được sử dụng trước.
B = [[3, 1], [4, 7]]f = svd(B)u = f[0]s = f[1]vt = f[2]u * [[s[0], 0], [0, s[1]]] * vt cho kết quả [[3, 1], [4, 7]]svd([[3, 4]]) cho kết quả [[[1]], [5], [[0.6, 0.8]]]svd trả về [U, s, Vt], trong đó s là danh sách phẳng các giá trị suy biến theo thứ tự giảm dần. Theo công thức trong sách giáo khoa, B bằng U * diag(s) * Vt. Không có hàm diag, nên hãy tự tạo ma trận đường chéo, như [[s[0], 0], [0, s[1]]].
| Hàm | Những gì nó cần và trả lại |
|---|---|
identity(n) |
Ma trận đơn vị kích thước n × n |
shape(A) |
[rows, columns] |
transpose(A) |
Các hàng và cột được hoán đổi |
det(A) |
Định thức của một ma trận vuông |
inverse(A) |
Nghịch đảo của một ma trận vuông với định thức khác không |
trace(A) |
Tổng các phần tử trên đường chéo chính của ma trận vuông |
rank(A) |
Số hàng độc lập; bất kỳ ma trận hình chữ nhật nào |
solve_system(A,b) |
Nghiệm của A * x = b với ma trận vuông và nghiệm duy nhất |
eigenvalues(A) |
Giá trị riêng của ma trận vuông, có thể là số phức, không theo thứ tự cụ thể |
qr(A) |
[Q, R] với Q * R xấp xỉ A; bất kỳ ma trận hình chữ nhật nào |
lu(A) |
[P, L, U] với P * A xấp xỉ L * U; ma trận vuông |
svd(A) |
[U, s, Vt], trong đó s là một danh sách phẳng; bất kỳ ma trận hình chữ nhật nào |
Đối với một ma trận không vuông, qr và svd trả về các thừa số mỏng: đối với ma trận 3 x 2, Q cũng là 3 x 2 thay vì 3 x 3.
Cái gì là chính xác, và cái gì bị từ chối
Với mọi ma trận Varlig chấp nhận, các phép cộng, trừ, nhân ma trận, nhân ma trận với một số, transpose, det và inverse đều được tính bằng phân số chính xác. Không có bước làm tròn khi nhận giá trị hoặc chuyển sang phép tính khác; vì vậy nhân ma trận với nghịch đảo của nó cho đúng ma trận đơn vị:
[[1, 2], [3, 4]] + [[10, 20], [30, 40]] cho kết quả [[11, 22], [33, 44]][[1, 2], [3, 4]] - [[1, 1], [1, 1]] cho kết quả [[0, 1], [2, 3]]3 * [[1, 2], [3, 4]] cho kết quả [[3, 6], [9, 12]][[1, 2], [3, 4]] * [[0, 1], [1, 0]] cho kết quả [[2, 1], [4, 3]]det([[1, 2], [3, 4]]) cho kết quả -2inverse([[1, 2], [3, 4]]) cho kết quả [[-2, 1], [1.5, -0.5]]inverse([[1, 2], [3, 4]]) * [[1, 2], [3, 4]] cho kết quả [[1, 0], [0, 1]]Mọi điều kiện đều được kiểm tra trước khi hiển thị kết quả; thông báo sẽ chỉ rõ điều kiện nào không được đáp ứng:
det([[1, 2, 3], [4, 5, 6]]) cho kết quả Unsupported: Expected a square matrixinverse([[1, 2], [2, 4]]) cho kết quả Unsupported: Singular matrix has no inverse[[1, 2], [3, 4]] + [[1, 2, 3], [4, 5, 6]] cho kết quả Unsupported: List dimensions do not match[[1, 2, 3], [4, 5, 6]] * [[1, 2], [3, 4]] cho kết quả Unsupported: Matrix inner dimensions do not matchPhần tử ma trận phải là số không kèm đơn vị. Nếu bất kỳ phần tử nào có đơn vị, là số tiền hoặc số phức, phép tính sẽ dừng thay vì tiếp tục xử lý, vì các phép toán ma trận không bảo toàn được những thông tin đó:
det([[1 kg, 2], [3, 4]]) cho kết quả Unsupported: Matrix entries must be plain numbers; units, money and complex values are not supportedChỉ một danh sách các hàng được đọc dưới dạng một ma trận. Một danh sách phẳng giữ ý nghĩa riêng của nó, vì vậy [1, 2] + [3, 4] vẫn là từng mục [4, 6], và [1, 2] * [3, 4] vẫn là một lỗi trỏ đến dot.
Để biết các quy tắc chính xác trên các phương trình, ma trận và thống kê ở cùng một nơi, hãy xem Công cụ đảm bảo điều gì.
Các thuật toán và giới hạn
det, inverse, rank và solve_system dùng phân số chính xác trong giới hạn độ lớn của số mà bộ máy tính toán hỗ trợ. eigenvalues, qr, lu và svd dùng số dấu phẩy động nhị phân, nên kết quả là giá trị gần đúng. Quá trình lặp dừng sau 10.000 bước.
Các ma trận có các hàng gần như phụ thuộc, chẳng hạn như [[1, 1], [1, 1.0000001]], được gọi là có điều kiện xấu. Các lỗi làm tròn nhỏ phát triển lớn khi bạn làm việc với chúng, vì vậy phân tích và giá trị riêng của các ma trận như vậy có thể mất độ chính xác và các trường hợp rất cực đoan có thể vượt quá giới hạn số và đưa ra lỗi.
Các quy tắc đầy đủ nằm trong tài liệu tham khảo toán học nâng cao.
Kết hợp các phần
Ba biên lai từ một quầy hàng ở chợ liệt kê số lượng táo, chuối và cam đã được mua và tổng số tiền đã thanh toán, nhưng không phải là giá riêng lẻ:
# Each row: apples, bananas, orangesbaskets = [[2, 3, 1], [1, 2, 3], [4, 1, 2]]paid = [2.15, 2.70, 3.05]det(baskets) cho kết quả 25prices = solve_system(baskets, paid) cho kết quả [0.4, 0.25, 0.6]# Check the prices against every receiptbaskets * transpose([prices]) cho kết quả [[2.15], [2.7], [3.05]]# What would 5 apples, 2 bananas and 4 oranges cost?dot([5, 2, 4], prices) cho kết quả 4.9Định thức khác không xác nhận các khoản thu đủ để tìm một bộ giá: táo ở mức 40p, chuối ở mức 25p và cam ở mức 60p. Nhân các giỏ với giá như một cột sẽ tái tạo tổng số và dot định giá một giỏ mới ở mức 4,90 bảng Anh.