unit矩阵的数值对角化

时间:2019-01-29 21:59:50

标签: matrix lapack eigenvector

要在数字上对角化 unit矩阵,我使用LAPACK例程zgeev

问题是:在简并的情况下,简并的子空间未进行正交归一化,因为该例程适用于一般矩阵。

但是,由于在我的情况下,矩阵是一元的,因此基础可以始终进行正交归一化。是否有比将QR算法应用于退化子空间更好的解决方案?

1 个答案:

答案 0 :(得分:2)

简短答案: Schur decomposition

如果方阵A是复数,则其Schur因式分解为 A=ZTZ* ,其中Z为unit,T为上三角。 如果A恰好是单一的,则T也必须是单一的。由于T是既酉和三角形的,它是对角(proof here,or there) 让我们考虑向量Z.e_i,其中e_i是规范基础的向量。这些向量显然构成了正交基础。此外,这些载体是矩阵的本征向量A因此,the矩阵Z的列是the矩阵A的特征向量,并形成正交标准。

因此,计算a矩阵的Schur分解等同于找到其特征向量的正交基础之一。

ZGEESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices

生成的T也可以进行测试,以检查A是单一的。

尽管scipy的scipy.linalg.schur使用Lapack的zgees进行Schur分解,但这是一段测试它的python代码。我用hpaulj的代码来生成随机酉矩阵如图How to create random orthonormal matrix in python numpy

import numpy as np
import scipy.linalg

#from hpaulj, https://stackoverflow.com/questions/38426349/how-to-create-random-orthonormal-matrix-in-python-numpy
def rvs(dim=3):
     random_state = np.random
     H = np.eye(dim)
     D = np.ones((dim,))
     for n in range(1, dim):
         x = random_state.normal(size=(dim-n+1,))
         D[n-1] = np.sign(x[0])
         x[0] -= D[n-1]*np.sqrt((x*x).sum())
         # Householder transformation
         Hx = (np.eye(dim-n+1) - 2.*np.outer(x, x)/(x*x).sum())
         mat = np.eye(dim)
         mat[n-1:, n-1:] = Hx
         H = np.dot(H, mat)
         # Fix the last sign such that the determinant is 1
     D[-1] = (-1)**(1-(dim % 2))*D.prod()
     # Equivalent to np.dot(np.diag(D), H) but faster, apparently
     H = (D*H.T).T
     return H

n=42
A= rvs(n)
A = A.astype(complex)
T,Z=scipy.linalg.schur(A,output='complex',lwork=None,overwrite_a=False,sort=None,check_finite=True)

#print T
normT=np.linalg.norm(T,ord=None) #2-norm
eigenvalues=[]
for i in range(n):
    eigenvalues.append(T[i,i])
    T[i,i]=0.
normTu=np.linalg.norm(T,ord=None)
print 'must be very low if A is unitary: ',normTu/normT

#print Z
for i in range(n):
    v=Z[:,i]
    w=A.dot(v)-eigenvalues[i]*v
    print i,'must be very low if column i of Z is eigenvector of A: ',np.linalg.norm(w,ord=None)/np.linalg.norm(v,ord=None)