在谐波振荡器的情况下,为什么SciPy eigsh()会产生错误的特征值?


15

我正在开发一些更大的代码,以在计算物理学的背景下执行巨大的稀疏矩阵的特征值计算。由于特征值在分析上是众所周知的,因此我在一维上针对简单的谐波振荡器测试了例程。这样做并将我自己的例程与SciPy的内置求解器进行比较,我遇到了下图中显示的异常情况。在这里可以看到第一个100个数值地计算本征值和分析本征值λ 一个Ñ 一个λñüλ一种ñ一种

在特征值40附近,数值结果开始与分析结果有所不同。这并不令我感到惊讶(除非在讨论中提到,否则我不会在这里解释原因)。但是,惊讶的eigsh()会生成简并的特征值(大约特征值80)。为什么即使很少的特征值,eigsh()的行为也是如此?

在此处输入图片说明

import numpy as np
from scipy.sparse.linalg import eigsh
import myFunctions as myFunc
import matplotlib.pyplot as plt

#discretize x-axis
N = 100
xmin = -10.
xmax = 10.
accuracy = 1e-5
#stepsize
h = (xmax - xmin) / (N + 1.)
#exclude first and last points since we force wave function to be zero there
x = np.linspace(-10. + h,10. - h,N)
#create potential
V = x**2

def fivePoint(N,h,V):
    C0 = (np.ones(N))*30. / (12. * h * h) + V
    C1 = (np.ones(N)) * (-16.) / (12. * h * h)
    C2 = (np.ones(N)) / (12. * h * h)
    H = sp.spdiags([C2, C1, C0, C1, C2],[-2, -1, 0, 1, 2],N,N)
    return H

H = myFunc.fivePoint(N,h,V)
eigval,eigvec = eigsh(H, k=N-1, which='SM', tol=accuracy)

#comparison analytical and numerical eigenvalues
xAxes = np.linspace(0,len(eigval)-1,len(eigval))
analyticalEigval = 2. * (xAxes + 0.5)
plt.figure()
plt.plot(xAxes,eigval, '+', label=r"$\lambda_{num}$")
plt.plot(xAxes,analyticalEigval, label=r"$\lambda_{ana}$")
plt.xlabel("Number of Eigenvalue")
plt.ylabel("Eigenvalue")
plt.legend(loc=4)
plt.title("eigsh()-method: Comparison of $\lambda_{num}$ and $\lambda_{ana}$")
plt.show()

这是一个非常奇怪的行为。我将在今天晚些时候对其进行测试。
拉斐尔·赖特2013年

我找到了答案。简而言之:我的想法是错误的。谐波振荡器(HOSZ)的分析解决方案有效,没有任何空间限制。但是,在上面的代码中,我的框是从-10到10,因此这为数值解添加了边界条件。因此,eigsh()解决了正确给出的系统。在n = 50左右(n为主要量子数)时,分析溶液不再适合-10,10盒。现在(经过一番思考),这似乎很明显。但是,在构建和测试代码时我没有看到。
2013年

但这仍然不能解释退化,是吗?
2013年

Answers:


12

在我看来,某些特征值的简并性就像是Lanczos算法崩溃的标志。Lanczos算法是一种用于近似Hermitian矩阵的特征值和特征向量的方法之一。这是scipy.eigsh()通过调用ARPACK库使用的

在精确算术中,Lanczos算法会生成一组正交向量,但在浮点算术中,它们可能无法正交,甚至变得与线性相关。真正令人烦恼的是,正交性的损失恰好发生在一个近似特征值已收敛到一个真实特征值中时-可以这么说,算法破坏了自身。结果是您将得到附近一些特征值的虚假对。有多种解决方案,例如,使用Gram-Schmidt强制每个收敛的特征向量在每一步都是正交的。

但是,没有一种方法是完美的,特别是如果您要计算矩阵的整个光谱。因此,如果您尝试获得50个最小的特征值,最好使用具有100个元素的向量来逼近波动函数,并且只要求eigsh()前50个能级,而不要使用具有50个点的向量来求所有的特征值。

如果您想了解更多信息,请查看Yousef Saad的大型特征值问题数值方法

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.