eig
时,您NEVER想要使用eigh
-eig
非常慢且非常不稳定。与此相关的是,我认为您的问题是后退的-您想将eig
的特征向量归一化为eigh
的特征向量,并且您知道该怎么做。
我知道,特征向量仅定义为一个乘法常数。据我所知,所有numpy
算法(例如linalg.eig
,linalg.eigh
,linalg.svd
)对于实矩阵产生相同的特征向量,因此显然它们使用相同的归一化。但是,在复杂矩阵的情况下,算法会得出不同的结果。
即,特征向量直到(复数)常数z
都是相同的。在对eig
和eigh
进行了一些实验之后,我意识到eigh
总是将每个本征向量的第一个分量的相位角(定义为arctan(复数部分/实数部分))设置为0,而eig
似乎开始具有一些(任意?)非零相位角。
Q:是否有一种方法可以按照eigh
的方式归一化eig
的特征向量(即不强制相位角= 0?]]]
我有一个复杂的厄米矩阵G
,我想使用以下两种算法来计算特征向量:
numpy.linalg.eig
用于实数/ 复方矩阵numpy.linalg.eigh
表示实对称/ 复厄密矩阵](特殊情况为1)# check if a matrix is hermitian
def isHermitian(a, rtol=1e-05, atol=1e-08):
return np.allclose(a, a.conjugate().T, rtol=rtol, atol=atol)
print('G is hermitian:', isHermitian(G))
输出:
G is hermitian: True
# eigenvectors from EIG()
l1,u1 = np.linalg.eig(G)
idx = np.argsort(l1)[::-1]
l1,u1 = l1[idx].real,u1[:,idx]
# eigenvectors from EIGH()
l2,u2 = np.linalg.eigh(G)
idx = np.argsort(l2)[::-1]
l2,u2 = l2[idx],u2[:,idx]
print('Eigenvalues')
print('eig\t:',l1[:3])
print('eigh\t:',l2[:3])
输出:
Eigenvalues
eig : [2.55621629e+03 3.48520440e+00 3.16452447e-02]
eigh : [2.55621629e+03 3.48520440e+00 3.16452447e-02]
两种方法都产生相同的特征向量。
现在查看特征向量(例如3.特征向量),它们相差一个常数因子z
。
multFactors = u1[:,2]/u2[:,2] if np.count_nonzero(multFactors[0] == multFactors): print("All multiplication factors are same:", multFactors[0]) else: print("Multiplication factors are different.")
输出:
All multiplication factors are same: (-0.8916113627685007+0.45280147727156245j)
检查相角
现在检查3.特征向量的第一个分量的相角:
print('Phase angel (in PI) for first point:') print('Eig\t:',np.arctan2(u1[0,2].imag,u1[0,2].real)/np.pi) print('Eigh\t:',np.arctan2(u2[0,2].imag,u2[0,2].real)/np.pi)
输出:
复制图形的代码Phase angel (in PI) for first point: Eig : 0.8504246311627189 Eigh : 0.0
num = 2 fig = plt.figure() gs = gridspec.GridSpec(2, 3) ax0 = plt.subplot(gs[0,0]) ax1 = plt.subplot(gs[1,0]) ax2 = plt.subplot(gs[0,1:]) ax3 = plt.subplot(gs[1,1:]) ax2r= ax2.twinx() ax3r= ax3.twinx() ax0.imshow(G.real,vmin=-30,vmax=30,cmap='RdGy') ax1.imshow(G.imag,vmin=-30,vmax=30,cmap='RdGy') ax2.plot(u1[:,num].real,label='eig') ax2.plot((u2[:,num]).real,label='eigh') ax3.plot(u1[:,num].imag,label='eig') ax3.plot((u2[:,num]).imag,label='eigh') for a in [ax0,ax1,ax2,ax3]: a.set_xticks([]) a.set_yticks([]) ax0.set_title('Re(G)') ax1.set_title('Im(G)') ax2.set_title('Re('+str(num+1)+'. Eigenvector)') ax3.set_title('Im('+str(num+1)+'. Eigenvector)') ax2.legend(loc=0) ax3.legend(loc=0) fig.subplots_adjust(wspace=0, hspace=.2,top=.9) fig.suptitle('Eigenanalysis of Hermitian Matrix G',size=16) plt.show()
我知道,特征向量仅定义为一个乘法常数。据我所见,所有的numpy算法(例如linalg.eig,linalg.eigh,linalg.svd)对于真实的... ...>根据我的经验(这里有很多问题可以证明这一点),当您选择eig
时,您NEVER想要使用
eigh
-eig
非常慢且非常不稳定。与此相关的是,我认为您的问题是后退的-您想将eig
的特征向量归一化为eigh
的特征向量,并且您知道该怎么做。
eig
时,您NEVER想要使用eigh
-eig
非常慢且非常不稳定。与此相关的是,我认为您的问题是后退的-您想将eig
的特征向量归一化为eigh
的特征向量,并且您知道该怎么做。