python - 如何消除 NumPy 特征向量分量的复杂角度的不连续性?

标签 python numpy complex-numbers eigenvector phase

我在方阵上使用 NumPy 的 linalg.eig 。我的方阵是二维域的函数,我正在沿着该域上的参数化圆查看其特征向量的复角。只要我考虑的路径是平滑的,我就期望每个特征向量分量的复角是平滑的。然而,在某些情况下,Python 的情况并非如此(尽管其他编程语言也是如此)。对于参数 M=0 (矩阵中出现在对角线上的一些参数),我的组件如下所示:

enter image description here enter image description here

理想情况下它们应该看起来像(M=0.1):

enter image description here enter image description here

我尝试过的:

  • 我验证了这两种情况下的矩阵都是 Hermitian 矩阵。
  • 当我使用 linalg.eigh 时,M=0.1 变得不连续,而 M=0 有时会变得连续。
  • 使用 np.unwrap 没有执行任何操作。
  • 分量相位之间的差异(即特征向量v=[[v1],[v2]]np.angle(v1-v2))是平滑/连续的,但这不是我想要的。
  • 在求解之前修复 NumPy 种子对于种子的不同值没有任何作用。例如:np.random.seed(1)

我还能做什么?我尝试使用 Sympy 的 eigenvects 只是因为我没有选择,并且我在这里提出了另一个问题,询问另一种潜在的方法:How do I force first component of NumPy eigenvectors to be real? 。但是,我不知道还能尝试什么。

这是一个在 Jupyter 笔记本中运行良好的最小工作示例:

import numpy as np
from numpy import linalg as LA
import matplotlib.pyplot as plt

M = 0.01; # nonzero M is okay
M = 0.0; # M=0 causes problems

def matrix_generator(kx,ky,M):
    a = 2.46;    t = 1;    k = np.array((kx,ky));
    d1 = (a/2)*np.array((1,np.sqrt(3)));d2 = (a/2)*np.array((1,-np.sqrt(3)));d3 = -a*np.array((1,0));
    sx = np.matrix([[0,1],[1,0]]);sy = np.matrix([[0,-1j],[1j,0]]);sz = np.matrix([[1,0],[0,-1]]);
    hx = np.cos(k@d1)+np.cos(k@d2)+np.cos(k@d3);hy = np.sin(k@d1)+np.sin(k@d2)+np.sin(k@d3);
    return -t*(hx*sx - hy*sy + M*sz)

n_segs = 200; #number of segments in (kx,ky) loop
evecs_along_loop = np.zeros((n_segs,2,2),dtype=float)
# parameterize circular loop
kx0 = 0.5; ky0 = 1; r1=0.2; r2=0.2; 
a = np.linspace(0.0, 2*np.pi, num=n_segs+2)
kloop=np.zeros((n_segs+2,2))
for i in range(n_segs+2):
    kloop[i,:]=np.array([kx0 + r1*np.cos(a[i]), ky0 + r2*np.sin(a[i])]) 
    
# assign eigenvector complex angles
for j in np.arange(n_segs):
    np.random.seed(2)
    H = matrix_generator(kloop[j][0],kloop[j][1],M)
    eval0, psi0 = LA.eig(H)
    evecs_along_loop[j,:,:] = np.angle(psi0)
    
# plot eigenvector complex angles
for p in np.arange(2):
    for q in np.arange(2):
        print(f"Phase for eigenvector element {p},{q}:")
        fig = plt.figure()
        ax = plt.axes()
        ax.plot((evecs_along_loop[:,p,q]))
        plt.show()

对 anon01 评论的澄清: enter image description here 对于 M=0,某个值为 (kx,ky) 的样本矩阵将如下所示:

a = np.matrix([[0.+0.j, 0.99286437+1.03026667j],
 [0.99286437-1.03026667j, 0.+0.j]])

对于M == 0,对角线将非零(但为实数)。

最佳答案

我认为总的来说这是一个棘手的问题。根本问题是特征向量(与特征值不同)没有明确定义。具有特征值 c 的 M 的特征向量 v 是任意非零向量,其中

M*v = c*v

特别是对于任何非零标量 s,将特征向量乘以 s 会产生特征向量,即使您(像往常一样)要求特征向量的长度为 1,我们仍然可以自由地乘以绝对值为 1 的任何标量。更糟糕的是,如果 v1,..vd 是 c 的正交特征向量,则 v 的任何非零线性组合也是 c 的特征向量。

因此,不同的特征分解例程很可能会得出非常不同的特征向量,但仍然在完成它们的工作。此外,某些例程可能会为靠近的矩阵生成相距较远的特征向量。

一个简单易处理的情况是,您知道所有特征值都是非简并的(即每个特征空间的维度为 1),并且您碰巧知道对于特定的 i,每个特征向量的第 i 个分量将是非退化的零。然后,您可以将特征向量 v 乘以绝对值为 1 的标量,选择该标量以便相乘后 v[i] 为正实数。在C中

s = conj(v[i])/cabs(v[i])
where 
conj(z) is the complex conjugate of the complex number z, 
and cabs(z) is the absolute value of the complex number z

请注意,上面假设我们对每个特征向量使用相同的索引,尽管因子 s 因特征向量而异。

这会给特征向量带来一种唯一性,并且人们希望这意味着它们会随着矩阵的参数而不断变化。

关于python - 如何消除 NumPy 特征向量分量的复杂角度的不连续性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67640569/

相关文章:

python - 如何将 boolean 掩码存储为 Cython 类的属性?

python - 索引错误: index is out of bounds for axis 0 with size

c - 如何在 C 中实现复杂的算术运算符?

matlab - Matlab复数矩阵的两种输入方式有什么区别

java - 在 Java 中将 double 转换为 BigDecimal

python - LaunchDaemon 处理系统关闭 - 没有 SIGTERM?

python - CNTK "times"函数究竟是如何工作的?

python - urls.py 中的 Django EOL

python - 使用这种日期格式对列表进行反向排序的最佳方法是什么?

python - 将 bool 值映射到字符串