Skip to content

量子信息 ​

本教程介绍 pyqpanda3.quantum_info 模块,该模块提供了表示和操作量子态、算子、量子通道以及统计距离度量的工具。这些基本组件对于量子算法开发、误差分析和量子硬件基准测试至关重要。

前置知识: 线路构建 和 模拟 -- 确保您已熟悉构建量子线路和运行模拟。


目录 ​


1. 模块概览 ​

quantum_info 模块提供以下组件:

python
from pyqpanda3.quantum_info import (
    StateVector,
    DensityMatrix,
    Unitary,
    Matrix,
    Kraus,
    Chi,
    Choi,
    SuperOp,
    PTM,
    hellinger_distance,
    hellinger_fidelity,
    KL_divergence,
)

这些组件分为四类:

类别类 / 函数用途
量子态StateVector、DensityMatrix表示纯态和混合态
算子Unitary、Matrix表示量子操作和一般矩阵
量子通道Kraus、Choi、SuperOp、Chi、PTM建模噪声和开放系统演化
距离度量hellinger_distance、hellinger_fidelity、KL_divergence比较概率分布
mermaid
graph TD
    A[quantum_info 模块] --> B[量子态]
    A --> C[算子]
    A --> D[量子通道]
    A --> E[距离度量]

    B --> B1[StateVector]
    B --> B2[DensityMatrix]

    C --> C1[Unitary]
    C --> C2[Matrix]

    D --> D1[Kraus]
    D --> D2[Choi]
    D --> D3[SuperOp]
    D --> D4[Chi]
    D --> D5[PTM]

    E --> E1[hellinger_distance]
    E --> E2[hellinger_fidelity]
    E --> E3[KL_divergence]

2. StateVector ​

态矢量是纯量子态最基本的表示方式。对于一个 n 量子比特系统,态矢量是一个长度为 2n 的复数数组,其元素为概率幅:

|ψ⟩=∑i=02n−1αi|i⟩

其中 αi∈C 且 ∑i|αi|2=1。

2.1 构造 StateVector ​

默认构造函数 -- 创建单量子比特态 |0⟩:

python
from pyqpanda3.quantum_info import StateVector

sv = StateVector()
print(sv)
# Output: [1+0j 0+0j]

运行结果:

[1.+0.j 0.+0.j]

通过量子比特数构造 -- 为 n 量子比特系统初始化全零态 |0⟩⊗n:

python
sv = StateVector(3)  # 3 qubits, state |000>
print(sv.dim())       # 8
print(sv.is_valid())  # True (normalized)

运行结果:

8
True

通过复数幅值的列表或 numpy 数组构造:

python
import numpy as np

# Bell 态 (|00> + |11>) / sqrt(2)
sv = StateVector([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)])
print(sv)
print(sv.is_valid())  # True

运行结果:

[0.70710678+0.j 0.        +0.j 0.        +0.j 0.70710678+0.j]
True

通过字典构造(索引到幅值的映射):

python
sv = StateVector({0: 1.0, 3: 1.0})
# 未归一化:索引 0 和 3 处有两个非零元素
print(sv.dim())  # 4 (since max index is 3)

运行结果:

4

2.2 访问数据 ​

使用 ndarray() 获取底层数据的 numpy 数组,at(i) 获取单个元素,dim() 获取维度:

python
sv = StateVector([1, 0, 0, 0])
print(sv.ndarray())  # numpy array: [1+0j, 0+0j, 0+0j, 0+0j]
print(sv.at(0))      # (1+0j)
print(sv.dim())      # 4

运行结果:

[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
(1+0j)
4

2.3 演化态矢量 ​

evolve 方法将 QCircuit 作用于态矢量并返回一个新的 StateVector,不修改原始对象。update_by_evolve 方法功能相同,但就地更新对象:

python
from pyqpanda3.quantum_info import StateVector
from pyqpanda3.core import QCircuit, X, SWAP, CP

sv = StateVector(3)  # |000>

cir = QCircuit()
cir << X(0) << SWAP(1, 2) << CP(1, 0, 3.14)

# 函数式风格:返回新的 StateVector
sv_evolved = sv.evolve(cir)
print("Original:", sv)
print("Evolved:  ", sv_evolved)

# 就地演化
sv.update_by_evolve(cir)
print("After update:", sv)

运行结果:

Original: [1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
Evolved:   [0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
After update: [0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]

2.4 密度矩阵与纯度 ​

每个纯态都有对应的密度矩阵 ρ=|ψ⟩⟨ψ|。使用 get_density_matrix() 计算它(返回 Matrix,而非 DensityMatrix):

python
sv = StateVector([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)])
dm = sv.get_density_matrix()
print(dm)

运行结果:

[[0.5+0.j 0. +0.j 0. +0.j 0.5+0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0.5+0.j 0. +0.j 0. +0.j 0.5+0.j]]

对于表示纯态的态矢量,纯度始终为 1:

γ=Tr(ρ2)
python
sv = StateVector([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)])
print(sv.purity())  # (1+0j)

运行结果:

(1.0000000000000004+0j)

两个 StateVector 对象可以使用 == 进行比较:

python
sv1 = StateVector([1, 0, 0, 0])
sv2 = StateVector(sv1)
print(sv1 == sv2)  # True

sv3 = StateVector([0, 1, 0, 0])
print(sv1 == sv3)  # False

运行结果:

True
False

3. DensityMatrix ​

密度矩阵(或密度算子)提供了量子态的最一般描述,涵盖纯态和混合态:

ρ=∑ipi|ψi⟩⟨ψi|

其中 pi≥0 且 ∑ipi=1。密度矩阵是一个迹为 1 的 2n×2n 半正定厄米矩阵。

3.1 构造 DensityMatrix ​

默认构造函数 -- 单量子比特处于态 |0⟩⟨0|:

python
from pyqpanda3.quantum_info import DensityMatrix

dm = DensityMatrix()
print(dm)

运行结果:

[[1.+0.j 0.+0.j]
 [0.+0.j 0.+0.j]]

通过量子比特数构造 -- 为 n 个量子比特初始化全零态:

python
dm = DensityMatrix(3)  # 3 qubits
print(dm.dim())  # 8

运行结果:

8

通过二维 numpy 数组构造:

python
import numpy as np

# 2 量子比特的最大混合态
data = np.eye(4, dtype=complex) / 4
dm = DensityMatrix(data)
print(dm)

运行结果:

[[0.25+0.j 0.  +0.j 0.  +0.j 0.  +0.j]
 [0.  +0.j 0.25+0.j 0.  +0.j 0.  +0.j]
 [0.  +0.j 0.  +0.j 0.25+0.j 0.  +0.j]
 [0.  +0.j 0.  +0.j 0.  +0.j 0.25+0.j]]

通过 StateVector 构造 -- 计算 |ψ⟩⟨ψ|:

python
from pyqpanda3.quantum_info import StateVector, DensityMatrix
import numpy as np

sv = StateVector([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)])
dm = DensityMatrix(sv)
print(dm)

运行结果:

[[0.5+0.j 0. +0.j 0. +0.j 0.5+0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0.5+0.j 0. +0.j 0. +0.j 0.5+0.j]]

拷贝构造函数:

python
dm_copy = DensityMatrix(dm)
print(dm == dm_copy)  # True

运行结果:

True

3.2 访问数据 ​

使用 ndarray() 获取数据的 numpy 数组,at(i, j) 获取单个元素,dim() 获取维度:

python
data = np.eye(4, dtype=complex) / 4
dm = DensityMatrix(data)

print(dm.ndarray())  # 4x4 numpy array
print(dm.at(0, 0))   # (0.25+0j)
print(dm.at(1, 2))   # 0j
print(dm.dim())      # 4

运行结果:

[[0.25+0.j 0.  +0.j 0.  +0.j 0.  +0.j]
 [0.  +0.j 0.25+0.j 0.  +0.j 0.  +0.j]
 [0.  +0.j 0.  +0.j 0.25+0.j 0.  +0.j]
 [0.  +0.j 0.  +0.j 0.  +0.j 0.25+0.j]]
(0.25+0j)
0j
4

3.3 纯度与验证 ​

纯度衡量量子态的"混合"程度。对于纯态,γ=1;对于 n 量子比特的最大混合态,γ=1/2n:

python
# 纯态
sv = StateVector([1, 0])
dm_pure = DensityMatrix(sv)
print(dm_pure.purity())  # (1+0j)

# 最大混合态
dm_mixed = DensityMatrix(np.eye(2, dtype=complex) / 2)
print(dm_mixed.purity())  # (0.5+0j)

运行结果:

(1+0j)
(0.5+0j)

is_valid() 方法检查密度矩阵是否满足三个物理要求:厄米性、半正定性和迹为 1:

python
data = np.eye(4, dtype=complex) / 4
dm = DensityMatrix(data)
print(dm.is_valid())  # True

# 一个无效的密度矩阵(构造函数在构造时验证)
try:
    bad = DensityMatrix(np.ones((4, 4), dtype=complex))
    print(bad.is_valid())
except RuntimeError as e:
    print("Invalid density matrix rejected:", str(e).split()[0])

运行结果:

True
Invalid density matrix rejected: Error:

3.4 演化密度矩阵 ​

与 StateVector 类似,DensityMatrix 支持通过 QCircuit 进行函数式和就地演化:

python
from pyqpanda3.core import QCircuit, X, SWAP, CP

dm = DensityMatrix(3)

cir = QCircuit()
cir << X(0) << SWAP(1, 2) << CP(1, 0, 3.14)

# 函数式:返回新的 DensityMatrix,原始对象不变
dm_evolved = dm.evolve(cir)
print("Original:", dm)
print("Evolved:  ", dm_evolved)

# 就地更新
dm.update_by_evolve(cir)
print("After update:", dm)

运行结果:

Original: [[1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
Evolved:   [[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
After update: [[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]]

3.5 转换为 StateVector ​

对于纯态密度矩阵,to_statevector() 提取对应的态矢量:

python
sv = StateVector([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)])
dm = DensityMatrix(sv)
recovered = dm.to_statevector()
print(recovered)

运行结果:

[(0.7071067811865475+0j), 0j, 0j, (0.7071067811865475+0j)]

注意:此方法假设密度矩阵表示纯态。对于混合态,结果可能没有物理意义。


4. Unitary ​

Unitary 类表示从量子线路或量子门中提取的幺正算子。幺正算子 U 满足 U†U=I。

4.1 构造 Unitary ​

从量子线路构造:

python
from pyqpanda3.quantum_info import Unitary
from pyqpanda3.core import QCircuit, X, CNOT, CP

cir = QCircuit()
cir << X(0) << CP(2, 1, 5.28) << CNOT(1, 0)

u = Unitary(cir)
print(u)

运行结果:

[[0.        +0.j         1.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j        ]
 [1.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j        ]
 [0.        +0.j         0.        +0.j         1.        +0.j
  0.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j        ]
 [0.        +0.j         0.        +0.j         0.        +0.j
  1.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j        ]
 [0.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j         1.        +0.j
  0.        +0.j         0.        +0.j        ]
 [0.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         1.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j        ]
 [0.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j         0.        +0.j
  0.53761923-0.84318774j 0.        +0.j        ]
 [0.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.        +0.j         0.        +0.j
  0.        +0.j         0.53761923-0.84318774j]]

Unitary(cir) 自动从线路中检测量子比特数。

4.2 访问数据 ​

ndarray() 方法以 numpy 数组形式返回幺正矩阵:

python
cir = QCircuit()
cir << X(0) << CNOT(1, 0)

u = Unitary(cir)
matrix = u.ndarray()
print(matrix)
print("Shape:", matrix.shape)  # e.g., (8, 8)

运行结果:

[[0.+0.j 1.+0.j 0.+0.j 0.+0.j]
 [1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 1.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
Shape: (4, 4)

来自同一线路的两个 Unitary 对象可以进行比较:

python
u1 = Unitary(cir)
u2 = Unitary(cir)
print(u1 == u2)  # True

运行结果:

True

5. Matrix ​

Matrix 类是一个通用的复数矩阵封装,支持常见的线性代数运算。它作为本模块中其他类的基础构建块。

Matrix 可以表示矩形和方阵、行向量和列向量以及单位矩阵。

5.1 构造 Matrix ​

从 numpy 数组构造:

python
from pyqpanda3.quantum_info import Matrix
import numpy as np

# 一般矩形矩阵
data = np.array([[1+1j, 2+2j, 3+3j, 4+4j],
                 [5+5j, 6+6j, 7+7j, 8+8j],
                 [9+9j, 10+10j, 11+11j, 12+12j]], dtype=complex)
m = Matrix(data)
print(m)

运行结果:

[[ 1. +1.j  2. +2.j  3. +3.j  4. +4.j]
 [ 5. +5.j  6. +6.j  7. +7.j  8. +8.j]
 [ 9. +9.j 10.+10.j 11.+11.j 12.+12.j]]

从 Python 嵌套列表构造:

python
m = Matrix(np.array([[1, 0], [0, 1]], dtype=complex))
print(m.row_total())  # 2
print(m.col_total())  # 2

运行结果:

2
2

5.2 矩阵运算 ​

Matrix 类提供以下运算:

python
from pyqpanda3.quantum_info import Matrix
import numpy as np

# 创建一个厄米矩阵
data = np.array([[3+0j, 1+2j],
                 [1-2j, 2+0j]], dtype=complex)
m = Matrix(data)

print("ndarray:", m.ndarray())
print("row_total:", m.row_total())  # 2
print("col_total:", m.col_total())  # 2
print("is_hermitian:", m.is_hermitian())  # True

# 转置
mt = m.transpose()
print("transpose:", mt)

# 伴随(共轭转置)
ma = m.adjoint()
print("adjoint:", ma)

# L2 范数(最大奇异值)
print("L2:", np.linalg.norm(m.ndarray(), 2))

运行结果:

ndarray: [[3.+0.j 1.+2.j]
 [1.-2.j 2.+0.j]]
row_total: 2
col_total: 2
is_hermitian: True
transpose: [[3.+0.j 1.-2.j]
 [1.+2.j 2.+0.j]]
adjoint: [[3.+0.j 1.+2.j]
 [1.-2.j 2.+0.j]]
L2: 4.7912878474779195

相等性检查:

python
m2 = m
print(m == m2)  # True

运行结果:

True

6. 量子通道 ​

量子通道描述了量子态的最一般物理变换。在数学上,它是一个完全正迹保持(CPTP)映射。pyqpanda3 支持五种等价的量子通道表示。

6.1 Kraus 表示 ​

Kraus 算子和形式是最直观的表示:

E(ρ)=∑iKiρKi†

满足迹保持条件 ∑iKi†Ki=I。

对于非迹保持通道(例如测量算子),可以使用双侧形式:

E(ρ)=∑iKi(L)ρ(Ki(R))†

构造 Kraus 通道:

python
from pyqpanda3.quantum_info import Kraus
import numpy as np

# 单侧(迹保持):E(rho) = sum K_i rho K_i^dagger
K0 = np.array([[1, 0], [0, 0]], dtype=complex)
K1 = np.array([[0, 0], [0, 1]], dtype=complex)
kraus = Kraus([K0, K1])
print(kraus)

运行结果:

[Kraus:
[Kraus_left:
[ [1+0j 0+0j]
[0+0j 0+0j]
] 
[ [0+0j 0+0j]
[0+0j 1+0j]
] 
]
[Kraus_right:
]
]

双侧 Kraus(用于广义通道):

python
K0 = np.array([[1+11j, 1+12j], [1+21j, 1+22j]])
K1 = np.array([[2+11j, 2+12j], [2+21j, 2+22j]])
K2 = np.array([[3+11j, 3+12j], [3+21j, 3+22j]])

Ks_left = [K0, K1, K2]
Ks_right = [K2, K1, K0]

kraus_two = Kraus(Ks_left, Ks_right)
print(kraus_two)

运行结果:

[Kraus:
[Kraus_left:
[ [1+11j 1+12j]
[1+21j 1+22j]
] 
[ [2+11j 2+12j]
[2+21j 2+22j]
] 
[ [3+11j 3+12j]
[3+21j 3+22j]
] 
]
[Kraus_right:
[ [3+11j 3+12j]
[3+21j 3+22j]
]  
[ [2+11j 2+12j]
[2+21j 2+22j]
]  
[ [1+11j 1+12j]
[1+21j 1+22j]
] 
]
]

访问算子:

python
left_ops = kraus_two.left()   # list of left operators
right_ops = kraus_two.right()  # list of right operators
for op in left_ops:
    print(op)

运行结果:

[[1.+11.j 1.+12.j]
 [1.+21.j 1.+22.j]]
[[2.+11.j 2.+12.j]
 [2.+21.j 2.+22.j]]
[[3.+11.j 3.+12.j]
 [3.+21.j 3.+22.j]]

增量构造:

python
kraus = Kraus()
kraus.left_push_back(K0)
kraus.left_push_back(K1)
kraus.right_push_back(K0)
print(kraus)

运行结果:

[Kraus:
[Kraus_left:
[ [1+11j 1+12j]
[1+21j 1+22j]
] 
[ [2+11j 2+12j]
[2+21j 2+22j]
] 
]
[Kraus_right:
[ [1+11j 1+12j]
[1+21j 1+22j]
] 
]
]

其他 Kraus 方法包括 append(other_kraus) 用于组合通道,以及 clear() 用于移除所有算子。

6.2 Choi 表示 ​

Choi 矩阵将通道表示为 d2×d2 半正定矩阵。对于作用于 d 维态上的通道 E:

J(E)=∑i,j=0d−1|i⟩⟨j|⊗E(|i⟩⟨j|)

当且仅当 Choi 矩阵半正定时,通道是完全正的。当且仅当 Choi 矩阵在输出空间上的偏迹等于单位矩阵时,通道是迹保持的。

python
from pyqpanda3.quantum_info import Choi

# 从 Kraus 构造
choi = Choi(kraus)
print(choi)
print("Input dim:", choi.get_input_dim())
print("Output dim:", choi.get_output_dim())

运行结果:

[[247. +0.j 467.-30.j 269. -3.j 489.-33.j]
 [467.+30.j 887. +0.j 509.+27.j 929. -3.j]
 [269. +3.j 509.-27.j 293. +0.j 533.-30.j]
 [489.+33.j 929. +3.j 533.+30.j 973. +0.j]]
Input dim: 2
Output dim: 2

6.3 SuperOp 表示 ​

SuperOp(超算子)表示将通道重塑为 d2×d2 矩阵,作用于向量化后的密度矩阵:

vec(E(ρ))=S⋅vec(ρ)

这对于组合通道很有用(SuperOp 矩阵的矩阵乘法对应于通道的顺序应用)。

python
from pyqpanda3.quantum_info import SuperOp

superop = SuperOp(kraus)
print(superop)
print("Input dim:", superop.get_input_dim())
print("Output dim:", superop.get_output_dim())

运行结果:

[[247. +0.j 269. +3.j 269. -3.j 293. +0.j]
 [467.+30.j 489.+33.j 509.+27.j 533.+30.j]
 [467.-30.j 509.-27.j 489.-33.j 533.-30.j]
 [887. +0.j 929. +3.j 929. -3.j 973. +0.j]]
Input dim: 2
Output dim: 2

6.4 Chi 表示 ​

Chi(χ)矩阵在 Pauli 基下展开通道。对于 n 量子比特通道,Pauli 基由 {I,X,Y,Z} 的 4n 个张量积组成:

E(ρ)=∑m,nχmnPmρPn†

Chi 矩阵对于过程层析成像和噪声表征很有用。

python
from pyqpanda3.quantum_info import Chi

chi = Chi(kraus)
print(chi)
print("Input dim:", chi.get_input_dim())
print("Output dim:", chi.get_output_dim())

运行结果:

[[1099.  +0.j 1099.  +0.j   27.+297.j -363. +33.j]
 [1099.  +0.j 1099.  +0.j   27.+297.j -363. +33.j]
 [  27.-297.j   27.-297.j   81.  +0.j    0. +99.j]
 [-363. -33.j -363. -33.j    0. -99.j  121.  +0.j]]
Input dim: 2
Output dim: 2

6.5 PTM 表示 ​

Pauli 传递矩阵(PTM)描述通道如何变换 Pauli 期望值:

Rmn=1dTr(PmE(Pn))

PTM 是实值矩阵(对于保厄米通道),常用于随机基准测试和门集层析成像。

python
from pyqpanda3.quantum_info import PTM

ptm = PTM(kraus)
print(ptm)
print("Input dim:", ptm.get_input_dim())
print("Output dim:", ptm.get_output_dim())

运行结果:

[[1200.+0.j 1198.+0.j   -6.+0.j  -66.+0.j]
 [1000.+0.j  998.+0.j   -6.+0.j  -66.+0.j]
 [  60.+0.j   60.+0.j  -20.+0.j    0.+0.j]
 [-660.+0.j -660.+0.j    0.+0.j   20.+0.j]]
Input dim: 2
Output dim: 2

6.6 不同表示之间的转换 ​

所有五种表示都可以从任何其他表示构造。pyqpanda3 会自动处理转换:

python
import numpy as np
from pyqpanda3.quantum_info import Kraus, Choi, Chi, SuperOp, PTM

K0 = np.array([[1, 0], [0, 0]], dtype=complex)
K1 = np.array([[0, 0], [0, 1]], dtype=complex)
kraus = Kraus([K0, K1])

# 转换为所有其他表示
choi = Choi(kraus)
superop = SuperOp(kraus)
chi = Chi(kraus)
ptm = PTM(kraus)

# 反向转换 -- 每种都可以从任何其他表示构造
kraus_from_choi = Kraus(choi)
kraus_from_chi = Kraus(chi)
kraus_from_superop = Kraus(superop)
kraus_from_ptm = Kraus(ptm)

# 也支持交叉转换
choi_from_superop = Choi(superop)
ptm_from_chi = PTM(chi)
chi_from_ptm = Chi(ptm)

6.7 通过通道演化量子态 ​

所有通道表示都支持 evolve 方法,该方法接受 StateVector 或 DensityMatrix 并返回 DensityMatrix:

python
from pyqpanda3.quantum_info import (
    StateVector, DensityMatrix, Kraus
)
import numpy as np

# 定义振幅阻尼通道
gamma = 0.3
K0 = np.array([[1, 0], [0, np.sqrt(1 - gamma)]], dtype=complex)
K1 = np.array([[0, np.sqrt(gamma)], [0, 0]], dtype=complex)
kraus = Kraus([K0, K1])

# 演化密度矩阵
dm = DensityMatrix(np.eye(2, dtype=complex) / 2)
result = kraus.evolve(dm)
print("Evolved density matrix:", result)
print("Is valid:", result.is_valid())

# 演化态矢量(返回 DensityMatrix)
sv = StateVector([0, 1])  # |1>
result_sv = kraus.evolve(sv)
print("Evolved from |1>:", result_sv)
print("Is valid:", result_sv.is_valid())

运行结果:

Evolved density matrix: [[0.65+0.j 0.  +0.j]
 [0.  +0.j 0.35+0.j]]
Is valid: True
Evolved from |1>: [[0.3+0.j 0. +0.j]
 [0. +0.j 0.7+0.j]]
Is valid: True

7. 距离与相似度度量 ​

quantum_info 模块提供三种统计距离度量,用于比较概率分布。这些度量对于量子硬件基准测试、比较测量结果与期望输出以及噪声分析至关重要。

mermaid
graph TD
    subgraph "距离度量"
        HD["hellinger_distance<br/>dict, dict → float"]
        HF["hellinger_fidelity<br/>dict, dict → float"]
        KL1["KL_divergence<br/>list, list → float"]
        KL2["KL_divergence<br/>callable, callable,<br/>float, float, float → float"]
    end

    HD --> |"H_f = (1 - H_d^2)^2"| HF
    KL1 --> |"离散分布"| NOTE1["非对称,非负"]
    KL2 --> |"连续分布"| NOTE2["数值积分"]

    style HD fill:#e3f2fd
    style HF fill:#e8f5e9
    style KL1 fill:#fff3e0
    style KL2 fill:#fce4ec

7.1 Hellinger 距离 ​

Hellinger 距离衡量两个离散概率分布之间的相似度。它接受字符串或整数键的字典:

Hd(p,q)=12∑x(p(x)−q(x))2

性质:

  • 取值范围:[0,1]
  • Hd(p,p)=0(相同分布)
  • 当 p 和 q 支撑集不相交时,Hd(p,q)=1
python
from pyqpanda3.quantum_info import hellinger_distance

# 字符串键
p = {'00': 0.5, '11': 0.5}
q = {'00': 0.6, '11': 0.4}
print(hellinger_distance(p, q))

# 整数键
p2 = {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25}
q2 = {0: 0.5, 1: 0.3, 2: 0.1, 3: 0.1}
print(hellinger_distance(p2, q2))

运行结果:

0.0711607124393506
0.2373974823735611

7.2 Hellinger 保真度 ​

由 Hellinger 距离导出的保真度,提供了一种相似度度量:相同分布时为 1,差异最大时为 0:

Hf(p,q)=(1−Hd(p,q)2)2
python
from pyqpanda3.quantum_info import hellinger_fidelity

p = {'00': 0.5, '11': 0.5}
q = {'00': 0.48, '11': 0.45, '01': 0.04, '10': 0.03}

hd = hellinger_distance(p, q)
hf = hellinger_fidelity(p, q)
print(f"Hellinger distance: {hd:.6f}")
print(f"Hellinger fidelity:  {hf:.6f}")

运行结果:

Hellinger distance: 0.189104
Hellinger fidelity:  0.929758

7.3 KL 散度(离散) ​

Kullback-Leibler 散度衡量概率分布 p 与第二个分布 q 之间的偏离程度:

KL(p|q)=∑xp(x)log⁡(p(x)q(x))

性质:

  • 始终非负:KL(p|q)≥0
  • 不对称:一般情况下 KL(p|q)≠KL(q|p)
  • 当且仅当 p=q 时,KL(p|q)=0
  • 当 q(x)=0 且 p(x)>0 时未定义

对于离散分布,KL_divergence 接受两个概率列表或 numpy 数组:

python
from pyqpanda3.quantum_info import KL_divergence

p = [0.5, 0.5]
q = [0.6, 0.4]
kl = KL_divergence(p, q)
print(f"KL(p || q) = {kl:.6f}")

# 不对称性演示
kl_reverse = KL_divergence(q, p)
print(f"KL(q || p) = {kl_reverse:.6f}")
# 这两个值将不同

# 相同分布
print(KL_divergence([0.25, 0.25, 0.25, 0.25],
                    [0.25, 0.25, 0.25, 0.25]))  # 0.0

运行结果:

KL(p || q) = 0.020411
KL(q || p) = 0.020136
0.0

7.4 KL 散度(连续) ​

对于连续概率分布,KL_divergence 接受 Python 可调用对象(函数)以及积分范围步长:

KL(p|q)=∫xstartxendp(x)log⁡(p(x)q(x))dx

数值积分使用步长为 dx 的黎曼和:

python
from pyqpanda3.quantum_info import KL_divergence
import math

def normal_pdf(x, mu, sigma):
    coefficient = 1 / (sigma * math.sqrt(2 * math.pi))
    exponent = math.exp(-0.5 * ((x - mu) / sigma) ** 2)
    return coefficient * exponent

def p_pdf(x):
    return normal_pdf(x, mu=3, sigma=3.14)

def q_pdf(x):
    return 0.000001  # Approximate uniform (near-zero constant)

kl_continuous = KL_divergence(
    p_pdf=p_pdf,
    q_pdf=q_pdf,
    x_start=-5.0,
    x_end=6.0,
    dx=0.0001
)
print(f"Continuous KL divergence: {kl_continuous:.6f}")

运行结果:

Continuous KL divergence: 9.422499

7.5 量子态保真度 ​

上面的三种度量比较的都是概率分布(测量结果)。当你需要直接比较两个量子态时,使用 state_fidelity()。它支持密度矩阵与态矢量两两组合的四种输入:态矢量保真度为 |⟨ψ2|ψ1⟩|2,密度矩阵保真度使用标准的 Uhlmann 定义。

说明:扁平(一维)输入被解释为态矢量,二维方阵被解释为密度矩阵。

python
from pyqpanda3.quantum_info import state_fidelity

plus = [[0.5, 0.5], [0.5, 0.5]]   # |+><+|
zero = [[1.0, 0.0], [0.0, 0.0]]   # |0><0|

# 密度矩阵 × 密度矩阵
print(round(state_fidelity(plus, zero), 6))

# 密度矩阵 × 态矢量(|0> 与自身,保真度为 1)
print(round(state_fidelity(zero, [1.0, 0.0]), 6))

# 态矢量 × 态矢量(两个正交叠加态,保真度为 0)
print(round(state_fidelity([0.5, 0.5, 0.5, 0.5], [0.5, -0.5, 0.5, -0.5]), 6))

运行结果:

0.5
1.0
0.0

validate=True(默认)会校验归一化与正定性,校验失败抛出 RuntimeError;设为 False 可跳过校验(此时结果可能超出 [0, 1])。完整的重载签名与参数说明见 分析 API 参考。


8. 完整示例 ​

以下示例将态构造、线路演化、通道应用和距离度量组合为一个完整的工作流程:

python
import numpy as np
from pyqpanda3.quantum_info import (
    StateVector, DensityMatrix, Kraus, Choi, Chi, SuperOp, PTM,
    hellinger_distance, hellinger_fidelity, KL_divergence,
)

# --- 步骤 1:创建 Bell 态 ---
sv = StateVector([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)])
print("Bell state purity:", sv.purity())

# --- 步骤 2:转换为密度矩阵 ---
dm = DensityMatrix(sv)
print("Is valid:", dm.is_valid())

# --- 步骤 3:应用去极化噪声通道(扩展到 2 量子比特)---
p_noise = 0.1
I = np.eye(2, dtype=complex)
X = np.array([[0, 1], [1, 0]], dtype=complex)
Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
Z = np.array([[1, 0], [0, -1]], dtype=complex)

K0 = np.sqrt(1 - 3*p_noise/4) * I
K1 = np.sqrt(p_noise/4) * X
K2 = np.sqrt(p_noise/4) * Y
K3 = np.sqrt(p_noise/4) * Z

# 扩展到 2 量子比特:Ki ⊗ I(量子比特 0 上的去极化)
kraus = Kraus([np.kron(K0, I), np.kron(K1, I), np.kron(K2, I), np.kron(K3, I)])
dm_noisy = kraus.evolve(dm)
print("Noisy purity:", dm_noisy.purity())

# --- 步骤 4:在通道表示之间转换 ---
choi = Choi(kraus)
chi = Chi(kraus)
superop = SuperOp(kraus)
ptm = PTM(kraus)

# 所有表示产生等价的演化
print("Choi evolve == Chi evolve:",
      choi.evolve(dm) == chi.evolve(dm))

# --- 步骤 5:使用距离度量比较分布 ---
ideal = {'00': 0.5, '11': 0.5}
noisy = {'00': 0.48, '11': 0.45, '01': 0.04, '10': 0.03}
print("Hellinger distance:", hellinger_distance(ideal, noisy))
print("Hellinger fidelity:", hellinger_fidelity(ideal, noisy))
# 使用二进制精确的概率值,确保 IEEE 754 中求和恰好为 1.0
print("KL divergence:", KL_divergence(
    [0.5, 0.25, 0.125, 0.125],
    [0.5, 0.125, 0.125, 0.25]
))

运行结果:

Bell state purity: (1.0000000000000004+0j)
Is valid: True
Noisy purity: (0.8575000000000004+0j)
Choi evolve == Chi evolve: True
Hellinger distance: 0.18910421047165366
Hellinger fidelity: 0.92975800154489
KL divergence: 0.08664339756999316

9. 数学背景 ​

量子态 ​

纯态 由希尔伯特空间中的归一化矢量描述:

|ψ⟩=∑i=0d−1αi|i⟩,∑i|αi|2=1

混合态 是纯态的统计系综,由密度矩阵描述:

ρ=∑ipi|ψi⟩⟨ψi|,pi≥0,∑ipi=1

有效密度矩阵的性质:

  • 厄米性:ρ=ρ†
  • 半正定性:ρ≥0
  • 迹为 1:Tr(ρ)=1

纯度 ​

纯度量化量子态的"混合程度":

γ=Tr(ρ2)
  • γ=1:纯态
  • 1/d<γ<1:混合态(d=2n)
  • γ=1/d:最大混合态

Kraus 算子和表示 ​

量子态的最一般物理变换为:

E(ρ)=∑iKiρKi†

满足迹保持条件 ∑iKi†Ki=I。

通道表示 ​

表示同一 CPTP 映射的五种等价方式:

表示矩阵大小关键性质
Kraus一组 d×d′ 矩阵算子和形式
Choidd′×dd′当且仅当 CP 时半正定
SuperOpd′2×d2向量化 ρ 上的线性映射
Chid2×d2Pauli 基展开
PTMd2×d2(实值)Pauli 期望值映射

Hellinger 距离与保真度 ​

Hd(p,q)=12∑x(p(x)−q(x))2Hf(p,q)=(1−Hd(p,q)2)2

KL 散度 ​

离散形式:

KL(p|q)=∑xp(x)log⁡(p(x)q(x))

连续形式:

KL(p|q)=∫p(x)log⁡(p(x)q(x))dx

注意,KL 散度不是真正的度量——它是非对称的,不满足三角不等式。但它是一个合理的散度度量:始终非负,且仅当 p=q 时为零。


10. API 参考 ​

StateVector ​

方法签名描述
构造函数StateVector()单量子比特处于 |0⟩
构造函数StateVector(qbit_total: int)n 量子比特全零态
构造函数StateVector(data: list)从复数幅值列表构造
构造函数StateVector(data: dict)从索引-幅值映射构造
构造函数StateVector(data: numpy.ndarray)从 numpy 数组构造
ndarray()-> numpy.ndarray内部数据的 numpy 数组
dim()-> int维度(2n)
at(idx)-> complex索引处的元素
purity()-> complexTr(ρ2)
is_valid()-> bool检查归一化
evolve(circuit)-> StateVector函数式演化
update_by_evolve(circuit)-> StateVector就地演化
get_density_matrix()-> Matrix计算 |ψ⟩⟨ψ|

DensityMatrix ​

方法签名描述
构造函数DensityMatrix()单量子比特 |0⟩⟨0|
构造函数DensityMatrix(qbit_total: int)n 量子比特全零态
构造函数DensityMatrix(data: 2D array)从矩阵数据构造
构造函数DensityMatrix(StateVector)从纯态构造
ndarray()-> numpy.ndarray内部数据
dim()-> int维度
at(row, col)-> complex矩阵元素
purity()-> complexTr(ρ2)
is_valid()-> bool厄米性、半正定、迹为 1
evolve(circuit)-> DensityMatrix函数式演化
update_by_evolve(circuit)-> DensityMatrix就地演化
to_statevector()-> list[complex]提取态矢量

量子通道(Kraus、Choi、SuperOp、Chi、PTM) ​

所有通道类共享通用接口:

方法描述
Constructor(other_repr)从任何其他表示转换
evolve(state)将通道应用于 StateVector 或 DensityMatrix
get_input_dim()输入希尔伯特空间维度
get_output_dim()输出希尔伯特空间维度

Kraus 特有方法:

方法描述
left()左算子列表
right()右算子列表
left_push_back(val)追加到左算子列表
right_push_back(val)追加到右算子列表
append(other)与另一个 Kraus 通道组合
clear()移除所有算子

距离函数 ​

函数签名描述
hellinger_distance(dict, dict) -> floatHellinger 距离 Hd∈[0,1]
hellinger_fidelity(dict, dict) -> floatHellinger 保真度 Hf∈[0,1]
KL_divergence(list, list) -> float离散 KL 散度
KL_divergence(fn, fn, float, float, float) -> float通过数值积分的连续 KL 散度

下一步? ​

既然您已经了解了 pyqpanda3 中的量子信息基础知识,请继续学习:


知识检测 ​

测试您对 quantum_info 模块的理解。

Q1:纯态和混合态有什么区别?如何通过编程区分它们?

A1:纯态可以用单个态矢量 |ψ⟩ 描述,其纯度 γ=Tr(ρ2)=1。混合态是统计系综,其纯度 γ<1。在 pyqpanda3 中,计算 dm.purity() 并检查其实部是否等于 1。

Q2:什么是 Kraus 算子和表示?对于迹保持通道,Kraus 算子需要满足什么条件?

A2:Kraus 表示将通道写为 E(ρ)=∑iKiρKi†。为满足迹保持,算子必须满足 ∑iKi†Ki=I。这确保了对于所有有效的 ρ,都有 Tr(E(ρ))=Tr(ρ)。

Q3:列出 pyqpanda3 中所有五种量子通道表示,并说明各自的优点。

A3:(1) Kraus -- 直观的物理解释;(2) Choi -- 易于验证完全正性(检查半正定性);(3) SuperOp -- 组合操作为矩阵乘法;(4) Chi -- 在 Pauli 基下进行过程层析成像的自然选择;(5) PTM -- 实值,用于随机基准测试。

Q4:为什么 KL 散度不是真正的度量?这对比较两个分布有什么影响?

A4:KL 散度是非对称的:一般情况下 KL(p|q)≠KL(q|p),且不满足三角不等式。这意味着"方向"很重要——KL(p|q) 衡量的是用 q 近似 p 时损失的信息量,而非对称距离。

Q5:如果将 γ=0.5 的振幅阻尼通道应用于态 |1⟩,演化后在该量子比特上测量到 |0⟩ 的概率是多少?

A5:振幅阻尼 Kraus 算子为 K0=(1001−γ) 和 K1=(0γ00)。对于 |1⟩:K0|1⟩=0.5|1⟩,K1|1⟩=0.5|0⟩。测量到 |0⟩ 的概率为 |0.5|2=0.5,与阻尼参数 γ 一致。

Q6:is_valid() 对 DensityMatrix 检查什么?

A6:它验证三个性质:(1) 厄米性:ρ=ρ†;(2) 半正定性:所有特征值 ≥0;(3) 迹为 1:Tr(ρ)=1。满足所有三个条件的矩阵才是物理上有效的密度矩阵。

Q7:什么时候应该对 StateVector 或 DensityMatrix 使用 evolve() 而不是 update_by_evolve()?

A7:当您希望保留原始状态时,使用 evolve() 的函数式编程风格——它返回一个新对象。当您不再需要原始状态并希望通过就地修改来节省内存时,使用 update_by_evolve()。


练习 1:去极化通道纯度分析

构造参数为 p 的去极化通道,并将其应用于 Bell 态密度矩阵。绘制或打印当 p 从 0 增加到 1 时纯度的变化。

解答:

python
import numpy as np
from pyqpanda3.quantum_info import StateVector, DensityMatrix, Kraus

# Bell 态
sv = StateVector([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)])
dm = DensityMatrix(sv)

# Pauli 矩阵
I = np.eye(2, dtype=complex)
X = np.array([[0, 1], [1, 0]], dtype=complex)
Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
Z = np.array([[1, 0], [0, -1]], dtype=complex)

# 2 量子比特单位矩阵(用于张量积通道)
I4 = np.eye(4, dtype=complex)

print("p     | purity")
print("------|-------")
for p in [0.0, 0.1, 0.2, 0.3, 0.5, 0.7, 1.0]:
    # 对量子比特 0 的单量子比特去极化
    K0 = np.sqrt(1 - 3*p/4) * I
    K1 = np.sqrt(p/4) * X
    K2 = np.sqrt(p/4) * Y
    K3 = np.sqrt(p/4) * Z

    # 扩展到 2 量子比特:I ⊗ Ki
    K0_2 = np.kron(K0, I)
    K1_2 = np.kron(K1, I)
    K2_2 = np.kron(K2, I)
    K3_2 = np.kron(K3, I)

    kraus = Kraus([K0_2, K1_2, K2_2, K3_2])
    dm_noisy = kraus.evolve(dm)
    purity = dm_noisy.purity()
    print(f"{p:.1f}   | {purity.real:.6f}")

运行结果:

p     | purity
------|-------
0.0   | 1.000000
0.1   | 0.857500
0.2   | 0.730000
0.3   | 0.617500
0.5   | 0.437500
0.7   | 0.317500
1.0   | 0.250000

练习 2:通道表示往返验证

创建一个 Kraus 通道,将其转换为所有其他四种表示,然后再将每种表示转换回 Kraus,验证它们在测试态上产生相同的演化。

解答:

python
import numpy as np
from pyqpanda3.quantum_info import (
    StateVector, DensityMatrix, Kraus, Choi, Chi, SuperOp, PTM
)

# 定义比特翻转通道
p = 0.2
K0 = np.array([[np.sqrt(1-p), 0], [0, np.sqrt(1-p)]], dtype=complex)
K1 = np.array([[0, np.sqrt(p)], [np.sqrt(p), 0]], dtype=complex)
kraus = Kraus([K0, K1])

# 转换为所有表示并转换回来
choi = Choi(kraus)
kraus_from_choi = Kraus(choi)

chi = Chi(kraus)
kraus_from_chi = Kraus(chi)

superop = SuperOp(kraus)
kraus_from_superop = Kraus(superop)

ptm = PTM(kraus)
kraus_from_ptm = Kraus(ptm)

# 测试态 |+>
sv = StateVector([1/np.sqrt(2), 1/np.sqrt(2)])
dm = DensityMatrix(sv)

# 所有表示应产生相同的演化态
result_original = kraus.evolve(dm)
result_choi = kraus_from_choi.evolve(dm)
result_chi = kraus_from_chi.evolve(dm)
result_superop = kraus_from_superop.evolve(dm)
result_ptm = kraus_from_ptm.evolve(dm)

print("All representations produce same result:")
print(f"  Original == Choi round-trip:    {result_original == result_choi}")
print(f"  Original == Chi round-trip:     {result_original == result_chi}")
print(f"  Original == SuperOp round-trip: {result_original == result_superop}")
print(f"  Original == PTM round-trip:     {result_original == result_ptm}")

运行结果:

All representations produce same result:
  Original == Choi round-trip:    True
  Original == Chi round-trip:     True
  Original == SuperOp round-trip: True
  Original == PTM round-trip:     True

Released under the MIT License.