2

複素数値のエルミート行列の最小の固有値と固有ベクトルを探します。実数値のエルミート行列の場合、次のコードは完全に機能します。

import numpy as np
import numpy.linalg as la
import copy as cp

#Generates the representation in Krylov subspace of a Hermitian NxN matrix using the Lanczos algorithm and an initial vector guess vg.
def Lanczos(H,vg):
    Lv=np.zeros((len(vg),len(vg)), dtype=complex) #Creates matrix for Lanczos vectors
    Hk=np.zeros((len(vg),len(vg)), dtype=complex) #Creates matrix for the Hamiltonian in Krylov subspace
    Lv[0]=vg/la.norm(vg) #Creates the first Lanczos vector as the normalized guess vector vg
     
    #Performs the first iteration step of the Lanczos algorithm
    w=np.dot(H,Lv[0]) 
    a=np.dot(np.conj(w),Lv[0])
    w=w-a*Lv[0]
    Hk[0,0]=a
     
    #Performs the iterative steps of the Lanczos algorithm
    for j in range(1,len(vg)):
        b=(np.dot(np.conj(w),np.transpose(w)))**0.5
        Lv[j]=w/b
         
        w=np.dot(H,Lv[j])
        a=np.dot(np.conj(w),Lv[j])
        w=w-a*Lv[j]-b*Lv[j-1]
        
        #Creates tridiagonal matrix Hk using a and b values
        Hk[j,j]=a
        Hk[j-1,j]=b
        Hk[j,j-1]=np.conj(b)
        
    return (Hk,Lv)

しかし、複素数の場合、出力固有ベクトルは同じではありません (固有値は同じですが!):

H = np.random.rand(8,8) + np.random.rand(8,8)*1j #Generates random complex-valued 8x8 matrix
H = H + H.conj().T #Ensures 8x8 matrix is symmetric (hermitian)
Hc = cp.copy(H)
a,b = np.linalg.eig(H) #Directly computes eigenvalues of H
vg = np.random.rand(8) + np.random.rand(8)*1j #Generates random guess vector
Hk,Lv = Lanczos(Hc,vg) #Applies the Lanczos algorithm to H using the guess vector vg
A,B= np.linalg.eig(Hk)

#While the following outputs are the same
a[0]
A[0]
#The following are not!!!
b[:,0]
np.dot(B[:,0],Lv)

私が間違っていることは何ですか?ありがとうございました。

- - 解決 - -

それを指摘するためにアキュムレーションに叫びますが、固有値チェックがもたらすので、この手順には何も問題がないようです:

a[0]*b[:,0] - np.dot(H,b[:,0])
array([ 3.55271368e-15+1.11022302e-15j,  4.44089210e-16-3.65257395e-16j,
        0.00000000e+00+9.99200722e-16j, -4.44089210e-16+3.33066907e-16j,
       -2.22044605e-15-1.66533454e-16j,  1.33226763e-15+0.00000000e+00j,
        2.66453526e-15+1.22124533e-15j,  3.10862447e-15+1.22124533e-15j])
A[0]*np.dot(B[:,0],Lv) - np.dot(H,)
array([2.22044605e-15+1.77635684e-15j, 2.66453526e-15+1.55431223e-15j,
       2.66453526e-15+1.55431223e-15j, 2.66453526e-15+1.77635684e-15j,
       3.55271368e-15+2.66453526e-15j, 1.77635684e-15+1.99840144e-15j,
       1.33226763e-15+1.77635684e-15j, 8.88178420e-16+1.55431223e-15j])

b[:,0] と np.dot(B[:,0],Lv) の両方がエルミート行列 H の固有ベクトルであることを意味します。

4

2 に答える 2