python 中的特征向量给出看似随机的元素符号
Eigen vectors in python giving seemingly random element-wise signs
我是运行以下代码:
import numpy as np
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
N = 100
t = 1
a1 = np.full((N-1,), -t)
a2 = np.full((N,), 2*t)
Hamiltonian = np.diag(a1, -1) + np.diag(a2) + np.diag(a1, 1)
eval, evec = np.linalg.eig(Hamiltonian)
idx = eval.argsort()[::-1]
eval, evec = eval[idx], evec[:,idx]
wave2 = evec[2] / np.sum(abs(evec[2]))
prob2 = evec[2]**2 / np.sum(evec[2]**2)
_ = plt.plot(wave2)
_ = plt.plot(prob2)
plt.show()
而出来的剧情是这样的:
但我希望蓝线也是正弦曲线。这让我很困惑,我找不到导致符号突然变化的原因。绘制函数绝对表明与每个 x 关联的值都很好,但符号搞砸了。
关于可能导致此问题或如何解决的任何想法?
我可能错了,但它们不都是有效的本征 vectors/values 吗?符号无关紧要,因为特征向量的定义是:
仅仅因为比例为负并不意味着它无效。
See this post about Matlab's eig that has a similar problem
解决这个问题的一种方法是简单地选择一个符号作为开始,然后将不符合该符号的所有内容乘以 -1(或者将每个元素的 abs
乘以您期望的符号).对于您的结果,这应该有效(没有任何内容超过 0)。
matlab 和 numpy 都不关心你要解决的问题,它的简单数学表明两个带符号的 eigenvector/value 组合都是有效的,你的值是正弦曲线,只是存在两组 eigenvector/value有效(消极和积极)
这是您的脚本的修改版本,可以满足您的预期。变化是:
- 更正了特征向量的索引;它们是
evec
. 的列
- 使用
np.linalg.eigh
而不是 np.linalg.eig
。这不是绝对必要的,但您不妨使用更高效的代码。
- 不要颠倒已排序特征值的顺序。我将特征值从最低到最高排序。因为
eigh
returns特征值是升序排列的,我只是把特征值排序的代码注释掉了
(只有第一个更改是必需的更正。)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
N = 100
t = 1
a1 = np.full((N-1,), -t)
a2 = np.full((N,), 2*t)
Hamiltonian = np.diag(a1, -1) + np.diag(a2) + np.diag(a1, 1)
eval, evec = np.linalg.eigh(Hamiltonian)
#idx = eval.argsort()[::-1]
#eval, evec = eval[idx], evec[:,idx]
k = 2
wave2 = evec[:, k] / np.sum(abs(evec[:, k]))
prob2 = evec[:, k]**2 / np.sum(evec[:, k]**2)
_ = plt.plot(wave2)
_ = plt.plot(prob2)
plt.show()
剧情:
我是运行以下代码:
import numpy as np
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
N = 100
t = 1
a1 = np.full((N-1,), -t)
a2 = np.full((N,), 2*t)
Hamiltonian = np.diag(a1, -1) + np.diag(a2) + np.diag(a1, 1)
eval, evec = np.linalg.eig(Hamiltonian)
idx = eval.argsort()[::-1]
eval, evec = eval[idx], evec[:,idx]
wave2 = evec[2] / np.sum(abs(evec[2]))
prob2 = evec[2]**2 / np.sum(evec[2]**2)
_ = plt.plot(wave2)
_ = plt.plot(prob2)
plt.show()
而出来的剧情是这样的:
但我希望蓝线也是正弦曲线。这让我很困惑,我找不到导致符号突然变化的原因。绘制函数绝对表明与每个 x 关联的值都很好,但符号搞砸了。
关于可能导致此问题或如何解决的任何想法?
我可能错了,但它们不都是有效的本征 vectors/values 吗?符号无关紧要,因为特征向量的定义是:
仅仅因为比例为负并不意味着它无效。
See this post about Matlab's eig that has a similar problem
解决这个问题的一种方法是简单地选择一个符号作为开始,然后将不符合该符号的所有内容乘以 -1(或者将每个元素的 abs
乘以您期望的符号).对于您的结果,这应该有效(没有任何内容超过 0)。
matlab 和 numpy 都不关心你要解决的问题,它的简单数学表明两个带符号的 eigenvector/value 组合都是有效的,你的值是正弦曲线,只是存在两组 eigenvector/value有效(消极和积极)
这是您的脚本的修改版本,可以满足您的预期。变化是:
- 更正了特征向量的索引;它们是
evec
. 的列
- 使用
np.linalg.eigh
而不是np.linalg.eig
。这不是绝对必要的,但您不妨使用更高效的代码。 - 不要颠倒已排序特征值的顺序。我将特征值从最低到最高排序。因为
eigh
returns特征值是升序排列的,我只是把特征值排序的代码注释掉了
(只有第一个更改是必需的更正。)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
N = 100
t = 1
a1 = np.full((N-1,), -t)
a2 = np.full((N,), 2*t)
Hamiltonian = np.diag(a1, -1) + np.diag(a2) + np.diag(a1, 1)
eval, evec = np.linalg.eigh(Hamiltonian)
#idx = eval.argsort()[::-1]
#eval, evec = eval[idx], evec[:,idx]
k = 2
wave2 = evec[:, k] / np.sum(abs(evec[:, k]))
prob2 = evec[:, k]**2 / np.sum(evec[:, k]**2)
_ = plt.plot(wave2)
_ = plt.plot(prob2)
plt.show()
剧情: