病态矩阵的矩阵逆元素

时间:2019-10-07 14:16:46

标签: python scipy eigenvector

我试图找到病态矩阵的矩阵逆元素

考虑复数非赫米特矩阵M,我知道这个矩阵有一个零本征值,因此是奇异的。但是,我需要找到矩阵元素的总和:v@f(M)@u,其中u和v都是向量,并且f(x)= 1 / x(实际上是矩阵逆)。我知道第零特征值对这个和没有贡献,因此奇点没有明显的问题。但是,我的代码在数值上非常不稳定,我认为这是查找系统特征值时出错的结果。

从构建初步矩阵开始:

import numpy as np
import scipy as sc

g0 = np.array([0,0,1])
g1 = np.array([0,1,0])
e0 = np.array([1,0,0])

sm = np.outer(g0, e0)
sp = np.outer(e0, g0)



def spre(op):
    return np.kron(np.eye(op.shape[0]),op)

def spost(op):
    return np.kron(op.T,np.eye(op.shape[0]))

def sprepost(op1,op2):
    return np.kron(op1.T,op2)

sm_reg = spre(sm)
sp_reg = spre(sp)

spsm_reg=spre(sp@sm)

hil_dim = int(g0.shape[0])
cav_proj= np.eye(hil_dim).reshape(hil_dim**2,)

rho0 =(np.outer(e0,e0)).reshape(hil_dim**2,)




def ham(g):
    return g * (np.outer(g1,e0) + np.outer(e0, g1))


def lind_op(A):
    L = 2 * sprepost(A,A.conj().T) - spre(A.conj().T @ A)
    L += - spost(A.conj().T @ A)
    return L



def JC_lio(g, kappa, gamma):
    unit = -1j * (spre(ham(g)) - spost(ham(g)))
    lind = gamma * lind_op(np.outer(g0 , e0)) + kappa * lind_op(np.outer(g0 , g1))
    return unit + lind

现在定义一个函数,该函数首先找到左右特征值,然后找到矩阵元素的总和:

def power_int(g, kappa, gamma):

    # Construct the non-Hermitian matrix of interest
    lio = JC_lio(g,kappa,gamma)

    #Find its left and right eigenvectors:
    ev, left, right = scipy.linalg.eig(lio, left=True,right=True)

    # Find the appropriate normalisation factors
    norm = np.array([(left.conj().T[ii]).dot(right.conj().T[ii]) for ii in range(len(ev))])

    #Find the similarity transformation for the problem
    P = right
    Pinv = (left/norm).conj().T


    #find the projectors for the Eigenbasis
    Proj = [np.outer(P.conj().T[ii],Pinv[ii]) for ii in range(len(ev))]


    #Find the relevant matrix elements between the Eigenbasis and the projectors --- this is where the zero eigenvector gets removed
    PowList = [(spsm_reg@ Proj[ii] @ rho0).dot(cav_proj) for ii in range(len(ev))]

    #apply the function
    Pow = 0

    for ii in range(len(ev)):
        if PowList[ii]==0:
            Pow = Pow
        else:
            Pow += PowList[ii]/ev[ii]


    return -np.pi * np.real(Pow)


#example run:

grange = np.linspace(0.001,10,40)

dat = np.array([power_int(g, 1, 1) for g in grange])

运行此代码会导致极度震荡的结果,在此情况下,我希望曲线平滑。我怀疑此错误是由于确定本征向量的准确性较差而引起的,但我似乎找不到任何相关文档。任何见解都将受到欢迎。

0 个答案:

没有答案