Scipy的稀疏Eigs产生错误的特征向量

时间:2019-03-01 18:21:43

标签: python scipy lanczos

我对以下问题感到困惑:

我正在计算量子通道的固定点,这意味着我想计算特定矩阵的前导特征向量。矩阵的维数为n ^ 2 x n ^ 2,并且以这样的方式定义矩阵:将主导特征值重塑为形状为n x n的矩阵是一个正矩阵(具有正特征值的自伴)。

如果我使用scipy.sparse.linalg.eigs进行此操作,但是得到错误的结果。精确的计算(使用scipy.linalg.eig)可以正常工作。我尝试使用求解器的kncv的参数,但是除非我设置了k=n**2,否则我无法正常工作,在这种情况下,eigs只是指eig。但是,在我确实要记住该通道(以下脚本中的super_op实际上被编码为LinearOperator)的情况下,这是行不通的。所以我依靠使用eigs:/

有人知道如何使其正常运行吗?

谢谢大家!

import numpy as np
from numpy.random import rand
from numpy import tensordot as td
from scipy.sparse.linalg import eigs
from scipy.linalg import eig


n = 16
d = 3

kraus_op = .5 - rand(n, d, n) + 1j * (.5 - rand(n, d, n))
super_op = td(kraus_op, kraus_op.conj(), [[1], [1]]).transpose(0, 2, 1, 3)

########
# Sparse
########

vals, vecs = eigs(super_op.reshape(n**2, n**2), k=n*(n-1), which='LM')

rho = vecs[:,0].reshape(n, n)

print('is self adjoint: ', np.allclose(rho, rho.conj().T))

super_op_times_rho = td(super_op, rho, [[2, 3], [0, 1]])

print('super_op(rho) == lambda * rho :', np.allclose(rho, super_op_times_rho/vals[0]))

########
# Exact
########

vals, vecs = eig(super_op.reshape(n**2, n**2))

rho = vecs[:,0].reshape(n, n)

print('is self adjoint: ', np.allclose(rho, rho.conj().T))

super_op_times_rho = td(super_op, rho, [[2, 3], [0, 1]])

print('super_op(rho) == lambda * rho :', np.allclose(rho, super_op_times_rho/vals[0]))

结果是:

is self adjoint:  False
super_op(rho) == lambda * rho : True
is self adjoint:  True
super_op(rho) == lambda * rho : True

出于完整性考虑:

Python 3.5.2 numpy 1.16.1
scipy 1.2.1

1 个答案:

答案 0 :(得分:0)

毕竟,在同事的帮助下,我找到了解决方案:

尽管eig给出了特征向量(1)(按幅度)和(2)进行排序,使得第一个条目是实数,而eigs的排序则必须与{{1} },并且也没有规范化特征向量的复数相位。通过将张量除以第一个入口的相位即可轻松地完成相位校正(对应于确保第一个对角元素是实数,从而摆脱了选择特征向量的复数相位的自由度并使隐性成为可能的...) 。

因此,稀疏情况的更正代码段为:

eig