2010-06-07 74 views
11

Tôi đang cố giải quyết một tập hợp các phương trình của dạng Ax = 0. A là ma trận 6x6 và tôi đã viết mã dưới đây bằng SVD để lấy vector x hoạt động Một mức độ nhất định. Câu trả lời là gần đúng nhưng không đủ tốt để có ích cho tôi, làm thế nào tôi có thể cải thiện độ chính xác của phép tính? Giảm eps dưới 1.e-4 khiến chức năng thất bại.Tính toán không gian trống của ma trận

from numpy.linalg import * 
from numpy import * 

A = matrix([[0.624010149127497 ,0.020915658603923 ,0.838082638087629 ,62.0778180312547 ,-0.336 ,0], 
[0.669649399820597 ,0.344105317421833 ,0.0543868015800246 ,49.0194290212841 ,-0.267 ,0], 
[0.473153758252885 ,0.366893577716959 ,0.924972565581684 ,186.071352614705 ,-1 ,0], 
[0.0759305208803158 ,0.356365401030535 ,0.126682113674883 ,175.292109352674 ,0 ,-5.201], 
[0.91160934274653 ,0.32447818779582 ,0.741382053883291 ,0.11536775372698 ,0 ,-0.034], 
[0.480860406786873 ,0.903499596111067 ,0.542581424762866 ,32.782593418975 ,0 ,-1]]) 

def null(A, eps=1e-3): 
    u,s,vh = svd(A,full_matrices=1,compute_uv=1) 
    null_space = compress(s <= eps, vh, axis=0) 
    return null_space.T 

NS = null(A) 
print "Null space equals ",NS,"\n" 
print dot(A,NS) 

Trả lời

9

A đầy rank --- rất x

Kể từ khi có vẻ như bạn cần một giải pháp bình phương nhỏ nhất, tức là min ||A*x|| s.t. ||x|| = 1, làm SVD mà [U S V] = svd(A) và cột cuối cùng của V (giả sử rằng các cột được sắp xếp theo thứ tự các giá trị số ít giảm) là x.

Ie,

U = 

    -0.23024  -0.23241  0.28225  -0.59968  -0.04403  -0.67213 
     -0.1818  -0.16426  0.18132  0.39639  0.83929  -0.21343 
    -0.69008  -0.59685  -0.18202  0.10908  -0.20664  0.28255 
    -0.65033  0.73984 -0.066702  -0.12447  0.088364  0.0442 
    -0.00045131 -0.043887  0.71552  -0.32745  0.1436  0.59855 
    -0.12164  0.11611  0.5813  0.59046  -0.47173  -0.25029 


S = 

     269.62   0   0   0   0   0 
      0  4.1038   0   0   0   0 
      0   0  1.656   0   0   0 
      0   0   0  0.6416   0   0 
      0   0   0   0  0.49215   0 
      0   0   0   0   0 0.00027528 


V = 

    -0.002597  -0.11341  0.68728  -0.12654  0.70622 0.0050325 
    -0.0024567  0.018021  0.4439  0.85217  -0.27644 0.0028357 
    -0.0036713  -0.1539  0.55281  -0.4961  -0.6516 0.00013067 
     -0.9999 -0.011204 -0.0068651 0.0013713 0.0014128 0.0052698 
    0.0030264  0.17515  0.02341 -0.020917 -0.0054032  0.98402 
    0.012996  -0.96557  -0.15623  0.10603  0.014754  0.17788 

Vì vậy,

x = 

    0.0050325 
    0.0028357 
    0.00013067 
    0.0052698 
     0.98402 
     0.17788 

Và, ||A*x|| = 0.00027528 như trái ngược với giải pháp trước đó của bạn cho x nơi ||A*x_old|| = 0.079442

+0

x = 0 là một giải pháp cho vấn đề , nhưng một điều không thú vị. Giải pháp thực sự cho vấn đề, đến bằng các cách khác nhau là: [0.880057009282733,0.571293018023548,0.0664250041765576,1,186.758799941964,33.7579819749057] T – Ainsworth

+0

Bạn có chắc chắn không? Tôi thấy một số phần tử khác không trong kết quả của 'A * x' ---' [-0.056356 -0.055643 -7.3896e-013 -0.0043278 0,00483 -2.1316e-014] ' – Jacob

+0

Trừ khi tất nhiên, bạn không muốn không gian trống, nhưng giải pháp bình phương nhỏ nhất, nghĩa là 'min || A * x || s.t. || x || = 1' – Jacob

5

Chú ý: Có thể có sự nhầm lẫn với SVD trong python so với matlab-syntax (?): trong python, numpy.linalg.svd (A) trả về ma trận u, s, vs uch rằng u * s * v = A (nghiêm ngặt: dấu chấm (u, dấu chấm (diag (s), v) = A, bởi vì s là một vec-tơ và không phải là ma trận 2D ở dạng numpy).

Câu trả lời trên cùng là chính xác theo nghĩa đó thường là bạn viết u * s * vh = A và vh được trả về và câu trả lời này thảo luận v VÀ NOT vh.

Để thực hiện một câu chuyện dài ngắn: nếu bạn có ma trận u, s, v mà u * s * v = A, sau đó các hàng cuối cùng của v, không colums cuối cùng của v, mô tả không gian rỗng.

Edit: [cho những người như tôi:] mỗi dòng cuối cùng là một v0 vector mà A * v0 = 0 (nếu giá trị đơn lẻ tương ứng là 0)

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