计算矩阵的零空间
我正在尝试求解 Ax = 0 形式的一组方程。A 是已知的 6x6 矩阵,我使用 SVD 编写了以下代码来获取在一定程度上有效的向量 x。答案大致正确,但不足以对我有用,我怎样才能提高计算的精度?将 eps 降低到 1.e-4 以下会导致函数失败。
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)
I'm attempting to solve a set of equations of the form Ax = 0. A is known 6x6 matrix and I've written the below code using SVD to get the vector x which works to a certain extent. The answer is approximately correct but not good enough to be useful to me, how can I improve the precision of the calculation? Lowering eps below 1.e-4 causes the function to fail.
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
A
是满秩 --- 所以x
是 0因为看起来您需要一个最小二乘解,即
min | |A*x|| st ||x|| = 1
,进行 SVD 使得[USV] = svd(A)
和V
的最后一列(假设各列按以下顺序排序)奇异值递减)是x
。即,
所以,
并且,
||A*x|| = 0.00027528
与之前的x
解决方案相反,其中||A*x_old|| = 0.079442
A
is full rank --- sox
is 0Since it looks like you need a least-squares solution, i.e.
min ||A*x|| s.t. ||x|| = 1
, do the SVD such that[U S V] = svd(A)
and the last column ofV
(assuming that the columns are sorted in order of decreasing singular values) isx
.I.e.,
So,
And,
||A*x|| = 0.00027528
as opposed to your previous solution forx
where||A*x_old|| = 0.079442
注意:python 与 matlab-syntax 中的 SVD 可能会产生混淆(?):
在 python 中,numpy.linalg.svd(A) 返回矩阵 u,s,v 使得 u*s*v = A
(严格来说:dot(u, dot(diag(s), v) = A,因为 s 是一个向量,而不是 numpy 中的二维矩阵)。
从这个意义上来说,最上面的答案是正确的,通常 你写 u*s*vh = A 并返回 vh,这个答案讨论 v 而不是 vh
长话短说:如果你有矩阵 u,s,v 使得 u*s*v = A,然后 v 的最后行,不是 v 的最后列,描述零空间
:[对于像我这样的人:]最后的每一行都是一个向量 v0。使得 A*v0 = 0(如果对应的奇异值为 0)
Attention: There might be confusion with the SVD in python vs. matlab-syntax(?):
in python, numpy.linalg.svd(A) returns matrices u,s,v such that u*s*v = A
(strictly: dot(u, dot(diag(s), v) = A, because s is a vector and not a 2D-matrix in numpy).
The uppermost Answer is correct in that sense that usually you write u*s*vh = A and vh is returned, and this answer discusses v AND NOT vh.
To make a long story short: if you have matrices u,s,v such that u*s*v = A, then the last rows of v, not the last colums of v, describe the nullspace.
Edit: [for people like me:] each of the last rows is a vector v0 such that A*v0 = 0 (if the corresponding singular value is 0)