scipy 复元素矩阵对角化后的重构

hivapdat  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(80)

我有一个随机矩阵Htest,它有复数元素,我用scipy.linalg.eig对角化了它。有了分解的矩阵,我试图重建原始矩阵。这是我的剧本

import numpy as np
    import scipy as sp
    import random
    
    L0=4
    Htest= np.array([[random.random()+1j*random.random() for e in range(L0)] for e in range(L0)])
    
    # calculate spin energy levels
    E, Vl, Vr=sp.linalg.eig(Htest,left=True)#
    E=np.array(E)
    Vl=np.array(Vl)
    Vr=np.array(Vr)
    idx = E.argsort()[::1]#sort with smallest eigenvalues
    Es = E[idx]
    Vrs = Vr[:,idx]
    Vls = Vl[:,idx]
    
    # This should be a null matrix, but it is not!
    print(np.round( (Htest)-  Vls.T.conj() @ np.diag(Es) @Vrs ,3))
    
    #This works
    for i in  range(L0):
        print(np.round( np.dot(Htest  , Vrs[:,i] )- Es[i] * Vrs[:,i] ,3))
        print(np.round( np.dot(Htest.conj().T, Vls[:,i] )- Es[i].conj() * Vls[:,i],3))

字符串
你有什么建议可以解决这个问题吗?

tcbh2hod

tcbh2hod1#

使用np.random.rand制作(4,4)复杂数组。

In [85]: Htest = np.random.rand(L0,L0)+np.random.rand(L0,L0)*1j

字符串
分解:

In [86]: E, Vl, Vr=linalg.eig(Htest,left=True)
In [87]: E.shape, Vl.shape, Vr.shape
Out[87]: ((4,), (4, 4), (4, 4))


输出已经是数组。测试不分类。

In [88]: np.allclose(Htest@Vr, E*Vr)
Out[88]: True
In [89]: np.allclose(Htest.conj().T@Vl, E.conj() * Vl)
Out[89]: True


使用`svd:

In [127]: U, s, Vh = linalg.svd(Htest)
In [130]: np.allclose(Htest, U@np.diag(s)@Vh)
Out[130]: True


我不记得足够的linalg来纠正这一点(尚未)

In [137]: np.allclose(Htest, Vl.T.conj() @ np.diag(E) @Vr)
Out[137]: False


使用diag的替代方法:

In [152]: np.allclose(E[:,None]*Vl, np.diag(E)@Vl)
Out[152]: True


我不知道这是否有用。
关于从特征值和特征向量重新创建矩阵的一般网络搜索会出现一些StackExchange问题,一些SO,一些数学。这似乎是有限制的(对称?)。您可能需要提供数学参考。

编辑

In [173]: np.allclose(Htest, Vr@np.diag(E)@np.linalg.inv(Vr))
Out[173]: True

In [176]: np.allclose(Htest, Vr@(E[:,None]*np.linalg.inv(Vr)))
Out[176]: True


从早期的测试:

Htest@Vr == E*Vr
Htest@Vr == Vr*E
Htest@Vr == Vr@diag(E)
Htest@Vr@inv(Vr) == Vr@diag(E)@inv(Vr)
Htest == Vr@diag(E)@inv(Vr)


对于Vl,也是同样的逻辑:

In [201]: np.allclose(Htest.conj().T, (Vl*E.conj())@np.linalg.inv(Vl))
Out[201]: True
In [203]: np.allclose(Htest.conj().T, Vl@np.diag(E.conj())@np.linalg.inv(Vl))
Out[203]: True

相关问题