我有一个6x6
矩阵H
,它的两个特征值在参数l
的某些值处变得复杂(对于λ)。显然,它们是对角化H
之后的特征值数组E
的前两个元素(调用np.linalg.eig
模块)。然而,当它们变成实数时(在我的例子中,当l
在-1和1之间时),这个序列就不会被保持。我可以通过将它们与精确的解析表达式进行比较来跟踪它们。
请看下面的代码:
import numpy as np
import matplotlib.pyplot as plt
import cmath
dim=6; t=1.0; eps=0.5; U = 2.0
# Initialize H
H=np.zeros((dim,dim),float)
# Vary parameter l
for l in np.linspace(-2,2,3):
# Construct H-matrix (size: 6 x 6)
tm=t-l; tp=t+l
H[0][0]=H[2][2]=H[3][3]=H[5][5]=2.0*eps
H[1][1]=H[4][4]=2.0*eps+U
H[1][2]=H[2][4]=tm
H[2][1]=H[4][2]=tp
H[1][3]=H[3][4]=-tm
H[3][1]=H[4][3]=-tp
# Diagonalize H
E,psi=np.linalg.eig(H)
# Print all the eigenvalues
print('lambda=',l,'===>')
print()
print('First two eigenvalues: E0=',E[0], 'E1=',E[1] )
print('Always real eigenvalues: E2=',E[2], 'E3=',E[3], 'E4=',E[4], 'E5=',E[5] )
print()
print("Expected sometimes complex eigenvalues:")
print("2\eps+[U+\srqt{16(t^2-\lambda^2)+U^2}]/2=",2.0*eps+(U+cmath.sqrt(16*tp*tm+U**2) )*0.5,"degeneracy=1")
print("2\eps+[U-\srqt{16(t^2-\lambda^2)}+U^2]/2=",2.0*eps+(U-cmath.sqrt(16*tp*tm+U**2) )*0.5,"degeneracy=1")
print("Expected always real eigenvalues:")
print("2\eps=",2.0*eps,"degeneracy=3")
print("2\eps+U=",2.0*eps+U,"degeneracy=1")
print('---------------------')
print()
我如何维护序列,以便我可以只绘制l
(或λ)的“有时复杂”的特征值对?
输出:
lambda= -2.0 ===>
First two eigenvalues: E0= (2.0000000000000058+3.3166247903554043j) E1= (2.0000000000000058-3.3166247903554043j)
Always real eigenvalues: E2= (2.9999999999999982+0j) E3= (0.9999999999999999+0j) E4= (1+0j) E5= (1+0j)
Expected sometimes complex eigenvalues:
2\eps+[U+\srqt{16(t^2-\lambda^2)+U^2}]/2= (2+3.3166247903554j) degeneracy=1
2\eps+[U-\srqt{16(t^2-\lambda^2)}+U^2]/2= (2-3.3166247903554j) degeneracy=1
Expected always real eigenvalues:
2\eps= 1.0 degeneracy=3
2\eps+U= 3.0 degeneracy=1
---------------------
lambda= 0.0 ===>
First two eigenvalues: E0= -0.23606797749979025 E1= 2.9999999999999996
Always real eigenvalues: E2= 4.236067977499788 E3= 1.0 E4= 1.0 E5= 1.0
Expected sometimes complex eigenvalues:
2\eps+[U+\srqt{16(t^2-\lambda^2)+U^2}]/2= (4.23606797749979+0j) degeneracy=1
2\eps+[U-\srqt{16(t^2-\lambda^2)}+U^2]/2= (-0.2360679774997898+0j) degeneracy=1
Expected always real eigenvalues:
2\eps= 1.0 degeneracy=3
2\eps+U= 3.0 degeneracy=1
---------------------
lambda= 2.0 ===>
First two eigenvalues: E0= (2.000000000000008+3.3166247903554043j) E1= (2.000000000000008-3.3166247903554043j)
Always real eigenvalues: E2= (2.999999999999997+0j) E3= (1+0j) E4= (1+0j) E5= (1+0j)
Expected sometimes complex eigenvalues:
2\eps+[U+\srqt{16(t^2-\lambda^2)+U^2}]/2= (2+3.3166247903554j) degeneracy=1
2\eps+[U-\srqt{16(t^2-\lambda^2)}+U^2]/2= (2-3.3166247903554j) degeneracy=1
Expected always real eigenvalues:
2\eps= 1.0 degeneracy=3
2\eps+U= 3.0 degeneracy=1
---------------------
PS:如果我的问题不清楚,或者是否需要重新组织,请告诉我。
发布于 2019-10-03 21:41:49
答案在文档中:https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.linalg.eig.html
我引述如下:
...特征值不一定是有序的。结果数组将是复数类型,除非虚部为零,在这种情况下,它将被转换为实数类型。当a是实数时,得到的特征值将是实数(0虚部)或出现在共轭对中
因此,如果您希望保持顺序,并且您知道特征值的实部相对于参数不断变化,则需要做的是按键对特征向量进行排序,其中键仅由特征值的实部给定:
vals, eigs = np.linalg.eig(H);
eigs = eigs[ np.argsort( np.real(vals) ) ]
应该能行得通。
https://stackoverflow.com/questions/58226715
复制