ANSI C +数值线性代数 - 使用线性求解器查找给定特征值的特征向量(问题)
我用 ANSI C 编写了一个使用 Householder 反射/变换的线性求解器,它在给定 A 和 b 的情况下求解 Ax=b。我想用它来查找与特征值相关的特征向量,如下所示:
(A-lambda*I)x = 0
问题是 0 向量始终是我得到的解(在有人说之前,是的,我有 100% 确定性的正确特征值)。
这里有一个非常准确地说明问题的示例:
给定A-lambda*I
(示例恰好是埃尔米特式):
1 2 0 | 0
2 1 4 | 0
0 4 1 | 0
Householder反射/转换将产生类似这样的结果
# # # | 0
0 # # | 0
0 0 # | 0
返回替换显然,你会发现解是{0,0,0}
。
I have written a linear solver employing Householder reflections/transformations in ANSI C which solves Ax=b given A and b. I want to use it to find the eigenvector associated with an eigenvalue, like this:
(A-lambda*I)x = 0
The problem is that the 0 vector is always the solution that I get (before someone says it, yes I have the correct eigenvalue with 100% certainty).
Here's an example which pretty accurately illustrates the issue:
Given A-lambda*I
(example just happens to be Hermitian):
1 2 0 | 0
2 1 4 | 0
0 4 1 | 0
Householder reflections/transformation will yield something like this
# # # | 0
0 # # | 0
0 0 # | 0
Back substitution will find that solution is {0,0,0}
, obviously.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我已经有一段时间没有编写特征求解器了,但我似乎记得技巧是将其从
(A - lambda*I) * x = 0
重构为A*x = lambda * x 。然后,您的 Householder 或 Givens 步骤将为您提供类似以下内容:
...您可以从中进行反向替换,而不会到达简并 0 向量。通常您还希望以标准化形式传递 x。
我的记忆在这里很生锈,所以我建议检查 Golub & Van Loan 给出了明确的答案。要使其稳健地工作,需要很多技巧,特别是对于非对称情况。
It's been a while since I've written an eigensolver, but I seem to recall that the trick was to refactor it from
(A - lambda*I) * x = 0
toA*x = lambda*x
. Then your Householder or Givens steps will give you something like:...from which you can back substitute without reaching the degenerate 0 vector. Usually you'll want to deliver x in normalized form as well.
My memory is quite rusty here, so I'd recommend checking Golub & Van Loan for the definitive answer. There are quite a few tricks involved in getting this to work robustly, particularly for the non-symmetric case.
这与@Drew 的答案基本相同,但解释有点不同。
如果 A 是矩阵
,则特征值为 lambda = 1、1+sqrt(20)、1-sqrt(20)。为了简单起见,我们假设 lambda = 1。那么系统的增广矩阵
(A - lambda*I) * x = 0
是现在您执行 Householder / Gives 将其简化为上三角形式。正如您所说,您会得到以下形式的内容
然而,最后一个
#
应该为零(或几乎为零)。你得到的确切结果取决于你所做的转换的细节,但如果我手工做,我会得到现在你做回代。在第一步中,您求解最后一行中的方程。但是,该方程不会产生任何信息,因此您可以将
x[2]
(向量x
的最后一个元素)设置为您想要的任何值。如果将其设置为零并继续用该值进行反向替换,则会得到零向量。如果将其设置为 1(或任何非零值),您将得到一个非零向量。 Drew 的答案背后的想法是将最后一行替换为0 0 1 | 1
将x[2]
设置为 1。舍入误差意味着最后一个应该为零的
#
可能不完全为零,而是有些小值,如 1e-16。这可以忽略:只需将其视为零并将x[2]
设置为 1。强制性警告:我假设您出于娱乐或教育目的而实施此操作。如果您需要在严肃的代码中查找特征向量,那么您最好使用其他人编写的代码,因为这些东西很难得到正确的结果。
This is basically the same answer as @Drew, but explained a bit differently.
If A is the matrix
then the eigenvalues are lambda = 1, 1+sqrt(20), 1-sqrt(20). Let us take for simplicity lambda = 1. Then the augmented matrix for the system
(A - lambda*I) * x = 0
isNow you do the Householder / Givens to reduce it to upper triangular form. As you say, you get something of the form
However, the last
#
should be zero (or almost zero). Exactly what you get depends on the details of the transformations you do, but if I do it by hand I getNow you do backsubstitution. In the first step, you solve the equation in the last row. However, this equation does not yield any information, so you can set
x[2]
(the last element of the vectorx
) to any value you want. If you set it to zero and continue the back-substitution with that value, you get the zero vector. If you set it to one (or any nonzero value), you get a nonzero vector. The idea behind Drew's answer is to replace the last row with0 0 1 | 1
which setsx[2]
to 1.Round-off error means that the last
#
, which should be zero, is probably not quite zero but some small value like 1e-16. This can be ignored: just take it as zero and setx[2]
to one.Obligatory warning: I assume you are implementing this for fun or educational purposes. If you need to find eigenvectors in serious code, you are better off using code written by others as this stuff is tricky to get right.