1. DeepQuantum 简介¶
1.1 什么是 DeepQuantum?¶
DeepQuantum 是一个基于 PyTorch 的量子计算框架,具有以下核心特点:
- 与 PyTorch 深度集成:支持自动微分、GPU 加速和批处理
- 高效的量子模拟:支持态矢、密度矩阵、矩阵乘积态(MPS)等多种表示方式
- 丰富的量子门库:包含所有常用的单比特门、双比特门和多比特门
- 变分量子算法:方便实现 VQE、QAOA 等混合量子-经典算法
- 量子机器学习:支持振幅编码、角度编码等多种量子编码方式
- 分布式计算:支持分布式量子态和分布式线路
- 光量子计算:支持高斯玻色采样、连续变量量子计算
1.2 应用场景¶
- 量子化学(VQE 求解分子基态能量)
- 组合优化(QAOA 求解最大割问题等)
- 量子机器学习(量子神经网络)
- 量子算法研究(量子傅里叶变换、HHL 算法等)
- 光量子计算(玻色采样、簇态制备)
In [ ]:
Copied!
# 在命令行中安装 DeepQuantum
# pip install deepquantum
# 或者从源码安装
# cd E:\02_Projects\turingQ\deepquantum
# pip install -e .
# 在命令行中安装 DeepQuantum
# pip install deepquantum
# 或者从源码安装
# cd E:\02_Projects\turingQ\deepquantum
# pip install -e .
2.2 导入必要的库¶
In [ ]:
Copied!
# 导入 DeepQuantum 框架
import deepquantum as dq
# 导入 PyTorch 和相关工具
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
# 设置随机种子以保证结果可复现
torch.manual_seed(42)
np.random.seed(42)
# 打印版本信息
print(f"DeepQuantum version: {dq.__version__}")
print(f"PyTorch version: {torch.__version__}")
print(f"CUDA available: {torch.cuda.is_available()}")
# 导入 DeepQuantum 框架
import deepquantum as dq
# 导入 PyTorch 和相关工具
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
# 设置随机种子以保证结果可复现
torch.manual_seed(42)
np.random.seed(42)
# 打印版本信息
print(f"DeepQuantum version: {dq.__version__}")
print(f"PyTorch version: {torch.__version__}")
print(f"CUDA available: {torch.cuda.is_available()}")
In [ ]:
Copied!
# 创建一个单量子比特态,初始化为 |1⟩ 态
# state=[0, 1] 表示振幅为 [0, 1],对应基态 |1⟩
qstate = dq.QubitState(nqubit=1, state=[0, 1])
print("单量子比特态 |1⟩:")
print(qstate.state)
print(f"量子态形状: {qstate.state.shape}")
# 创建一个单量子比特态,初始化为 |1⟩ 态
# state=[0, 1] 表示振幅为 [0, 1],对应基态 |1⟩
qstate = dq.QubitState(nqubit=1, state=[0, 1])
print("单量子比特态 |1⟩:")
print(qstate.state)
print(f"量子态形状: {qstate.state.shape}")
In [ ]:
Copied!
# 创建两量子比特态,初始化为 |00⟩ 态
qstate2 = dq.QubitState(nqubit=2, state='zeros')
print("\n两量子比特态 |00⟩:")
print(qstate2.state)
print(f"量子态形状: {qstate2.state.shape}")
# 创建两量子比特态,初始化为 |00⟩ 态
qstate2 = dq.QubitState(nqubit=2, state='zeros')
print("\n两量子比特态 |00⟩:")
print(qstate2.state)
print(f"量子态形状: {qstate2.state.shape}")
In [ ]:
Copied!
# 创建等权叠加态(所有基态等概率叠加)
# 对于 2 个量子比特,等权叠加态为 (|00⟩ + |01⟩ + |10⟩ + |11⟩)/2
equal_state = dq.QubitState(nqubit=2, state='equal')
print("\n等权叠加态:")
print(equal_state.state)
# 创建等权叠加态(所有基态等概率叠加)
# 对于 2 个量子比特,等权叠加态为 (|00⟩ + |01⟩ + |10⟩ + |11⟩)/2
equal_state = dq.QubitState(nqubit=2, state='equal')
print("\n等权叠加态:")
print(equal_state.state)
In [ ]:
Copied!
# 创建 GHZ 态(Greenberger-Horne-Zeilinger 态)
# GHZ 态是多量子比特最大纠缠态,形式为 (|000...0⟩ + |111...1⟩)/√2
ghz_state = dq.QubitState(nqubit=3, state='ghz')
print("\nGHZ 态 (3 量子比特):")
print(ghz_state.state)
print(f"\nGHZ 态的特点:只有 |000⟩ 和 |111⟩ 的振幅非零")
# 创建 GHZ 态(Greenberger-Horne-Zeilinger 态)
# GHZ 态是多量子比特最大纠缠态,形式为 (|000...0⟩ + |111...1⟩)/√2
ghz_state = dq.QubitState(nqubit=3, state='ghz')
print("\nGHZ 态 (3 量子比特):")
print(ghz_state.state)
print(f"\nGHZ 态的特点:只有 |000⟩ 和 |111⟩ 的振幅非零")
3.2 量子线路(QubitCircuit)¶
量子线路是 DeepQuantum 的核心对象,用于构建和执行量子算法。
In [ ]:
Copied!
# 创建一个 3 量子比特的量子线路
cir = dq.QubitCircuit(3)
print(f"量子比特数: {cir.nqubit}")
print(f"初始状态: {cir.init_state.state.squeeze()}")
print(f"\n量子线路是一个 PyTorch 模块:\n{cir}")
# 创建一个 3 量子比特的量子线路
cir = dq.QubitCircuit(3)
print(f"量子比特数: {cir.nqubit}")
print(f"初始状态: {cir.init_state.state.squeeze()}")
print(f"\n量子线路是一个 PyTorch 模块:\n{cir}")
In [ ]:
Copied!
# 创建单比特量子门
x_gate = dq.PauliX() # X 门(NOT 门)
h_gate = dq.Hadamard() # Hadamard 门
rx_gate = dq.Rx(torch.tensor(np.pi/2)) # 绕 X 轴旋转 π/2
print("Pauli X 门矩阵:")
print(x_gate.matrix)
print("\nHadamard 门矩阵:")
print(h_gate.matrix)
print("\nRx(π/2) 门矩阵:")
print(rx_gate.matrix)
# 创建单比特量子门
x_gate = dq.PauliX() # X 门(NOT 门)
h_gate = dq.Hadamard() # Hadamard 门
rx_gate = dq.Rx(torch.tensor(np.pi/2)) # 绕 X 轴旋转 π/2
print("Pauli X 门矩阵:")
print(x_gate.matrix)
print("\nHadamard 门矩阵:")
print(h_gate.matrix)
print("\nRx(π/2) 门矩阵:")
print(rx_gate.matrix)
In [ ]:
Copied!
# 对量子态应用量子门
state = dq.QubitState(nqubit=1, state=[0, 1]) # 初始态 |1⟩
print("初始态 |1⟩:")
print(state.state)
# 应用 X 门(将 |1⟩ 变为 |0⟩)
x_state = x_gate(state.state)
print("\n应用 X 门后的态 |0⟩:")
print(x_state)
# 应用 Hadamard 门(创建叠加态)
h_state = h_gate(state.state)
print("\n对 |1⟩ 应用 H 门后的态 (|0⟩ - |1⟩)/√2:")
print(h_state)
# 对量子态应用量子门
state = dq.QubitState(nqubit=1, state=[0, 1]) # 初始态 |1⟩
print("初始态 |1⟩:")
print(state.state)
# 应用 X 门(将 |1⟩ 变为 |0⟩)
x_state = x_gate(state.state)
print("\n应用 X 门后的态 |0⟩:")
print(x_state)
# 应用 Hadamard 门(创建叠加态)
h_state = h_gate(state.state)
print("\n对 |1⟩ 应用 H 门后的态 (|0⟩ - |1⟩)/√2:")
print(h_state)
4.2 双比特量子门¶
- CNOT 门:受控非门(CX)
- SWAP 门:交换两个量子比特的状态
- 旋转门:Rxx, Ryy, Rzz 等双比特旋转门
In [ ]:
Copied!
# CNOT 门示例:制备贝尔态
cir = dq.QubitCircuit(2)
cir.h(0) # 在第 0 个量子比特上应用 H 门
cir.cnot(0, 1) # CNOT,控制位为 0,目标位为 1
# 执行线路
final_state = cir()
print("贝尔态 (|00⟩ + |11⟩)/√2:")
print(final_state)
print("\n验证:只有 |00⟩ 和 |11⟩ 的振幅非零且相等")
# CNOT 门示例:制备贝尔态
cir = dq.QubitCircuit(2)
cir.h(0) # 在第 0 个量子比特上应用 H 门
cir.cnot(0, 1) # CNOT,控制位为 0,目标位为 1
# 执行线路
final_state = cir()
print("贝尔态 (|00⟩ + |11⟩)/√2:")
print(final_state)
print("\n验证:只有 |00⟩ 和 |11⟩ 的振幅非零且相等")
In [ ]:
Copied!
# 双比特旋转门示例
cir = dq.QubitCircuit(2)
cir.rxx([0, 1], torch.tensor(np.pi/4)) # XX 旋转 π/4
print("Rxx(π/4) 门的酉矩阵:")
print(cir.operators[0].gates[0].get_unitary())
# 双比特旋转门示例
cir = dq.QubitCircuit(2)
cir.rxx([0, 1], torch.tensor(np.pi/4)) # XX 旋转 π/4
print("Rxx(π/4) 门的酉矩阵:")
print(cir.operators[0].gates[0].get_unitary())
4.3 多比特量子门¶
- Toffoli 门:受控-受控-非门(CCX)
- Fredkin 门:受控-SWAP 门
In [ ]:
Copied!
# Toffoli 门(CCX)示例
cir = dq.QubitCircuit(3)
cir.x(0) # 将第 0 个量子比特置为 |1⟩
cir.x(1) # 将第 1 个量子比特置为 |1⟩
cir.toffoli(0, 1, 2) # 控制位为 0 和 1,目标位为 2
final_state = cir()
print("Toffoli 门示例:")
print("初始态: |110⟩")
print("最终态:")
print(final_state)
print("\n当两个控制位都为 1 时,目标位翻转")
# Toffoli 门(CCX)示例
cir = dq.QubitCircuit(3)
cir.x(0) # 将第 0 个量子比特置为 |1⟩
cir.x(1) # 将第 1 个量子比特置为 |1⟩
cir.toffoli(0, 1, 2) # 控制位为 0 和 1,目标位为 2
final_state = cir()
print("Toffoli 门示例:")
print("初始态: |110⟩")
print("最终态:")
print(final_state)
print("\n当两个控制位都为 1 时,目标位翻转")
In [ ]:
Copied!
# 创建一个简单的量子电路
cir = dq.QubitCircuit(3)
# 添加量子门
cir.h(0) # 在第 0 个量子比特上添加 H 门
cir.x(1) # 在第 1 个量子比特上添加 X 门
cir.y(2) # 在第 2 个量子比特上添加 Y 门
# 执行电路
final_state = cir()
print("最终量子态:")
print(final_state)
# 创建一个简单的量子电路
cir = dq.QubitCircuit(3)
# 添加量子门
cir.h(0) # 在第 0 个量子比特上添加 H 门
cir.x(1) # 在第 1 个量子比特上添加 X 门
cir.y(2) # 在第 2 个量子比特上添加 Y 门
# 执行电路
final_state = cir()
print("最终量子态:")
print(final_state)
5.2 制备 GHZ 态¶
In [ ]:
Copied!
# 制备 GHZ 态:(|000⟩ + |111⟩)/√2
cir = dq.QubitCircuit(3)
cir.h(0) # 在第 0 个量子比特上创建叠加态
cir.cnot(0, 1) # 纠缠第 0 和第 1 个量子比特
cir.cnot(0, 2) # 纠缠第 0 和第 2 个量子比特
final_state = cir()
print("GHZ 态:")
print(final_state)
print("\n验证:只有 |000⟩ 和 |111⟩ 的振幅非零且相等")
# 制备 GHZ 态:(|000⟩ + |111⟩)/√2
cir = dq.QubitCircuit(3)
cir.h(0) # 在第 0 个量子比特上创建叠加态
cir.cnot(0, 1) # 纠缠第 0 和第 1 个量子比特
cir.cnot(0, 2) # 纠缠第 0 和第 2 个量子比特
final_state = cir()
print("GHZ 态:")
print(final_state)
print("\n验证:只有 |000⟩ 和 |111⟩ 的振幅非零且相等")
5.3 量子电路可视化¶
In [ ]:
Copied!
# 可视化 GHZ 态制备线路
cir = dq.QubitCircuit(3)
cir.h(0)
cir.cnot(0, 1)
cir.cnot(0, 2)
cir.barrier() # 添加屏障(可视化辅助线)
# 绘制量子电路
cir.draw()
# 可视化 GHZ 态制备线路
cir = dq.QubitCircuit(3)
cir.h(0)
cir.cnot(0, 1)
cir.cnot(0, 2)
cir.barrier() # 添加屏障(可视化辅助线)
# 绘制量子电路
cir.draw()
In [ ]:
Copied!
# 更复杂的量子电路
cir = dq.QubitCircuit(4)
# 第一层:Hadamard 层
cir.hlayer()
cir.barrier()
# 第二层:参数化旋转
cir.rx(0, torch.tensor(np.pi/4))
cir.ry(1, torch.tensor(np.pi/3))
cir.rz(2, torch.tensor(np.pi/6))
cir.barrier()
# 第三层:纠缠层
cir.cnot_ring() # 将量子比特连接成环状
cir.barrier()
# 第四层:再次旋转
cir.rxlayer()
cir.barrier()
# 可视化
cir.draw()
# 更复杂的量子电路
cir = dq.QubitCircuit(4)
# 第一层:Hadamard 层
cir.hlayer()
cir.barrier()
# 第二层:参数化旋转
cir.rx(0, torch.tensor(np.pi/4))
cir.ry(1, torch.tensor(np.pi/3))
cir.rz(2, torch.tensor(np.pi/6))
cir.barrier()
# 第三层:纠缠层
cir.cnot_ring() # 将量子比特连接成环状
cir.barrier()
# 第四层:再次旋转
cir.rxlayer()
cir.barrier()
# 可视化
cir.draw()
In [ ]:
Copied!
# 创建参数化电路
cir = dq.QubitCircuit(4)
# 添加参数化旋转门(不指定参数,会自动初始化)
cir.rx(0) # 在第 0 个量子比特上添加 Rx 门
cir.ry(1) # 在第 1 个量子比特上添加 Ry 门
cir.rz(2) # 在第 2 个量子比特上添加 Rz 门
# 添加参数化双比特门
cir.rxx([1, 2]) # 在量子比特 1 和 2 上添加 Rxx 门
# 打印电路参数
print("参数化电路结构:")
print(cir)
# 查看参数值
print("\n参数化门的参数:")
for name, param in cir.named_parameters():
if 'theta' in name or 'phi' in name:
print(f" {name}: {param.item():.4f}")
# 创建参数化电路
cir = dq.QubitCircuit(4)
# 添加参数化旋转门(不指定参数,会自动初始化)
cir.rx(0) # 在第 0 个量子比特上添加 Rx 门
cir.ry(1) # 在第 1 个量子比特上添加 Ry 门
cir.rz(2) # 在第 2 个量子比特上添加 Rz 门
# 添加参数化双比特门
cir.rxx([1, 2]) # 在量子比特 1 和 2 上添加 Rxx 门
# 打印电路参数
print("参数化电路结构:")
print(cir)
# 查看参数值
print("\n参数化门的参数:")
for name, param in cir.named_parameters():
if 'theta' in name or 'phi' in name:
print(f" {name}: {param.item():.4f}")
6.1 使用层操作¶
In [ ]:
Copied!
# 使用层操作快速构建电路
cir = dq.QubitCircuit(4)
# Hadamard 层(在所有量子比特上应用 H 门)
cir.hlayer()
# Rx 层(在所有量子比特上添加 Rx 门)
cir.rxlayer()
# CNOT 环(将量子比特连接成环状)
cir.cnot_ring()
# 可视化
cir.draw()
# 使用层操作快速构建电路
cir = dq.QubitCircuit(4)
# Hadamard 层(在所有量子比特上应用 H 门)
cir.hlayer()
# Rx 层(在所有量子比特上添加 Rx 门)
cir.rxlayer()
# CNOT 环(将量子比特连接成环状)
cir.cnot_ring()
# 可视化
cir.draw()
6.2 指定自定义参数¶
In [ ]:
Copied!
# 指定参数值
theta = torch.tensor(np.pi/3, requires_grad=True)
phi = torch.tensor(np.pi/4, requires_grad=True)
cir = dq.QubitCircuit(2)
cir.rx(0, theta) # 指定参数 theta
cir.ry(1, phi) # 指定参数 phi
cir.cnot(0, 1)
print(f"Rx 参数 theta: {theta.item():.4f} rad")
print(f"Ry 参数 phi: {phi.item():.4f} rad")
# 执行线路
state = cir()
print("\n最终量子态:")
print(state)
# 指定参数值
theta = torch.tensor(np.pi/3, requires_grad=True)
phi = torch.tensor(np.pi/4, requires_grad=True)
cir = dq.QubitCircuit(2)
cir.rx(0, theta) # 指定参数 theta
cir.ry(1, phi) # 指定参数 phi
cir.cnot(0, 1)
print(f"Rx 参数 theta: {theta.item():.4f} rad")
print(f"Ry 参数 phi: {phi.item():.4f} rad")
# 执行线路
state = cir()
print("\n最终量子态:")
print(state)
In [ ]:
Copied!
# 制备贝尔态并测量
cir = dq.QubitCircuit(2)
cir.h(0)
cir.cnot(0, 1)
# 执行测量(默认 1024 次)
measurement_results = cir.measure(shots=1000)
print("测量结果(1000 次采样):")
for bitstring, count in sorted(measurement_results.items()):
print(f" |{bitstring}⟩: {count} 次 ({count/10:.1f}%)")
print("\n贝尔态的测量结果应该近似 50% |00⟩ 和 50% |11⟩")
# 制备贝尔态并测量
cir = dq.QubitCircuit(2)
cir.h(0)
cir.cnot(0, 1)
# 执行测量(默认 1024 次)
measurement_results = cir.measure(shots=1000)
print("测量结果(1000 次采样):")
for bitstring, count in sorted(measurement_results.items()):
print(f" |{bitstring}⟩: {count} 次 ({count/10:.1f}%)")
print("\n贝尔态的测量结果应该近似 50% |00⟩ 和 50% |11⟩")
7.2 部分测量¶
In [ ]:
Copied!
# 部分测量和概率显示
cir = dq.QubitCircuit(3)
cir.h(0)
cir.cnot(0, 1)
cir.cnot(0, 2)
# 只测量前两个量子比特,显示理论概率
results = cir.measure(shots=500, wires=[0, 1], with_prob=True)
print("部分测量结果(量子比特 0 和 1):")
for bitstring, (count, prob) in sorted(results.items()):
print(f" |{bitstring}⟩: {count} 次 (理论概率: {prob:.4f})")
# 部分测量和概率显示
cir = dq.QubitCircuit(3)
cir.h(0)
cir.cnot(0, 1)
cir.cnot(0, 2)
# 只测量前两个量子比特,显示理论概率
results = cir.measure(shots=500, wires=[0, 1], with_prob=True)
print("部分测量结果(量子比特 0 和 1):")
for bitstring, (count, prob) in sorted(results.items()):
print(f" |{bitstring}⟩: {count} 次 (理论概率: {prob:.4f})")
7.3 Observable 和期望值计算¶
在量子计算中,我们经常需要计算某个可观测量(Observable)的期望值。
In [ ]:
Copied!
# 创建电路并添加观测器
cir = dq.QubitCircuit(2)
cir.h(0)
cir.cnot(0, 1)
# 添加观测器(在第 0 个量子比特上测量 Z 算符)
cir.observable(wires=0, basis='z')
# 计算期望值
state = cir()
expectation = cir.expectation()
print(f"Z_0 的期望值: {expectation.item():.4f}")
print("\n对于贝尔态,Z_0 的期望值为 0(因为处于叠加态)")
# 创建电路并添加观测器
cir = dq.QubitCircuit(2)
cir.h(0)
cir.cnot(0, 1)
# 添加观测器(在第 0 个量子比特上测量 Z 算符)
cir.observable(wires=0, basis='z')
# 计算期望值
state = cir()
expectation = cir.expectation()
print(f"Z_0 的期望值: {expectation.item():.4f}")
print("\n对于贝尔态,Z_0 的期望值为 0(因为处于叠加态)")
In [ ]:
Copied!
# 多个观测器
cir = dq.QubitCircuit(3)
cir.hlayer()
cir.cnot_ring()
# 在每个量子比特上添加观测器
for i in range(3):
cir.observable(wires=i, basis='z')
# 计算期望值
state = cir()
expectations = cir.expectation()
print("所有量子比特的 Z 期望值:")
for i, exp in enumerate(expectations[0]):
print(f" Z_{i}: {exp.item():.4f}")
# 多个观测器
cir = dq.QubitCircuit(3)
cir.hlayer()
cir.cnot_ring()
# 在每个量子比特上添加观测器
for i in range(3):
cir.observable(wires=i, basis='z')
# 计算期望值
state = cir()
expectations = cir.expectation()
print("所有量子比特的 Z 期望值:")
for i, exp in enumerate(expectations[0]):
print(f" Z_{i}: {exp.item():.4f}")
In [ ]:
Copied!
# 不同基的测量
cir = dq.QubitCircuit(2)
cir.h(0)
cir.rx(1, torch.tensor(np.pi/4))
# X, Y, Z 基测量
cir.observable(wires=0, basis='x')
cir.observable(wires=0, basis='y')
cir.observable(wires=0, basis='z')
state = cir()
expectations = cir.expectation()
print("不同基的期望值:")
print(f" X: {expectations[0][0].item():.4f}")
print(f" Y: {expectations[0][1].item():.4f}")
print(f" Z: {expectations[0][2].item():.4f}")
# 不同基的测量
cir = dq.QubitCircuit(2)
cir.h(0)
cir.rx(1, torch.tensor(np.pi/4))
# X, Y, Z 基测量
cir.observable(wires=0, basis='x')
cir.observable(wires=0, basis='y')
cir.observable(wires=0, basis='z')
state = cir()
expectations = cir.expectation()
print("不同基的期望值:")
print(f" X: {expectations[0][0].item():.4f}")
print(f" Y: {expectations[0][1].item():.4f}")
print(f" Z: {expectations[0][2].item():.4f}")
In [ ]:
Copied!
# 制备 |Φ⁺⟩ = (|00⟩ + |11⟩)/√2
cir = dq.QubitCircuit(2)
cir.h(0)
cir.cnot(0, 1)
state = cir()
print("|Φ⁺⟩ 态:")
print(state)
# 验证纠缠特性
cir.observable(wires=0, basis='z')
cir.observable(wires=1, basis='z')
expectations = cir.expectation()
print(f"\nZ₀Z₁ 的期望值(纠缠度量): {expectations[0][0].item() * expectations[0][1].item():.4f}")
# 制备 |Φ⁺⟩ = (|00⟩ + |11⟩)/√2
cir = dq.QubitCircuit(2)
cir.h(0)
cir.cnot(0, 1)
state = cir()
print("|Φ⁺⟩ 态:")
print(state)
# 验证纠缠特性
cir.observable(wires=0, basis='z')
cir.observable(wires=1, basis='z')
expectations = cir.expectation()
print(f"\nZ₀Z₁ 的期望值(纠缠度量): {expectations[0][0].item() * expectations[0][1].item():.4f}")
In [ ]:
Copied!
# 制备所有四种贝尔态
def create_bell_state(state_type):
"""创建贝尔态
Args:
state_type: 'phi_plus', 'phi_minus', 'psi_plus', 'psi_minus'
"""
cir = dq.QubitCircuit(2)
if state_type == 'phi_plus':
cir.h(0)
cir.cnot(0, 1)
elif state_type == 'phi_minus':
cir.h(0)
cir.cnot(0, 1)
cir.z(1)
elif state_type == 'psi_plus':
cir.h(0)
cir.x(1)
cir.cnot(0, 1)
elif state_type == 'psi_minus':
cir.h(0)
cir.x(1)
cir.cnot(0, 1)
cir.z(1)
return cir
# 测试所有贝尔态
bell_states = ['phi_plus', 'phi_minus', 'psi_plus', 'psi_minus']
bell_names = ['|Φ⁺⟩', '|Φ⁻⟩', '|Ψ⁺⟩', '|Ψ⁻⟩']
for name, state_type in zip(bell_names, bell_states):
cir = create_bell_state(state_type)
results = cir.measure(shots=1000)
print(f"\n{name} 测量结果:")
for bitstring, count in sorted(results.items()):
if count > 0:
print(f" |{bitstring}⟩: {count} 次")
# 制备所有四种贝尔态
def create_bell_state(state_type):
"""创建贝尔态
Args:
state_type: 'phi_plus', 'phi_minus', 'psi_plus', 'psi_minus'
"""
cir = dq.QubitCircuit(2)
if state_type == 'phi_plus':
cir.h(0)
cir.cnot(0, 1)
elif state_type == 'phi_minus':
cir.h(0)
cir.cnot(0, 1)
cir.z(1)
elif state_type == 'psi_plus':
cir.h(0)
cir.x(1)
cir.cnot(0, 1)
elif state_type == 'psi_minus':
cir.h(0)
cir.x(1)
cir.cnot(0, 1)
cir.z(1)
return cir
# 测试所有贝尔态
bell_states = ['phi_plus', 'phi_minus', 'psi_plus', 'psi_minus']
bell_names = ['|Φ⁺⟩', '|Φ⁻⟩', '|Ψ⁺⟩', '|Ψ⁻⟩']
for name, state_type in zip(bell_names, bell_states):
cir = create_bell_state(state_type)
results = cir.measure(shots=1000)
print(f"\n{name} 测量结果:")
for bitstring, count in sorted(results.items()):
if count > 0:
print(f" |{bitstring}⟩: {count} 次")
8.2 示例 2:参数化量子电路优化¶
In [ ]:
Copied!
# 目标:制备一个特定的目标态 |ψ_target⟩
target_state = torch.tensor([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)],
dtype=torch.complex128).reshape(-1, 1)
print("目标态:")
print(target_state)
# 目标:制备一个特定的目标态 |ψ_target⟩
target_state = torch.tensor([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)],
dtype=torch.complex128).reshape(-1, 1)
print("目标态:")
print(target_state)
In [ ]:
Copied!
# 创建参数化电路
cir = dq.QubitCircuit(2)
cir.ry(0) # 参数 θ₀
cir.ry(1) # 参数 θ₁
cir.cnot(0, 1)
# 定义损失函数(保真度)
def fidelity(circuit, target):
"""计算当前态与目标态的保真度"""
current_state = circuit()
overlap = torch.abs(torch.dot(current_state.flatten().conj(),
target.flatten()))**2
return overlap
# 优化参数
optimizer = torch.optim.Adam(cir.parameters(), lr=0.1)
n_iterations = 50
fidelities = []
print("开始优化...")
for i in range(n_iterations):
optimizer.zero_grad()
# 计算负保真度作为损失
f = fidelity(cir, target_state)
loss = -f
loss.backward()
optimizer.step()
fidelities.append(f.item())
if (i + 1) % 10 == 0:
print(f"迭代 {i+1}/{n_iterations}, 保真度: {f.item():.6f}")
print(f"\n最终保真度: {fidelities[-1]:.6f}")
# 创建参数化电路
cir = dq.QubitCircuit(2)
cir.ry(0) # 参数 θ₀
cir.ry(1) # 参数 θ₁
cir.cnot(0, 1)
# 定义损失函数(保真度)
def fidelity(circuit, target):
"""计算当前态与目标态的保真度"""
current_state = circuit()
overlap = torch.abs(torch.dot(current_state.flatten().conj(),
target.flatten()))**2
return overlap
# 优化参数
optimizer = torch.optim.Adam(cir.parameters(), lr=0.1)
n_iterations = 50
fidelities = []
print("开始优化...")
for i in range(n_iterations):
optimizer.zero_grad()
# 计算负保真度作为损失
f = fidelity(cir, target_state)
loss = -f
loss.backward()
optimizer.step()
fidelities.append(f.item())
if (i + 1) % 10 == 0:
print(f"迭代 {i+1}/{n_iterations}, 保真度: {f.item():.6f}")
print(f"\n最终保真度: {fidelities[-1]:.6f}")
In [ ]:
Copied!
# 可视化优化过程
plt.figure(figsize=(10, 5))
plt.plot(fidelities, linewidth=2)
plt.xlabel('迭代次数', fontsize=12)
plt.ylabel('保真度', fontsize=12)
plt.title('参数优化过程', fontsize=14)
plt.grid(True, alpha=0.3)
plt.show()
# 打印优化后的参数
print("\n优化后的参数:")
for name, param in cir.named_parameters():
if 'theta' in name:
print(f" {name}: {param.item():.4f} rad")
# 可视化优化过程
plt.figure(figsize=(10, 5))
plt.plot(fidelities, linewidth=2)
plt.xlabel('迭代次数', fontsize=12)
plt.ylabel('保真度', fontsize=12)
plt.title('参数优化过程', fontsize=14)
plt.grid(True, alpha=0.3)
plt.show()
# 打印优化后的参数
print("\n优化后的参数:")
for name, param in cir.named_parameters():
if 'theta' in name:
print(f" {name}: {param.item():.4f} rad")
In [ ]:
Copied!
# 验证最终结果
final_state = cir()
print("优化后的量子态:")
print(final_state)
print("\n目标态:")
print(target_state)
# 可视化最终线路
print("\n优化的量子线路:")
cir.draw()
# 验证最终结果
final_state = cir()
print("优化后的量子态:")
print(final_state)
print("\n目标态:")
print(target_state)
# 可视化最终线路
print("\n优化的量子线路:")
cir.draw()
振幅编码¶
振幅编码将数据编码到量子态的振幅中。
In [ ]:
Copied!
# 振幅编码示例
nqubit = 4
batch = 2
data = torch.randn(batch, 2 ** nqubit)
# 构建量子电路
cir = dq.QubitCircuit(nqubit)
cir.rxlayer()
cir.cnot_ring()
cir.observable(wires=0, basis='z')
# 振幅编码
state = cir.amplitude_encoding(data)
state = cir(state=state)
print(f"编码后的量子态形状: {state.shape}")
print(f"归一化系数: {state.norm(dim=-2)}")
# 振幅编码示例
nqubit = 4
batch = 2
data = torch.randn(batch, 2 ** nqubit)
# 构建量子电路
cir = dq.QubitCircuit(nqubit)
cir.rxlayer()
cir.cnot_ring()
cir.observable(wires=0, basis='z')
# 振幅编码
state = cir.amplitude_encoding(data)
state = cir(state=state)
print(f"编码后的量子态形状: {state.shape}")
print(f"归一化系数: {state.norm(dim=-2)}")
角度编码¶
角度编码将数据编码到旋转门的参数中。
In [ ]:
Copied!
# 角度编码示例
nqubit = 4
batch = 2
data = torch.sin(torch.tensor(list(range(batch * nqubit)))).reshape(batch, nqubit)
print("输入数据:")
print(data)
# 构建量子电路(encode=True 表示用于编码)
cir = dq.QubitCircuit(nqubit)
cir.hlayer()
cir.rxlayer(encode=True) # 编码层
cir.cnot_ring()
# 对每个量子比特添加观测器
for i in range(nqubit):
cir.observable(wires=i)
# 角度编码
state = cir(data)
exp = cir.expectation()
print(f"\n编码后的量子态形状: {state.shape}")
print(f"期望值:\n{exp}")
# 角度编码示例
nqubit = 4
batch = 2
data = torch.sin(torch.tensor(list(range(batch * nqubit)))).reshape(batch, nqubit)
print("输入数据:")
print(data)
# 构建量子电路(encode=True 表示用于编码)
cir = dq.QubitCircuit(nqubit)
cir.hlayer()
cir.rxlayer(encode=True) # 编码层
cir.cnot_ring()
# 对每个量子比特添加观测器
for i in range(nqubit):
cir.observable(wires=i)
# 角度编码
state = cir(data)
exp = cir.expectation()
print(f"\n编码后的量子态形状: {state.shape}")
print(f"期望值:\n{exp}")
9.2 VQE(变分量子本征求解器)简介¶
VQE 是一个重要的混合量子-经典算法,用于求解哈密顿量的基态能量。
In [ ]:
Copied!
# 简化的 VQE 示例:求解横向场 Ising 模型的基态
# H = -J * Σ Z_i Z_j - h * Σ X_i
class SimpleVQE(nn.Module):
def __init__(self, nqubit, n_layers):
super().__init__()
self.nqubit = nqubit
self.n_layers = n_layers
# 构建参数化电路
self.cir = dq.QubitCircuit(nqubit)
for _ in range(n_layers):
# 问题哈密顿量对应的参数化门
for i in range(nqubit - 1):
self.cir.rzz([i, i+1], encode=True)
# 混合哈密顿量对应的参数化门
for i in range(nqubit):
self.cir.rx(i, encode=True)
# 添加观测器
for i in range(nqubit):
self.cir.observable(wires=i, basis='z')
def forward(self, params):
"""计算能量"""
self.cir(params)
exp_values = self.cir.expectation()[0]
# 简化:只计算 Z 项的能量
energy = -torch.sum(exp_values)
return energy
# 创建 VQE 模型
nqubit = 4
n_layers = 2
vqe = SimpleVQE(nqubit, n_layers)
# 初始化参数
n_params = n_layers * (2 * nqubit - 1) # 每层的参数数
params = torch.randn(n_params, requires_grad=True)
# 优化
optimizer = torch.optim.Adam([params], lr=0.1)
energies = []
print("VQE 优化过程:")
for i in range(50):
optimizer.zero_grad()
energy = vqe(params)
loss = energy
loss.backward()
optimizer.step()
energies.append(energy.item())
if (i + 1) % 10 == 0:
print(f"迭代 {i+1}/50, 能量: {energy.item():.4f}")
print(f"\n最终能量: {energies[-1]:.4f}")
# 简化的 VQE 示例:求解横向场 Ising 模型的基态
# H = -J * Σ Z_i Z_j - h * Σ X_i
class SimpleVQE(nn.Module):
def __init__(self, nqubit, n_layers):
super().__init__()
self.nqubit = nqubit
self.n_layers = n_layers
# 构建参数化电路
self.cir = dq.QubitCircuit(nqubit)
for _ in range(n_layers):
# 问题哈密顿量对应的参数化门
for i in range(nqubit - 1):
self.cir.rzz([i, i+1], encode=True)
# 混合哈密顿量对应的参数化门
for i in range(nqubit):
self.cir.rx(i, encode=True)
# 添加观测器
for i in range(nqubit):
self.cir.observable(wires=i, basis='z')
def forward(self, params):
"""计算能量"""
self.cir(params)
exp_values = self.cir.expectation()[0]
# 简化:只计算 Z 项的能量
energy = -torch.sum(exp_values)
return energy
# 创建 VQE 模型
nqubit = 4
n_layers = 2
vqe = SimpleVQE(nqubit, n_layers)
# 初始化参数
n_params = n_layers * (2 * nqubit - 1) # 每层的参数数
params = torch.randn(n_params, requires_grad=True)
# 优化
optimizer = torch.optim.Adam([params], lr=0.1)
energies = []
print("VQE 优化过程:")
for i in range(50):
optimizer.zero_grad()
energy = vqe(params)
loss = energy
loss.backward()
optimizer.step()
energies.append(energy.item())
if (i + 1) % 10 == 0:
print(f"迭代 {i+1}/50, 能量: {energy.item():.4f}")
print(f"\n最终能量: {energies[-1]:.4f}")
In [ ]:
Copied!
# 可视化能量收敛过程
plt.figure(figsize=(10, 5))
plt.plot(energies, linewidth=2)
plt.xlabel('迭代次数', fontsize=12)
plt.ylabel('能量', fontsize=12)
plt.title('VQE 能量收敛过程', fontsize=14)
plt.grid(True, alpha=0.3)
plt.show()
# 可视化能量收敛过程
plt.figure(figsize=(10, 5))
plt.plot(energies, linewidth=2)
plt.xlabel('迭代次数', fontsize=12)
plt.ylabel('能量', fontsize=12)
plt.title('VQE 能量收敛过程', fontsize=14)
plt.grid(True, alpha=0.3)
plt.show()
9.3 QAOA(量子近似优化算法)简介¶
QAOA 是另一个重要的混合量子-经典算法,用于求解组合优化问题。
In [ ]:
Copied!
# 简化的 QAOA 示例:最大割问题
class SimpleQAOA(nn.Module):
def __init__(self, nqubit, pairs, coefs, n_layers):
super().__init__()
self.nqubit = nqubit
self.pairs = pairs
self.coefs = torch.tensor(coefs)
self.n_layers = n_layers
# 构建参数化电路
self.cir = dq.QubitCircuit(nqubit)
self.cir.hlayer()
self.cir.barrier()
for _ in range(n_layers):
# 问题哈密顿量(Hp)
for wires in pairs:
self.cir.cnot(wires[0], wires[1])
self.cir.rz(wires[1], encode=True)
self.cir.cnot(wires[0], wires[1])
self.cir.barrier()
# 混合哈密顿量(Hb)
for i in range(nqubit):
self.cir.rx(i, encode=True)
self.cir.barrier()
# 添加观测器
for wires in pairs:
self.cir.observable(wires)
def forward(self, params):
"""计算目标函数"""
self.cir(params)
exp_values = self.cir.expectation()[0]
# 计算目标函数值
cost = torch.sum(self.coefs * exp_values)
return cost
# 定义问题:最大割问题
# 简单示例:4 个节点,5 条边
problem = {
'Z0 Z1': 1.0,
'Z1 Z2': 1.0,
'Z2 Z3': 1.0,
'Z3 Z0': 1.0,
'Z0 Z2': 1.0,
}
# 解析问题
pairs = []
coefs = []
for key, value in problem.items():
temp = []
for item in key.split():
if item[0] == 'Z':
temp.append(int(item[1:]))
if len(temp) == 2:
pairs.append(temp)
coefs.append(value)
print("问题定义:")
print(f"节点对: {pairs}")
print(f"权重: {coefs}")
# 创建 QAOA 模型
nqubit = 4
n_layers = 2
qaoa = SimpleQAOA(nqubit, pairs, coefs, n_layers)
# 初始化参数
n_params = n_layers * (len(pairs) + nqubit)
params = torch.randn(n_params, requires_grad=True)
# 优化
optimizer = torch.optim.Adam([params], lr=0.1)
costs = []
print("\nQAOA 优化过程:")
for i in range(50):
optimizer.zero_grad()
cost = qaoa(params)
loss = -cost # 最大化目标函数
loss.backward()
optimizer.step()
costs.append(cost.item())
if (i + 1) % 10 == 0:
print(f"迭代 {i+1}/50, 目标函数值: {cost.item():.4f}")
print(f"\n最终目标函数值: {costs[-1]:.4f}")
# 简化的 QAOA 示例:最大割问题
class SimpleQAOA(nn.Module):
def __init__(self, nqubit, pairs, coefs, n_layers):
super().__init__()
self.nqubit = nqubit
self.pairs = pairs
self.coefs = torch.tensor(coefs)
self.n_layers = n_layers
# 构建参数化电路
self.cir = dq.QubitCircuit(nqubit)
self.cir.hlayer()
self.cir.barrier()
for _ in range(n_layers):
# 问题哈密顿量(Hp)
for wires in pairs:
self.cir.cnot(wires[0], wires[1])
self.cir.rz(wires[1], encode=True)
self.cir.cnot(wires[0], wires[1])
self.cir.barrier()
# 混合哈密顿量(Hb)
for i in range(nqubit):
self.cir.rx(i, encode=True)
self.cir.barrier()
# 添加观测器
for wires in pairs:
self.cir.observable(wires)
def forward(self, params):
"""计算目标函数"""
self.cir(params)
exp_values = self.cir.expectation()[0]
# 计算目标函数值
cost = torch.sum(self.coefs * exp_values)
return cost
# 定义问题:最大割问题
# 简单示例:4 个节点,5 条边
problem = {
'Z0 Z1': 1.0,
'Z1 Z2': 1.0,
'Z2 Z3': 1.0,
'Z3 Z0': 1.0,
'Z0 Z2': 1.0,
}
# 解析问题
pairs = []
coefs = []
for key, value in problem.items():
temp = []
for item in key.split():
if item[0] == 'Z':
temp.append(int(item[1:]))
if len(temp) == 2:
pairs.append(temp)
coefs.append(value)
print("问题定义:")
print(f"节点对: {pairs}")
print(f"权重: {coefs}")
# 创建 QAOA 模型
nqubit = 4
n_layers = 2
qaoa = SimpleQAOA(nqubit, pairs, coefs, n_layers)
# 初始化参数
n_params = n_layers * (len(pairs) + nqubit)
params = torch.randn(n_params, requires_grad=True)
# 优化
optimizer = torch.optim.Adam([params], lr=0.1)
costs = []
print("\nQAOA 优化过程:")
for i in range(50):
optimizer.zero_grad()
cost = qaoa(params)
loss = -cost # 最大化目标函数
loss.backward()
optimizer.step()
costs.append(cost.item())
if (i + 1) % 10 == 0:
print(f"迭代 {i+1}/50, 目标函数值: {cost.item():.4f}")
print(f"\n最终目标函数值: {costs[-1]:.4f}")
In [ ]:
Copied!
# 可视化目标函数收敛过程
plt.figure(figsize=(10, 5))
plt.plot(costs, linewidth=2)
plt.xlabel('迭代次数', fontsize=12)
plt.ylabel('目标函数值', fontsize=12)
plt.title('QAOA 目标函数收敛过程', fontsize=14)
plt.grid(True, alpha=0.3)
plt.show()
# 测量最终结果
print("\n测量结果(1000 次采样):")
results = qaoa.cir.measure(shots=1000)
for bitstring, count in sorted(results.items(), key=lambda x: -x[1])[:5]:
print(f" {bitstring}: {count} 次")
# 可视化目标函数收敛过程
plt.figure(figsize=(10, 5))
plt.plot(costs, linewidth=2)
plt.xlabel('迭代次数', fontsize=12)
plt.ylabel('目标函数值', fontsize=12)
plt.title('QAOA 目标函数收敛过程', fontsize=14)
plt.grid(True, alpha=0.3)
plt.show()
# 测量最终结果
print("\n测量结果(1000 次采样):")
results = qaoa.cir.measure(shots=1000)
for bitstring, count in sorted(results.items(), key=lambda x: -x[1])[:5]:
print(f" {bitstring}: {count} 次")
10. 总结和资源¶
10.1 本教程总结¶
本教程介绍了 DeepQuantum 框架的核心功能:
- 量子比特和量子线路:使用
QubitState和QubitCircuit创建和管理量子系统 - 基本量子门:单比特门(X, Y, Z, H, Rx, Ry, Rz)、双比特门(CNOT, SWAP, Rxx 等)、多比特门(Toffoli, Fredkin)
- 参数化电路:创建变分量子电路,支持自动微分和优化
- 量子态初始化和测量:多种初始化方式,灵活的测量选项
- Observable 和期望值:计算可观测量期望值,支持多种测量基
- 可视化工具:直观展示量子线路结构
- 量子编码:振幅编码、角度编码等多种编码方式
- 进阶算法:VQE、QAOA 等变分量子算法
10.2 DeepQuantum 的优势¶
- 与 PyTorch 深度集成:支持自动微分、GPU 加速
- 高效的量子模拟:支持 MPS、密度矩阵等多种表示
- 丰富的量子门库:包含所有常用量子门
- 灵活的参数化电路:方便实现变分量子算法
- 强大的可视化:直观展示量子线路
- 分布式计算:支持大规模量子系统模拟
- 光量子计算:支持连续变量量子计算
10.3 下一步学习¶
深入 VQE:学习如何求解真实的量子化学问题
- 教程路径:
教程/01-VQE基础教程/→教程/02-哈密顿量模型系列/→教程/03-分子应用/
- 教程路径:
探索量子机器学习:学习量子神经网络
- 示例:
examples/qresnets.ipynb - 教程:
教程/06-高级应用/量子机器学习入门.ipynb
- 示例:
学习 QAOA:求解组合优化问题
- 示例:
examples/qaoa.ipynb - 教程:
教程/04-量子算法系列/QAOA量子近似优化算法.ipynb
- 示例:
研究量子算法:量子傅里叶变换、HHL 算法等
- 示例:
examples/hhl.ipynb - 教程:
教程/04-量子算法系列/HHL线性方程组求解算法.ipynb
- 示例:
光量子计算:高斯玻色采样、簇态制备
- 教程:
教程/05-光量子计算/高斯玻色采样GBS算法.ipynb - 教程:
教程/04-量子算法系列/MBQC基于测量的量子计算.ipynb
- 教程:
10.4 相关资源¶
项目文档:
E:\02_Projects\turingQ\deepquantum\docs\basics.ipynb- 基础教程mbqc_basics.ipynb- MBQC 基础photonic_basics.ipynb- 光量子基础
示例代码:
E:\02_Projects\turingQ\examples\- VQE、QAOA、QResNets、HHL 等各种算法示例
核心模块:
E:\02_Projects\turingQ\deepquantum\src\deepquantum\circuit.py- 量子线路gate.py- 量子门state.py- 量子态ansatz.py- 绝景(ansatz)电路
教程系列:
E:\02_Projects\turingQ\教程\- 从基础到应用的完整教程路径
10.5 常见问题¶
Q1: 如何选择合适的量子态表示方式?
- 态矢(State Vector):适用于小规模量子系统(< 20 量子比特)
- 密度矩阵(Density Matrix):适用于需要考虑噪声和纠缠的系统
- 矩阵乘积态(MPS):适用于大规模但纠缠度较低的系统
Q2: 如何提高量子模拟的效率?
- 使用 GPU 加速:
device='cuda' - 使用 MPS 表示:
mps=True - 使用批处理:一次性处理多个量子态
- 使用分布式计算:
DistributedQubitCircuit
Q3: 如何设计好的参数化电路?
- 选择合适的 ansatz(硬件高效 ansatz 或问题自适应 ansatz)
- 避免梯度过小或过大(贫瘠高原问题)
- 考虑电路的纠缠能力
- 使用层结构(旋转层 + 纠缠层)
10.6 结语¶
DeepQuantum 是一个功能强大的量子计算框架,适用于从量子计算基础学习到前沿量子算法研究。通过本教程,你应该已经掌握了 DeepQuantum 的核心概念和基本使用方法。
继续探索和实践,你将能够使用 DeepQuantum 解决各种量子计算问题,从量子化学模拟到量子机器学习,从组合优化到量子算法研究。
祝你在量子计算的旅程中收获满满!