2011-08-23 36 views
11

Tôi đang cố chuyển đổi mã chứa toán tử \ từ Matlab (Octave) sang Python. Mã mẫuBộ phận Ma trận Trái và Giải quyết Numpy

B = [2;4] 
b = [4;4] 
B \ b 

Điều này hoạt động và tạo ra 1,2 câu trả lời. Việc sử dụng trang web này

http://mathesaurus.sourceforge.net/matlab-numpy.html

tôi dịch rằng:

import numpy as np 
import numpy.linalg as lin 
B = np.array([[2],[4]]) 
b = np.array([[4],[4]]) 
print lin.solve(B,b) 

này đã cho tôi một lỗi:

numpy.linalg.linalg.LinAlgError: Array must be square 

Tại sao Matlab \ làm việc với ma trận không vuông cho B?

Bất kỳ giải pháp nào cho điều này?

Trả lời

14

Từ MathWorks documentation cho bộ phận ma trận trái:

If A is an m-by-n matrix with m ~= n and B is a column vector with m components, or a matrix with several such columns, then X = A\B is the solution in the least squares sense to the under- or overdetermined system of equations AX = B. In other words, X minimizes norm(A*X - B), the length of the vector AX - B.

Tương đương trong NumPy là np.linalg.lstsq:

In [15]: B = np.array([[2],[4]]) 

In [16]: b = np.array([[4],[4]]) 

In [18]: x,resid,rank,s = np.linalg.lstsq(B,b) 

In [19]: x 
Out[19]: array([[ 1.2]]) 
8

Matlab sẽ thực sự làm một số hoạt động khác nhau khi \ điều hành được sử dụng, tùy thuộc vào hình dạng của các ma trận liên quan (xem here để biết thêm chi tiết). Trong ví dụ của bạn, Matlab trả về một giải pháp bình phương nhỏ nhất, thay vì giải phương trình tuyến tính trực tiếp, như sẽ xảy ra với một ma trận vuông. Để có được hành vi tương tự như vậy, hãy thực hiện điều này:

import numpy as np 
import numpy.linalg as lin 
B = np.array([[2],[4]]) 
b = np.array([[4],[4]]) 
print np.linalg.lstsq(B,b)[0] 

nên cung cấp cho bạn giải pháp tương tự như Matlab.

1

Bạn có thể hình nghịch đảo trái:

import numpy as np 
import numpy.linalg as lin 
B = np.array([[2],[4]]) 
b = np.array([[4],[4]]) 

B_linv = lin.solve(B.T.dot(B), B.T) 
c = B_linv.dot(b) 
print('c\n', c) 

Kết quả:

c 
[[ 1.2]] 

Trên thực tế, chúng tôi chỉ đơn giản là có thể chạy các giải một lần, mà không tạo thành một nghịch đảo, như thế này:

c = lin.solve(B.T.dot(B), B.T.dot(b)) 
print('c\n', c) 

Kết quả:

c 
[[ 1.2]] 

.... như trước

Tại sao? Bởi vì:

Chúng tôi có:

enter image description here

Multiply qua bởi B.T, cho chúng ta:

enter image description here

Bây giờ, B.T.dot(B) là hình vuông, đầy đủ cấp bậc, không có một nghịch đảo. Và do đó chúng tôi có thể nhân thông qua nghịch đảo của B.T.dot(B) hoặc sử dụng người giải quyết như trên để có được c.

Các vấn đề liên quan