上一章: 态矢量
下一章: Choi
简介
量子通道的算子和 Kraus 表示。
对于一个量子通道
\[ \mathcal{E}(\rho)=\sum_{i=0}^{K-1} A_{i} \rho A_{i}^{\dagger}
\]
Kraus 表示由一组矩阵
\[ \left[A_{0}, \ldots, A_{K-1}\right]
\]
给出,使得密度矩阵 \( \rho\) 的演化由下式表示:
\[\mathcal{E}(\rho)=\sum_{i=0}^{K-1} A_{i} \rho A_{i}^{\dagger}
\]
一个广义算子映射 \(\mathcal{G}\) 也可以使用广义 Kraus 表示,该表示由两组矩阵
\(\left[A_{0}, \ldots, A_{K-1}\right]
\) , \(\left[B_{0}, \ldots, B_{B-1}\right]
\)
给出,使得
\[ \mathcal{G}(\rho)=\sum_{i=0}^{K-1} A_{i} \rho B_{i}^{\dagger}
\]
请参考:C.J. Wood, J.D. Biamonte, D.G. Cory, Tensor networks and graphical calculus for open quantum systems, Quant. Inf. Comp. 15, 0579-0811 (2015).arXiv:1111.6950 [quant-ph]
在 QPanda3 量子信息模块中
构造 Kraus 对象
API文档链接
默认构造函数
生成一个不包含元素的 Kraus 对象。
Python
Kra1 = Kraus()
print("Kra1:", Kra1)
输出:
Kra1: [Kraus:
[Kraus_left:
]
[Kraus_right:
]
]
使用二维矩阵数组构造
从算子列表的二维矩阵数组构造 Kraus 对象。
生成的 Kraus 对象的左算子列表由输入矩阵数组构造,右算子列表为空。
Python
import numpy as np
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Kra2 = Kraus(Ks1)
print("Kra2:", Kra2)
输出:
Kra2: [Kraus:
[Kraus_left:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
]
[Kraus_right:
]
]
从两个算子列表构造
从包含两个算子列表的二维矩阵数组构造 Kraus 对象。
生成的 Kraus 对象的左算子列表由第一个输入数组构造。
生成的 Kraus 对象的右算子列表由第二个输入数组构造。
Python
import numpy as np
def test_construct():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
print("Kra3:", Kra3)
if __name__ == "__main__":
test_construct()
输出:
Kra3: [Kraus:
[Kraus_left:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
]
[Kraus_right:
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
]
从二维矩阵构造
从算子的二维矩阵构造 Kraus 对象。
生成的 Kraus 对象的左算子列表由输入矩阵构造,右算子列表为空。
Python
import numpy as np
def test_construct():
K0 = np.array([[0, 1], [1+0.j, 0]])
Kra4 = Kraus(K0)
print("Kra4:", Kra4)
if __name__ == "__main__":
test_construct()
输出:
Kra4: [Kraus:
[Kraus_left:
[ [0+0j ]
[1+0j ]
]
[ [1+0j ]
[0+0j ]
]
]
[Kraus_right:
]
]
从 Kraus 构造
从一个 Kraus 对象生成另一个 Kraus 对象。
Python
import numpy as np
def test_construct():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
Kra5 = Kra3
print("Kra5:", Kra5)
if __name__ == "__main__":
test_construct()
输出:
Kra5: [Kraus:
[Kraus_left:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
]
[Kraus_right:
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
]
Python
import numpy as np
def test_construct():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
Kra5 = Kraus(Kra3)
print("Kra5:", Kra5)
if __name__ == "__main__":
test_construct()
输出:
Kra5: [Kraus:
[Kraus_left:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
]
[Kraus_right:
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
]
从 Choi 构造
从 Choi 对象生成另一个 Kraus 对象。
请参考 Choi
Python
import numpy as np
def test_construct_from_choi():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
choi = Choi(Kra3)
Kra4= Kraus(choi)
print("Kra4:",Kra4)
if __name__ == "__main__":
test_construct_from_choi()
输出:
Kra4: [Kraus:
[Kraus_left:
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1.4142135623731+0j]
[0+0j 0+0j]
]
[ [0+0j 0+0j]
[1.4142135623731+0j 0+0j]
]
]
[Kraus_right:
]
]
从 Chi 构造
从 Chi 对象生成另一个 Kraus 对象。
请参考 Chi
Python
import numpy as np
def test_construct_from_chi():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
chi = Chi(Kra3)
Kra4= Kraus(chi)
print("Kra4:",Kra4)
if __name__ == "__main__":
test_construct_from_chi()
输出:
Kra4: [Kraus:
[Kraus_left:
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1.4142135623731+0j]
[0+0j 0+0j]
]
[ [0+0j 0+0j]
[1.4142135623731+0j 0+0j]
]
]
[Kraus_right:
]
]
从 SuperOp 构造
从 SuperOp 对象生成另一个 Kraus 对象。
请参考 SuperOp
Python
import numpy as np
def test_construct_from_superop():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
sop = SuperOp(Kra3)
Kra4= Kraus(sop)
print("Kra4:",Kra4)
if __name__ == "__main__":
test_construct_from_superop()
输出:
Kra4: [Kraus:
[Kraus_left:
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1.4142135623731+0j]
[0+0j 0+0j]
]
[ [0+0j 0+0j]
[1.4142135623731+0j 0+0j]
]
]
[Kraus_right:
]
]
从 PTM 构造
从 PTM 对象生成另一个 Kraus 对象。
请参考 PTM
Python
import numpy as np
def test_construct_from_ptm():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
ptm = PTM(Kra3)
Kra4= Kraus(ptm)
print("Kra4:",Kra4)
if __name__ == "__main__":
test_construct_from_ptm()
输出:
Kra4: [Kraus:
[Kraus_left:
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1.4142135623731+0j]
[0+0j 0+0j]
]
[ [0+0j 0+0j]
[1.4142135623731+0j 0+0j]
]
]
[Kraus_right:
]
]
获取内部数据
输入和输出维度
获取与Kraus对象对应的输入维度 input_dim
和输出维度 output_dim
输出维度应等于算子矩阵的行数。
输入维度应等于算子矩阵的列数。
当前实现要求矩阵必须是方阵,因此输入和输出维度应相等。
Kraus.get_input_dim的API文档链接
Kraus.get_output_dim的API文档链接
Python
import numpy as np
def test_dim():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
print("Kra3:", Kra3)
input_dim = Kra3.get_input_dim()
output_dim = Kra3.get_output_dim()
print("input_dim:",input_dim)
print("output_dim:",output_dim)
if __name__ == "__main__":
test_dim()
输出:
Kra3: [Kraus:
[Kraus_left:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
]
[Kraus_right:
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
]
input_dim: 2
output_dim: 2
左算子列表
获取Kraus对象内部的左算子列表
结果以list[pyqpanda3.quantum_info.Matrix]
的形式返回。
Kraus.left的API文档链接
Python
import numpy as np
def test_left():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
left = Kra3.left()
for v in left:
print(v)
if __name__ == "__main__":
test_left()
输出:
[[0.+0.j 1.+0.j]
[1.+0.j 0.+0.j]]
[[ 1.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j]]
[[ 0.+0.j -0.-1.j]
[ 0.+1.j 0.+0.j]]
右算子列表
获取Kraus对象内部的右算子列表
结果以list[pyqpanda3.quantum_info.Matrix]
的形式返回。
Kraus.right的API文档链接
Python
import numpy as np
def test_right():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
right = Kra3.right()
for v in right:
print(v)
if __name__ == "__main__":
test_right()
输出:
[[ 0.+0.j -0.-1.j]
[ 0.+1.j 0.+0.j]]
[[ 1.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j]]
[[0.+0.j 1.+0.j]
[1.+0.j 0.+0.j]]
修改内部数据
清除内部数据
Kraus.clear的API文档链接
Python
import numpy as np
def test_clear():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
Kra3.clear()
print("Kra3:",Kra3)
if __name__ == "__main__":
test_clear()
输出:
Kra3: [Kraus:
[Kraus_left:
]
[Kraus_right:
]
]
追加Kraus
将另一个Kraus对象的内部数据追加到当前Kraus对象的内部数据末尾
另一个Kraus对象的矩阵应与当前Kraus对象的内部矩阵具有相同的形状
Kraus.append的API文档链接
Python
import numpy as np
def test_append():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
Kra3.append(Kra3)
print("Kra3:",Kra3)
if __name__ == "__main__":
test_append()
输出:
Kra3: [Kraus:
[Kraus_left:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
[ [0+0j 1+0j]
[1+0j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
]
[Kraus_right:
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1+0j]
[1+0j 0+0j]
]
[ [0+0j -0+-1j]
[0+1j 0+0j]
]
[ [1+0j 0+0j]
[0+0j -1+0j]
]
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
]
向左算子列表添加矩阵对象
将矩阵对象中的数据添加到Kraus对象内部左算子列表的末尾
矩阵对象的形状应与当前Kraus对象的内部矩阵形状相同
Kraus.left_push_back的API文档链接
Python
import numpy as np
def test_push_back():
K0 = np.array([[0, 1], [1+0.j, 0]])
Kra3 = Kraus()
Kra3.left_push_back(Matrix(K0))
print("Kra3:",Kra3)
if __name__ == "__main__":
test_push_back()
输出:
Kra3: [Kraus:
[Kraus_left:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
[Kraus_right:
]
]
向右算子列表添加矩阵对象
将矩阵对象中的数据添加到Kraus对象内部右算子列表的末尾
矩阵对象的形状应与当前Kraus对象的内部矩阵形状相同
Kraus.right_push_back的API文档链接
Python
import numpy as np
def test_push_back():
K0 = np.array([[0, 1], [1+0.j, 0]])
Kra3 = Kraus()
Kra3.right_push_back(Matrix(K0))
print("Kra3:",Kra3)
if __name__ == "__main__":
test_push_back()
输出:
Kra3: [Kraus:
[Kraus_left:
]
[Kraus_right:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
]
向左算子列表追加numpy.ndarray
将表示二维数组的numpy.ndarray
对象的数据追加到Kraus对象内部左算子列表的末尾
numpy.ndarray
对象的形状应与当前Kraus对象的内部矩阵形状相同
Kraus.left_push_back的API文档链接
Python
import numpy as np
def test_push_back2():
K0 = np.array([[0, 1], [1+0.j, 0]])
Kra3 = Kraus()
Kra3.left_push_back(K0)
print("Kra3:",Kra3)
if __name__ == "__main__":
test_push_back2()
输出:
Kra3: [Kraus:
[Kraus_left:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
[Kraus_right:
]
]
向右算子列表追加numpy.ndarray
将表示二维数组的numpy.ndarray
对象的数据追加到Kraus对象内部右算子列表的末尾
numpy.ndarray
对象的形状应与当前Kraus对象的内部矩阵形状相同
Kraus.right_push_back的API文档链接
Python
import numpy as np
def test_push_back2():
K0 = np.array([[0, 1], [1+0.j, 0]])
Kra3 = Kraus()
Kra3.right_push_back(K0)
print("Kra3:",Kra3)
if __name__ == "__main__":
test_push_back2()
输出:
Kra3: [Kraus:
[Kraus_left:
]
[Kraus_right:
[ [0+0j 1+0j]
[1+0j 0+0j]
]
]
]
量子态的演化
Kraus.evolve的API文档链接
密度矩阵
对DensityMatrix对象进行演化,演化结果以DensityMatrix对象的形式返回
DensityMatrix对象的维度通过dim()
方法获取,应等于Kraus对象的输入维度
请参阅密度矩阵。
Python
import numpy as np
import math
def test_evolve():
data = np.array(
[[0.69272168 + 0.j, 0.38338527 - 0.17772383j],
[0.38338527 + 0.17772383j, 0.30727832 + 0.j]]
)
dm = DensityMatrix(data)
K0 = np.array([[0, 1 + 0.j], [1, 0]])
K1 = np.array([[0, 0. - 1.j], [0. + 1.j, 0]])
K2 = np.array([[1, 1], [1, -1 + 0.j]]) / math.sqrt(2)
Ks1 = [K0, K1, K2]
Kra3 = Kraus(Ks1)
res = Kra3.evolve(dm)
print("res:", res)
if __name__ == "__main__":
test_evolve()
输出:
res: [[1.49794191+0.j 0.19272168+0.17772383j]
[0.19272168-0.17772383j 1.50205809+0.j ]]
态矢量
对StateVector对象进行演化,演化结果以DensityMatrix对象的形式返回
StateVector对象的维度通过dim()
方法获取,应等于Kraus对象的输入维度
请参阅密度矩阵。
请参阅状态向量。
Python
import numpy as np
import math
def test_evolve():
stv = StateVector()
K0 = np.array([[0, 1+0.j], [1, 0]])
K1 = np.array([[0, 0.-1.j], [0.+1.j, 0]])
K2 = np.array([[1, 1], [1, -1+0.j]])/math.sqrt(2)
Ks1 = [K0, K1, K2]
Kra3 = Kraus(Ks1)
res = Kra3.evolve(stv)
print("res:",res)
if __name__ == "__main__":
test_evolve()
输出:
res: [[0.5+0.j 0.5+0.j]
[0.5+0.j 2.5+0.j]]
布尔函数
判等
判断两个Kraus对象的内部数据是否相等
Kraus.__eq__的API文档链接
Python
import numpy as np
def test_equal():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K2, K1, K0]
Kra3 = Kraus(Ks1, Ks2)
Kra4 = Kra3
print(Kra4 == Kra3)
if __name__ == "__main__":
test_equal()
输出: