Python专题, 语言

np.linalg.eig和np.linalg.eigh的区别

np.linalg.eig文档:https://numpy.org/doc/stable/reference/generated/numpy.linalg.eig.html

np.linalg.eigh文档:https://numpy.org/doc/stable/reference/generated/numpy.linalg.eigh.html

1. np.linalg.eig

Compute the eigenvalues and right eigenvectors of a square array

特点:

(1)可以计算任意矩阵的特征值和特征向量。

(2)特征值没有按大小排序,需自行根据实部排序。

(3)对于相同特征值的情况,得到的特征向量可能相互正交,也可能不相互正交。

2. np.linalg.eigh

Return the eigenvalues and eigenvectors of a complex Hermitian (conjugate symmetric) or a real symmetric matrix.

特点:

(1)计算厄密矩阵或实对称矩阵的特征值和特征向量,即特征值一定为实数。

(2)特征值已按大小排序,从小到大。

(3)对于相同特征值的情况,得到的特征向量相互正交。

3. 结论

在已知是厄密矩阵(包括实对称矩阵)的情况下,最好使用 np.linalg.eigh,可以避免相同特征值对应的特征向量不正交的情况,同时特征值也经过了排序。

4. 代码测试

"""
This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/17789
"""

import numpy as np

def hamiltonian(width=2, length=2):
    h00 = np.zeros((width*length, width*length))
    for i0 in range(length):
        for j0 in range(width-1):
            h00[i0*width+j0, i0*width+j0+1] = 1
            h00[i0*width+j0+1, i0*width+j0] = 1
    for i0 in range(length-1):
        for j0 in range(width):
            h00[i0*width+j0, (i0+1)*width+j0] = 1
            h00[(i0+1)*width+j0, i0*width+j0] = 1
    return h00

print('矩阵:\n', hamiltonian(), '\n')

eigenvalue, eigenvector = np.linalg.eig(hamiltonian())
print('eig求解特征值:', eigenvalue)
print('eig求解特征向量:\n',eigenvector)
print('判断特征向量是否正交:\n', np.dot(eigenvector.transpose(), eigenvector))

print()

eigenvalue, eigenvector = np.linalg.eigh(hamiltonian())
print('eigh求解特征值:', eigenvalue)
print('eigh求解特征向量:\n',eigenvector)
print('判断特征向量是否正交:\n', np.dot(eigenvector.transpose(), eigenvector))

计算结果:

矩阵:
 [[0. 1. 1. 0.]
 [1. 0. 0. 1.]
 [1. 0. 0. 1.]
 [0. 1. 1. 0.]]

eig求解特征值: [-2.00000000e+00+0.00000000e+00j  2.00000000e+00+0.00000000e+00j
 -1.72210111e-33+3.25817663e-25j -1.72210111e-33-3.25817663e-25j]
eig求解特征向量:
 [[ 5.00000000e-01+0.00000000e+00j -5.00000000e-01+0.00000000e+00j
  -3.62985589e-17+6.86760585e-09j -3.62985589e-17-6.86760585e-09j]
 [-5.00000000e-01+0.00000000e+00j -5.00000000e-01+0.00000000e+00j
  -7.07106781e-01-2.42600790e-40j -7.07106781e-01+2.42600790e-40j]
 [-5.00000000e-01+0.00000000e+00j -5.00000000e-01+0.00000000e+00j
   7.07106781e-01+0.00000000e+00j  7.07106781e-01-0.00000000e+00j]
 [ 5.00000000e-01+0.00000000e+00j -5.00000000e-01+0.00000000e+00j
   3.62985589e-17-6.86760585e-09j  3.62985589e-17+6.86760585e-09j]]
判断特征向量是否正交:
 [[ 1.00000000e+00+0.00000000e+00j  1.66533454e-16+0.00000000e+00j
  -1.15866495e-16-7.62457413e-25j -1.15866495e-16+7.62457413e-25j]
 [ 1.66533454e-16+0.00000000e+00j  1.00000000e+00+0.00000000e+00j
  -2.30669677e-16+4.13590306e-25j -2.30669677e-16-4.13590306e-25j]
 [-1.15866495e-16-7.62457413e-25j -2.30669677e-16+4.13590306e-25j
   1.00000000e+00-9.97136782e-25j  1.00000000e+00+0.00000000e+00j]
 [-1.15866495e-16+7.62457413e-25j -2.30669677e-16-4.13590306e-25j
   1.00000000e+00+0.00000000e+00j  1.00000000e+00+9.97136782e-25j]]

eigh求解特征值: [-2.00000000e+00 -1.11310287e-16  3.33354892e-16  2.00000000e+00]
eigh求解特征向量:
 [[-0.5         0.05367498  0.70506666 -0.5       ]
 [ 0.5         0.70506666 -0.05367498 -0.5       ]
 [ 0.5        -0.70506666  0.05367498 -0.5       ]
 [-0.5        -0.05367498 -0.70506666 -0.5       ]]
判断特征向量是否正交:
 [[ 1.00000000e+00 -5.55111512e-17  1.11022302e-16  4.16333634e-16]
 [-5.55111512e-17  1.00000000e+00 -5.66593128e-17  1.11022302e-16]
 [ 1.11022302e-16 -5.66593128e-17  1.00000000e+00 -1.11022302e-16]
 [ 4.16333634e-16  1.11022302e-16 -1.11022302e-16  1.00000000e+00]]

由以上结果可以看出:

  • 用 eig 求解时,特征值没有排序。
  • 用 eig 求解时,特征向量没有正交。
  • 特征向量的结果仅供参考,在有的 numpy 版本中在 eig 后会得到相互正交的结果,而在有的版本中会得到不相互正交的结果,这可能是官方那边在 eig 的底层算法在不同版本中做了调整,但计算结果在数学上都是正确的。
4,460 次浏览

【说明:本站主要是个人的一些笔记和代码分享,内容可能会不定期修改。为了使全网显示的始终是最新版本,这里的文章未经同意请勿转载。引用请注明出处:https://www.guanjihuan.com

3 thoughts on “np.linalg.eig和np.linalg.eigh的区别”

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

Captcha Code