QPanda3
Supported by OriginQ
载入中...
搜索中...
未找到
v0.1.0

量子门(QGate)

前言(Prelude)

在经典计算中,最基本的单位是比特,而最基本的控制方式是逻辑门。我们可以通过组合逻辑门来实现线路控制。同样,在量子计算中,我们通过量子逻辑门来操控量子比特(qubits)。 pyqpanda3 提供了一种更简洁、轻量级的方法来构建和使用量子逻辑门。

变更(Changes)

  • 优化空间占用

    在 pyqpanda 中,量子逻辑门存储自己的矩阵形式,这会在生成超大规模量子线路时占用大量内存空间。而在 pyqpanda3 中,量子门的矩阵是在运行时获取的,从而有效减少了内存占用。

from pyqpanda3.core import H
h_gate = H(1)
# 运行时获取矩阵
matrix = h_gate.matrix()
定义 __init__.py:1

新特性(New Features)

  • 简化量子门的构建与初始化流程

    在大多数场景下,我们只需要知道逻辑门的类型和作用比特的索引就可以构建量子逻辑门。而在 pyqpanda 中,我们需要提前申请比特。

from pyqpanda import CPUQVM, H, CNOT
qvm = CPUQVM()
qvm.init_qvm()
qvm.set_configure(29, 29)
qubits = qvm.qAlloc_many(4)
cbits = qvm.cAlloc_many(4)
h_gate = H(qubits[0])
cnot_gate = CNOT(qubits[0], qubits[1])

pyqpanda3 中,这一过程被大幅简化:

from pyqpanda3.core import QCircuit, H, CNOT, RX, CP
circuit = QCircuit(2)
circuit << H(0)
circuit << CNOT(0, 1)
circuit << RX(0, 3.9)
circuit << RX(0, 1.2)
circuit << RX(0, 5.6)
circuit << CP(0, 1, 4.9)
  • 存储和空间优化

    与 pyqpanda 相比,pyqpanda3 对量子逻辑门的信息存储进行了优化,降低了内存占用,在构建大规模量子线路时可有效减少 70% 以上的空间使用。

  • 更丰富、简洁的开发接口
    • 获取量子逻辑门的信息和参数
from pyqpanda3.core import H
h_gate = H(1)
# 获取量子门的类型
gate_type = h_gate.gate_type()
# 获取量子门作用的比特
qubits = h_gate.qubits()
# 获取量子门的参数
parameters = h_gate.parameters()
# 获取量子门的控制比特
control_qubits = h_gate.control_qubits()
# 获取量子门的作用比特数量
qubits_num = h_gate.qubits_num()
# 获取量子门矩阵
matrix = h_gate.matrix()
# 获取该门的共轭转置(Dagger)
h_dag_gate = h_gate.dagger()
  • 简化不必要的量子逻辑门类型

    pyqpanda 具有许多容易引起误导的重复量子逻辑门。在之前的版本中,我们支持以下类型的逻辑门:

class GateType:
GATE_NOP
GATE_UNDEFINED
P0_GATE
P1_GATE
PAULI_X_GATE
PAULI_Y_GATE
PAULI_Z_GATE
X_HALF_PI
Y_HALF_PI
Z_HALF_PI
HADAMARD_GATE
T_GATE
S_GATE
P_GATE
CP_GATE
RX_GATE
RY_GATE
RZ_GATE
RXX_GATE
RYY_GATE
RZZ_GATE
RZX_GATE
U1_GATE
U2_GATE
U3_GATE
U4_GATE
CU_GATE
CNOT_GATE
CZ_GATE
MS_GATE
CPHASE_GATE
ISWAP_THETA_GATE
ISWAP_GATE
SQISWAP_GATE
SWAP_GATE
TWO_QUBIT_GATE
P00_GATE
P11_GATE
TOFFOLI_GATE
ORACLE_GATE
I_GATE
BARRIER_GATE
RPHI_GATE

pyqpanda3 已完成简化和优化。

class GateType:
BARRIER
CNOT
CP
CU
CZ
H
I
ISWAP
ORACLE
P
RPHI
RX
RXX
RY
RYY
RZ
RZX
RZZ
S
SQISWAP
SWAP
SX
T
TOFFOLI
U1
U2
U3
U4
X
X1
Y
Y1
Z
Z1

量子线路与量子程序(Circuit & QProg)

前言(Prelude)

量子线路和量子程序是量子计算领域的重要模型,用于描述和研究量子算法及量子计算机的运行过程。它们是一种图形化表示方法,展示了量子比特(qubits)之间的操作和交互,类似于经典计算中的线路图。

变更(Changes)

  • 量子程序与 OriginIR 之间的转换更加便捷和用户友好

    在 pyqpanda 中,量子程序与 OriginIR 之间的转换需要通过独立的外部接口进行。

from pyqpanda import *
if __name__ == "__main__":
machine = CPUQVM()
machine.init_qvm()
qlist = machine.qAlloc_many(4)
clist = machine.cAlloc_many(4)
prog = QProg()
prog_cir = QCircuit()
prog_cir << Y(qlist[2]) << H(qlist[2]) << CNOT(qlist[0],qlist[1])
prog << H(qlist[2]) << Measure(qlist[1],clist[1])
print(convert_qprog_to_originir(prog,machine))

pyqpanda3 中,这一功能直接通过量子程序的成员函数实现,无需依赖独立的外部接口。

from pyqpanda3.core import QProg
if __name__ == "__main__":
originir_str = """
QINIT 3
CREG 2
H q[2]
H q[0]
H q[1]
CONTROL q[1]
RX q[2],(-3.141593)
ENDCONTROL
CONTROL q[0]
RX q[2],(-3.141593)
RX q[2],(-3.141593)
ENDCONTROL
DAGGER
H q[1]
// CR q[0],q[1],(1.570796)
H q[0]
ENDDAGGER
MEASURE q[0],c[0]
MEASURE q[1],c[1]
"""
prog = QProg(originir_str)

示例用法(Example Usage):

# 导入 QCircuit 类
from pyqpanda3.core import QCircuit, H, CNOT
# 创建一个包含 2 个量子比特的量子线路
circuit = QCircuit(2)
# 向线路中添加量子门
circuit << H(0) # 在量子比特 0 上应用 Hadamard 门
circuit << CNOT(0, 1) # 以 0 号比特为控制,1 号比特为目标,应用 CNOT 门
from pyqpanda3.core import QProg,H,CNOT,measure,CPUQVM,draw_qprog
prog = QProg()
prog << H(0)
for i in range(1, 5):
prog << CNOT(i - 1, i)
for i in range(5):
prog << measure(i, i)
qvm = CPUQVM()
qvm.run(prog, 1024)
qvm.result().get_prob_list()
qvm.result().get_prob_dict()

新特性(New Features)

  • 底层数据结构优化

    在 pyqpanda 中,我们使用链表(linked lists)存储内部量子操作节点。而在 pyqpanda3 中,我们通过顺序容器(sequential containers)对该方法进行了优化。

特性/场景 量子程序顺序容器(std::vector) 量子程序链表(std::list, std::forward_list)
内存布局 连续的内存分配,提高缓存命中率和访问效率 分散的内存分配,缓存命中率低,访问速度慢
随机访问效率 支持 O(1) 级别的随机访问,例如 QCircuit[i] 不支持随机访问,需要从头遍历,访问复杂度为 O(n)
遍历性能 支持高效遍历,连续内存分配使得遍历效率高,复杂度为 O(n) 遍历效率较低,分散的内存分配及指针操作增加额外开销
内存使用 需要额外的空间管理(如动态扩展时),但整体内存开销较小 每个节点需要额外存储指针,导致更高的内存开销
稳定性(指针或引用) 插入或删除元素可能导致指针或引用失效(如 std::vector 可能会重新分配内存) 插入/删除元素不会使指向其他元素的指针或引用失效

总体而言,量子程序涉及大量遍历和空间分配,因此使用顺序容器可以提高整体系统效率。

  • 丰富的其他成员函数接口
from pyqpanda3.core import QProg, QCircuit, H, RY, RX, CNOT
circuit = QCircuit(3)
circuit << H(0)
circuit << RY(1, 0.3)
circuit << RY(2, 2.7)
circuit << RX(0, 1.5)
circuit << CNOT(0, 1)
circuit << CNOT(1, 2)
prog = QProg()
# append nodes
prog << circuit
# get depth
depth = prog.depth()

模拟器(Simulator)

前言(Prelude)

模拟器用于模拟量子计算线路的演化过程,包括理想状态下的量子系统以及含噪声的模拟。在最新的 pyqpanda3 版本中,目前支持六种类型的虚拟机,包括全振幅模拟器、单振幅模拟器、密度矩阵模拟器、Clifford 线路模拟器,以及含噪声的模拟器。相比 pyqpanda,我们移除了多个冗余接口,使其使用方式更加统一。

新特性(New Features)

  • 初始化过程简化

    在 pyqpanda 的量子模拟器代码中,比特的申请与释放、量子线路的构建以及虚拟机的绑定是集成在一起的。例如:

from pyqpanda import *
qvm = CPUQVM()
qvm.init_qvm()
qvm.set_configure(29, 29)
qubits = qvm.qAlloc_many(4)
cbits = qvm.cAlloc_many(4)
prog = QProg()
prog << H(qubits[0]) << CNOT(qubits[0], qubits[1]) << Measure(qubits[0], cbits[0])

pyqpanda3 中,实现了完全解耦,并移除了显式的初始化配置。

  • 移除全局虚拟机函数及其使用方式:
from pyqpanda import *
init(QMachineType.CPU)
machine = init_quantum_machine(QMachineType.CPU)

在上述 pyqpanda 代码中,全局使用的虚拟机及其初始化方法已被弃用。

  • 噪声模型配置和使用的优化

    噪声模型用于在量子线路计算任务中模拟真实环境的噪声影响。在 pyqpanda 中,设置噪声参数需要一个复杂的噪声模型,且噪声模型与噪声误差没有解耦。

from pyqpanda import *
noise = Noise()
noise.add_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR, GateType.PAULI_X_GATE, 0.1)
qv0 = [q[0], q[1]]
noise.add_noise_model(NoiseModel.DEPHASING_KRAUS_OPERATOR, GateType.HADAMARD_GATE, 0.1, qv0)
qves = [[q[0], q[1]], [q[1], q[2]]]
noise.add_noise_model(NoiseModel.DAMPING_KRAUS_OPERATOR, GateType.CNOT_GATE, 0.1, qves)
f0 = 0.9
f1 = 0.85
noise.set_readout_error([[f0, 1 - f0], [1 - f1, f1]])
noise.set_rotation_error(0.05)

pyqpanda3 中,噪声误差和噪声模型被解耦。

from pyqpanda3.core import pauli_x_error, NoiseModel, GateType, depolarizing_error, phase_damping_error
pauli_error = pauli_x_error(0.6)
model = NoiseModel()
model.add_all_qubit_quantum_error(pauli_error, GateType.RX)
model.add_all_qubit_quantum_error(depolarizing_error(0.9), GateType.RX)
model.add_all_qubit_quantum_error(phase_damping_error(0.9), GateType.RX)
  • 运行模拟器和获取结果的接口已简化 。详细参考以下代码示例:
    • (1)全振幅模拟器(Full Amplitude)
      pyqpanda3 中,全振幅模拟和噪声模拟已合并到一个模拟器中,采用统一的 run 方法执行,噪声模型作为可选参数。
from pyqpanda3.core import QCircuit, H, RY, RX, CNOT, QProg, measure, NoiseModel, CPUQVM
from pyqpanda3.core import pauli_x_error, GateType
circuit = QCircuit(3)
circuit << H(0)
circuit << RY(1, 0.3)
circuit << RY(2, 2.7)
circuit << RX(0, 1.5)
circuit << CNOT(0, 1)
circuit << CNOT(1, 2)
prog = QProg()
prog << circuit
prog << measure(0, 0)
prog << measure(1, 1)
prog << measure(2, 2)
model = NoiseModel()
model.add_all_qubit_quantum_error(pauli_x_error(0.5), GateType.RX)
machine = CPUQVM()
machine.run(prog, 1000, model)
measure_result = machine.result().get_counts()
  • 部分振幅模拟器(Partial Amplitude)
from pyqpanda3.core import QCircuit, H, RY, RX, CNOT, QProg
from pyqpanda3.core import PartialAmplitudeQVM
circuit = QCircuit(3)
circuit << H(0)
circuit << RY(1, 0.3)
circuit << RY(2, 2.7)
circuit << RX(0, 1.5)
circuit << CNOT(0, 1)
circuit << CNOT(1, 2)
prog = QProg()
prog << circuit
machine = PartialAmplitudeQVM()
machine.run(prog)
measure_result = machine.get_state_vector(["0", "1", "2"])
  • 密度矩阵模拟器(Density Matrix Simulator)
    from pyqpanda3.core import QCircuit,H,RX,CNOT,QProg,GateType
    from pyqpanda3.core import DensityMatrixSimulator,pauli_x_error,NoiseModel,depolarizing_error
    circuit = QCircuit(2)
    circuit << H(0)
    circuit << CNOT(0, 1)
    circuit << RX(0, 3.9)
    circuit << RX(0, 1.2)
    circuit << RX(0, 5.6)
    prog = QProg()
    prog << circuit
    machine = DensityMatrixSimulator()
    machine.run(prog)
    density_matrix = machine.density_matrix()
    pauli_error = pauli_x_error(0.6)
    model = NoiseModel()
    model.add_all_qubit_quantum_error(pauli_error,GateType.RX)
    model.add_all_qubit_quantum_error(depolarizing_error(0.9),GateType.RX)
    machine.run(prog, model)
    density_matrix = machine.density_matrix()

稳定器模拟器

稳定器用于模拟仅包含 H、X、Y、Z、CNOT、S、CNOT、CZ 量子门的 Clifford 量子线路。最大可模拟超过 5000 个量子比特。

from pyqpanda3.core import QProg,measure,random_qcircuit,Stabilizer
prog = QProg()
prog << random_qcircuit([0,1,2,3,4,5 ], 20, ["H","X","Y","Z","S","CZ","CNOT","SWAP"])
prog << measure(0,0)
prog << measure(1,1)
prog << measure(2,2)
machine = Stabilizer()
machine.run(prog,1000)
measure_result = machine.result().get_counts()

中间编译器

前言

pyqpanda3 优化了量子程序转换的实现方式。它用逐行扫描的方法替换了 pyqpanda 中使用的跨语言语法解析器 Antlr4,从而使整体执行效率提高了五倍。

此外,pyqpanda3 还支持对量子程序中的注释进行解析。

新特性

中间编译器模块提供了一个接口,支持将 OriginIR 格式的指令集字符串转换为量子程序(QProg)。

from pyqpanda3.intermediate_compiler import convert_originir_string_to_qprog
prog = convert_originir_string_to_qprog(originir_str)

中间编译器模块提供了一个接口,支持将包含 OriginIR 指令集字符串的文本文件转换为量子程序(QProg)。

from pyqpanda3.intermediate_compiler import convert_originir_file_to_qprog
prog = convert_originir_file_to_qprog(originir_file_path)

中间编译器模块提供了一个接口,支持将 OpenQASM 格式的指令集字符串转换为量子程序(QProg)。

from pyqpanda3.intermediate_compiler import convert_qasm_string_to_qprog
prog = convert_qasm_string_to_qprog(qasm_str)

中间编译器模块提供了一个接口,支持将包含 OpenQASM 指令集字符串的文本文件转换为量子程序(QProg)。

from pyqpanda3.intermediate_compiler import convert_qasm_file_to_qprog
prog = convert_qasm_file_to_qprog(qasm_file_path)

中间编译器模块提供了一个接口,支持将量子程序(QProg)转换为 OriginIR 格式的指令集字符串。

from pyqpanda3.intermediate_compiler import convert_qprog_to_originir
convert_str = convert_qprog_to_originir(prog)

可以看出,在 pyqpanda3 翻译 QProg 接口定义中,参数列表去除了旧版本用于转换的 QuantumMachine 类型参数,而仅使用指令集字符串或量子程序文件路径字符串作为转换参数。此外,返回值不再是包含 QProg 对象、量子比特和经典比特的列表,而仅仅是 QProg 对象。

哈密顿量

前言

在最新版本中,pyqpanda3 支持使用 qpanda2 风格和 qiskit 风格的参数形式或 PauliOperator 对象,直接构造 Hamiltonian 类对象。Hamiltonian 类对象支持加法、减法、标量乘法、乘法、张量积以及混合运算,并且支持通过省略 "I" 或省略量子比特索引字符串来显示对象的主要信息。

新特性

Hamiltonian 支持直接使用 PauliOperator 的参数构造哈密顿量对象。
构造哈密顿量时,不再需要先构造 Pauli 算符再构造哈密顿量:

H2 = Hamiltonian({"Z0 I1": 1})
Ham = Hamiltonian([("XXZ", [0, 1, 4], 1 + 2j), ("ZZ", [1, 2], -1 + 1j)] )

Hamiltonian 支持加法、减法、标量乘法、乘法和张量积的混合运算:

H1 = Hamiltonian({"X0 Y1":1})
H2 = Hamiltonian({"X0 Y1": 2})
H3 = H1+H2
H1 = Hamiltonian({"X0 Y1":1})
H2 = Hamiltonian({"X0 Y1": 2})
H3 = H1-H2
H1 = Hamiltonian({"X0 Y1":1})
H2 = Hamiltonian({"X0 Y1": 2})
H3 = H1*H2
H1 = Hamiltonian({"X0 Y1":1})
H3 = (3.3+1.j) * H1
H4 = H1*(4.4+1.j)
H1 = Hamiltonian({"X0 Y1":1})
H2 = Hamiltonian({"X0 Y1": 2})
H3 = H1.tensor(H2)

Hamiltonian 支持以省略 "I" 模式打印相应的字符串。

from pyqpanda3.hamiltonian import Hamiltonian
Ham = Hamiltonian({"X0 Z1":2,"X1 Y2":3})
print("without I:\n",Ham)
定义 __init__.py:1

输出:

without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }

Hamiltonian 支持省略量子比特索引来打印相应的字符串。

from pyqpanda3.hamiltonian import Hamiltonian
Ha = Hamiltonian({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", Ha)
print("with I:\n", Ha.str_with_I(True))

输出:

without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
with I:
{ qbit_totql = 3, paulis = [ 'IZX', 'YXI', ], coefs = [ 2 + 0j, 3 + 0j, ] }

算符(Operator)

前言

在最新版本中,pyqpanda3 支持使用 qpanda2 风格和 qiskit 风格的参数形式直接构造 PauliOperator 对象。PauliOperator 类对象支持加法、减法、标量乘法、乘法、张量积及其混合运算,并支持通过省略 "I" 或省略量子比特索引字符串来显示对象的主要信息。

变更

使用 PauliOperator 类提供对基本泡利算符及其组合的统一模拟。

op = PauliOperator("X")
op = PauliOperator("Y")
op = PauliOperator("Z")
op = PauliOperator("I")
H1 = PauliOperator({"X0 Y1":1})

新特性

PauliOperator 支持 qiskit 风格的构造方法。

# op 表示对量子系统应用 "X0 X1 Z4",系数为 1+2.j,同时应用 "Z1 Z2",系数为 -1+1.j
op = PauliOperator([("XXZ", [0, 1, 4], 1 + 2j), ("ZZ", [1, 2], -1 + 1j)] )

PauliOperator 支持张量积运算。

H1 = PauliOperator({"X0 Y1":1})
H2 = PauliOperator({"X0 Y1":1})
H3 = H1.tensor(H2)

PauliOperator 支持标量乘法。

H1 = PauliOperator({"X0 Y1":1})
H3 = (3.3+1.j) * H1

PauliOperator 支持加法、减法、标量乘法、乘法和张量积的混合运算。

PauliOperator 支持省略 "I" 来打印相应的字符串。

PauliOperator 支持省略量子比特索引来打印相应的字符串。

from pyqpanda3.hamiltonian import PauliOperator
Ha = PauliOperator({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", Ha)
print("with I:\n", Ha.str_with_I(True))

输出:

without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
with I:
{ qbit_totql = 3, paulis = [ 'IZX', 'YXI', ], coefs = [ 2 + 0j, 3 + 0j, ] }

性能分析模块(Profiling Module)

前言

性能分析模块旨在直观地呈现量子程序的信息。它通过两种方法分析量子程序,并通过可视化方式向用户展示分析结果。

新特性

  • draw_circuit_profile:此函数分析量子程序,输出量子程序及其子程序的执行时间,以及各个量子门之间的调用关系。其输入包括量子线路、量子门名称及其在硬件上的执行时间,输出为量子门调用关系的流程图。
  • draw_circuit_features:此函数通过生成雷达图来可视化量子线路的特征。它计算与线路结构和行为相关的多个指标,包括连通性(connectivity)、活动性(liveness)、并行性(parallelism)、纠缠度(entanglement)和关键深度(critical depth)。具体特性含义可参考 [1]。

参考文献

  1. Tomesh T, Gokhale P, Omole V, et al. Supermarq: A scalable quantum benchmark suite[C]//2022 IEEE International Symposium on High-Performance Computer Architecture (HPCA). IEEE, 2022: 587-603.

量子云服务(QCloudService)

前言

在复杂的量子线路模拟中,依赖高性能计算集群或真实量子计算机来替代本地计算是必要的,这在一定程度上降低了用户的计算成本,并提供了更好的计算体验。
本源量子云平台(Origin Quantum Cloud Platform)通过 Origin South Service 将任务提交至远程部署的量子计算机或计算集群,并查询处理结果。

新特性

  • 简化了本源量子云服务的初始化流程

    在 pyqpanda 的量子云服务代码中,量子比特的申请和释放、量子线路的构造以及虚拟机的绑定都被集成在一起。

例如,以下是 pyqpanda 的使用方法,该流程相对复杂。

from pyqpanda import *
import numpy as np
qm = QCloud()
qm.set_configure(72,72);
qm.init_qvm("302e020100301006072a86006052b8104001c041730502010424100b6d33ad8772eb9708494453a3c8a/16327",True)
q = qm.qAlloc_many(6)
c = qm.cAlloc_many(6)
prog = QProg()
prog << hadamard_circuit(q)\
<< RX(q[1], np.pi / 4)\
<< RX(q[2], np.pi / 4)\
<< RX(q[1], np.pi / 4)\
<< CZ(q[0], q[1])\
<< CZ(q[1], q[2])\
<< Measure(q[0], c[0])\
<< Measure(q[1], c[1])

pyqpanda3 中,已经实现了完全解耦,并移除了显式的初始化配置。

# 你的真实 API 令牌
api_key = "XXXXX"
from pyqpanda3.core import QProg, H, Y, X, measure
import pyqpanda3.qcloud as qcloud
prog = QProg()
prog << H(0)
prog << X(0)
prog << Y(0)
prog << measure(0, 0)
service = qcloud.QCloudService(api_key)
定义 __init__.py:1

  • 统一计算接口(Unified Computing Interface)

在 pyqpanda 中,不同的计算接口是独立的。

result0 = QCM.full_amplitude_measure(measure_prog, 100)
result1 = QCM.full_amplitude_pmeasure(pmeasure_prog, [0, 1, 2])
result2 = QCM.partial_amplitude_pmeasure(pmeasure_prog, ["0", "1", "2"])
batch_prog = [prog for _ in range(6)]
real_chip_measure_batch_result = machine.batch_real_chip_measure(batch_prog, 1000, real_chip_type.origin_72)

pyqpanda3 中,采用了重载 run 函数的方式,实现了统一的计算方法。

目前,支持全振幅模拟、单振幅模拟、部分振幅模拟、噪声模拟等集群任务的提交与查询,并支持对真实量子计算芯片的单个任务和批量任务的提交与查询。

from pyqpanda3.core import QProg, H, Y, X, measure
import pyqpanda3.qcloud as qcloud
# 你的真实 API 令牌
api_key = "XXXXX"
prog = QProg()
prog << H(0)
prog << X(0)
prog << Y(0)
prog << measure(0, 0)
service = qcloud.QCloudService(api_key)
backend = service.backend("origin_wukong")
options = qcloud.QCloudOptions()
job = backend.run(prog, 1000, options)
result = job.result()
  • 优化的同步与异步处理(Optimized Synchronous and Asynchronous Processes)

在 pyqpanda 中,同步和异步方法是分别提供的,而 pyqpanda3 对此过程进行了简化。

同步模式 job.result() 会持续轮询任务结果,直到任务计算完成或出现错误。

job = backend.run(prog, 1000)
result = job.result()
probs = result.get_probs()

异步方法的工作方式与同步类似,但 Job.status() 会查询当前任务的状态并返回查询结果。

while True:
status = job.status()
if status == JobStatus.FINISHED:
break
sleep(5)
  • 新增任务查询功能
  • 现在支持查询 单个任务 的详细信息,包括 查询任何历史任务 ID 的能力。
job = QCloudJob("A45DE13AA1920B115220C19BC0C0F4A5")
probs = job.result().get_probs()

量子信息(QuantumInformation)

前言

在最新版本中,pyqpanda3 支持使用 StateVectorDensityMatrix 来表示两种基本的量子状态表示形式: 态矢量密度矩阵
此外,还支持五种描述量子通道的表示形式,包括 Kraus、Choi、Chi、SuperOp 和 PTM ,并支持这些表示方法之间的相互转换。
另外,还提供了一些信息分析工具,例如 Hellinger 距离、Hellinger 保真度 和 KL 散度
此外,还新增了用于获取 量子线路 QCircuit 的幺正矩阵 的专用类,以及支持计算 转置矩阵、伴随矩阵 和 L2 范数Matrix 类。

新特性

抽象和模拟量子状态

支持 态矢量(State Vector)和密度矩阵(Density Matrix) ,并允许对其进行量子线路的演化操作。

# 构造密度矩阵对象
dm = DensityMatrix(data)
# 构造态矢量对象
stv = StateVector([1+1.j, 2+2.j, 3+3.j, 4+4.j, 5+5.j, 6+6.j, 7+7.j, 8+8.j])

量子通道的抽象和模拟

支持 Kraus、Choi、PTM、SuperOp 和 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]
# 构造 Kraus 对象
Kra2 = Kraus(Ks1)
# 从 Kraus 对象构造 Choi 对象
choi = Choi(Kra3)
# 从 Kraus 对象构造 Chi 对象
chi = Chi(Kra3)
# 从 Kraus 对象构造 SuperOp 对象
sop = SuperOp(Kra3)
# 从 Kraus 对象构造 PTM 对象
ptm = PTM(Kra3)

信息分析工具 提供 Hellinger 距离、Hellinger 保真度 和 KL 散度 的计算方法。
支持计算离散概率分布之间的 KL 散度 以及 连续概率分布之间的 KL 散度

# 计算 p 分布与 q 分布的 Hellinger 距离
hd = hellinger_distance(p_prob, q_prob)
# 计算 p 分布与 q 分布的 Hellinger 保真度
hf = hellinger_fidelity(p_prob, q_prob)
# 计算 p 分布和 q 分布的 KL 散度
kld = KL_divergence(p_prob_val, q_prob_val)

其他功能 提供 矩阵类(Matrix) ,以及获取 量子线路 QCircuit 的幺正矩阵 的类。

data = np.array(data, dtype=complex)
# 构造矩阵对象
m = Matrix(data)
# 获取 QCircuit 的幺正矩阵
matrix = Unitary(cir)

编译器模块(Transpiler Module)

前言

该模块提供 量子线路编译 的功能,支持优化量子线路并映射到特定的硬件拓扑结构。


新特性

  • 新增 Transpiler ,该类通过 transpile() 接口对量子线路进行编译。
    该接口包含四个参数:
    • QProg:待编译的量子线路
    • chip_topology_edges:目标硬件拓扑结构
    • init_mapping:虚拟比特到物理比特的映射
    • optimization_level:优化级别,可取 012
      • 0:不进行优化
      • 1:执行基本优化,如 双比特门消除和单比特门合并
      • 2:执行高级优化,如 矩阵优化、双比特门消除和单比特门合并
  • 当前支持的基础门集合 :[X1RZCZ]
  • 未来规划 :将逐步开放 InitPassLayoutPassRoutingPassOptimizationPassTranslationPass,允许用户自由组合这些 Pass 以定制编译器流程。

示例

from pyqpanda3.core import QProg,H,RX,CNOT,U1,CNOT,measure,draw_qprog
from pyqpanda3.transpilation import Transpiler,generate_topology
prog_1 = QProg()
prog_1 << H(0) << RX(0, 1.25) << CNOT(0, 1) << U1(1, 0.0001) << CNOT(0, 1) << CNOT(1, 2)
for i in range(3):
prog_1 << measure(i, i)
# Create topology structure
topo = generate_topology(20, "square")
transpiler = Transpiler()
prog_level_0 = transpiler.transpile(prog_1, topo, {}, 0)
prog_level_1 = transpiler.transpile(prog_1, topo, {}, 1)
prog_level_2 = transpiler.transpile(prog_1, topo, {}, 2)
定义 __init__.py:1

变分量子线路

前言

在最新版本中,pyqpanda3 使用 VQCircuit 来支持变分量子线路。提供占位符支持,以便在 Ansatz 逻辑门中使用多维数组设置变量参数,支持基于多维数组批量生成 QCircuit,并支持计算生成的 QCircuit 的哈密顿量/泡利算符的期望值。此外,VQCircuit 还支持启用分层机制,以更好地生成由多个相同结构的量子线路串联组成的 QCircuit。

变更

类的名称已从 VQC 更改为 VQCircuit,以避免与变分量子线路分类器的缩写冲突。
代码示例

在构建 Ansatz 时,添加非参数门和固定参数门的方法已更改。pyqpanda3 采用与 QCircuit 和 QProg 相同的函数来添加相应的量子逻辑门。
代码示例

在构建 Ansatz 时,添加需要更新的量子逻辑门参数的方法已更改。pyqpanda3 采用与生成 QCircuit 或 QProg 相同名称的函数。这些函数可以指定某种类型的门参数需要更新。
代码示例

生成特定 QCircuit 对象的方法不同。VQCircuit 对象通过传入多维数组批量生成相应的 QCircuit 对象。
代码示例

在生成 QCircuit 对象后,返回的结果形式不同。pyqpanda3 使用 VQCResult 对象来管理生成的 QCircuit。
代码示例

新特性

使用 VQCircuit 作为类名可以避免在 VQC 术语中对“变分量子线路”和“变分量子分类器”缩写产生歧义。

# 构造 VQCircuit 对象
from pyqpanda3.vqcircuit import VQCircuit
vqc = VQCircuit()
定义 __init__.py:1

使用统一的函数名称来添加量子逻辑门。
在构建 Ansatz 时,添加非参数门和固定参数门的方法已更改。pyqpanda3 采用与 QCircuit 和 QProg 相同的函数来添加相应的量子逻辑门。

如果你想直接运行此示例代码以尝试此功能,最简单的方法是将 第一个代码示例 中的所有代码块复制到该代码中,并将其保存为 Python 脚本文件。

# pyqpanda3 采用与 QCircuit 和 QProg 相同的函数来添加相应的量子逻辑门
from pyqpanda3.core import QCircuit, RX, RY, U2, Y, H, X, CP
# 逐个添加带参数的可变量子逻辑门,并固定它们的参数
vqc << H(0) << X(0) << CP(1, 2, 3.14)
# 批量添加带有固定参数的可变子线路逻辑门
cir = QCircuit()
cir << Y(0) << U2(1, 4.14, 5.14)
vqc << cir

它提供了一种占位符机制,可用于在构建变分量子线路的 Ansatz 时添加带有可变参数的量子逻辑门。
在构建 Ansatz 时,添加需要更新的量子逻辑门参数的方法已更改。pyqpanda3 采用与生成 QCircuit 或 QProg 相同名称的函数。这些函数可以指定某种类型的门参数需要更新。

如果你想直接运行此示例代码以尝试此功能,最简单的方法是将 第一个代码示例 中的所有代码块复制到该代码中,并将其保存为 Python 脚本文件。

# 1> pyqpanda3 采用与生成 QCircuit 或 QProg 相同名称的函数。
# 这些函数可以指定某种类型的门参数需要更新。
# 2> 在使用这些函数之前,需要预先约定构造 QCircuit 对象所需的多维数组的维度信息
# (默认情况下禁用分层机制),或者当启用分层机制时,需要预先约定用于构造单层子线路的
# 多维数组的维度信息。
# 3> 请使用成员函数 set_Param 来设置维度信息。
vqc.set_Param([3,2])
# 成员函数 get_Param_dims 用于获取维度信息。
dims = vqc.get_Param_dims()
print("dims:",dims)
# 逐个添加可变量子逻辑门,其中参数化门的参数可变。
vqc << RX(0,vqc.Param([0,0],"theta")) << RX(2,vqc.Param("theta")) << RX(1,vqc.Param([1,0])) << RY(0,vqc.Param([0,1])) << U2(1,vqc.Param([1,1]),5.55) << RY(2,vqc.Param([2,1]))

运行本说明文档中介绍的代码序列,从代码块 第一个代码示例 到此代码块。
该代码块对应的输出如下:

dims: [3, 2]

它提供了一个实用的接口,可用于打印与 Ansatz 相关的信息。

如果你想直接运行此示例代码以尝试此功能,最简单的方法是将 第一个代码示例 中的所有代码块复制到该代码中,并将其保存为 Python 脚本文件。

# 显示与 Ansatz 相关的信息。
print("display_ansatz:")
vqc.display_ansatz()

运行本说明文档中介绍的代码序列,从代码块 第一个代码示例 到此代码块。
该代码块对应的输出如下:

display_ansatz:
---gates of a layer circuit:
___
gate id:0
gate type:H
qbits:0,
gate's params' total:0
gate's params:
___
gate id:1
gate type:X
qbits:0,
gate's params' total:0
gate's params:
___
gate id:2
gate type:CP
qbits:1,2,
gate's params' total:1
gate's params:
1th param is fixed. It's val is 3.14
___
gate id:3
gate type:Y
qbits:0,
gate's params' total:0
gate's params:
___
gate id:4
gate type:U2
qbits:1,
gate's params' total:2
gate's params:
1th param is fixed. It's val is 4.14
2th param is fixed. It's val is 5.14
___
gate id:5
gate type:RX
qbits:0,
gate's params' total:1
gate's params:
1th param is mutable.
It's pos in parameters is:0,0
It's label is:theta
___
gate id:6
gate type:RX
qbits:2,
gate's params' total:1
gate's params:
1th param is mutable.
It's pos in parameters is:0,0
It's label is:theta
___
gate id:7
gate type:RX
qbits:1,
gate's params' total:1
gate's params:
1th param is mutable.
It's pos in parameters is:1,0
It's label is:
___
gate id:8
gate type:RY
qbits:0,
gate's params' total:1
gate's params:
1th param is mutable.
It's pos in parameters is:0,1
It's label is:
___
gate id:9
gate type:U2
qbits:1,
gate's params' total:2
gate's params:
1th param is mutable.
It's pos in parameters is:1,1
It's label is:
2th param is fixed. It's val is 5.55
___
gate id:10
gate type:RY
qbits:2,
gate's params' total:1
gate's params:
1th param is mutable.
It's pos in parameters is:2,1
It's label is:
---

VQCircuit 支持使用多维数组来存储参数,以便批量生成 QCircuit 对象。以下代码用于准备一个多维数组数据,该数据将在后续示例代码中用于批量生成 QCircuit 对象。

如果你想直接运行此示例代码以尝试此功能,最简单的方法是将 第一个代码示例 中的所有代码块复制到该代码中,并将其保存为 Python 脚本文件。

# 1> 准备一个多维数组,以批量构造 QCircuit 对象。该多维数组包含多个用于构造单个 QCircuit
# 对象或单个分层子线路的多维数组。
# 2> 例如,set_Param([3,2]) 指定了构造一个 QCircuit 对象(在未启用分层机制的情况下)
# 或者构造一个分层子线路(在启用分层机制的情况下)所需的多维数组的形状为 [3,2]。
# 这里,data 是一个形状为 (2,3,2,3,2) 的多维数组,其中包含 12 个形状为 [3,2] 的多维数组
# (计算方式为 2*3*2)。
# 这些多维数组可以通过索引格式 data[i][j][k] 访问。
import numpy as np
data = np.zeros((3,2,3,2))
for i1 in range(3):
for i2 in range(2):
for i3 in range(3):
for i4 in range(2):
data[i1][i2][i3][i4] = (i1+1)*1000+(i2+1)*100+(i3+1)*10+(i4+1)

VQCircuit 对象支持禁用分层机制。

如果你想直接运行此示例代码以尝试此功能,最简单的方法是将 第一个代码示例 中的所有代码块复制到该代码中,并将其保存为 Python 脚本文件。

注解

VQCircuit 的默认构造函数默认禁用分层机制。
# 禁用分层机制
vqc.disable_layer()

pyqpanda3 中,使用多维数组存储参数以批量生成 QCircuit 对象非常简单。

如果你想直接运行此示例代码来尝试此功能,最简单的方法是将第一个代码示例中的所有代码块复制到该代码中,并保存为 Python 脚本文件。

# 1> 将参数数据应用于批量生成多个 QCircuit,并将它们存储在 cirs 中
# 2> 这里生成了 3*2 个 QCircuit,总共 12 个 QCircuit。每个 QCircuit 都由 VQC
# 根据数据的最后两个维度进行更新,该数据是形状为 (3,2) 的数组
res = vqc(data)

使用 VQResult 管理由 VQCircuit 生成的 QCircuit 结果

这使用户可以使用多维数组索引访问每个 QCircuit 对象。

如果你想直接运行此示例代码来尝试此功能,最简单的方法是将第一个代码示例中的所有代码块复制到该代码中,并保存为 Python 脚本文件。

# 使用多维索引从结果中获取 QCircuit
from pyqpanda3.core import draw_qprog
for i1 in range(3):
for i2 in range(2):
cir = res.at([i1, i2])
# 1> 在这里,你可以直接使用每个 QCircuit 对象,或者对其进行自定义处理。
# 2> 如果希望通过可视化方式理解 QCircuit 对象的结构,
# 请取消注释下面的两行代码。这些代码将使用 draw_qprog 接口
# 打印 QCircuit 对象的结构。
# if len(cir.count_ops()) > 0:
# print(draw_qprog(circuit=cir, param_show=True, expend_map={'all': 2}))

使用层机制构造由子结构(子线路)串联组成的 QCircuit

如果希望构造由多个子结构(子线路)串联组成的 QCircuit,启用 VQCircuit 的层机制可以让用户更方便地使用多维数组中的参数批量构造 QCircuit 对象。

如果你想直接运行此示例代码来尝试此功能,最简单的方法是将第一个代码示例中的所有代码块复制到该代码中,并保存为 Python 脚本文件。

# 启用层机制
vqc.enable_layer()
# 1> 将参数数据应用于批量生成多个 QCircuit,并存储在 cirs 中
# 2> 这里生成了 3 个 QCircuit,每个 QCircuit 由两层子线路组成,总共 6 个 QCircuit
# 3> 每个 QCircuit 由 VQC 生成,并根据数据的最后 3 维更新参数,该数据是
# 形状为 (2, 3, 2) 的数组
# 4> 每个 QCircuit 由两层子线路串联组成,每一层子线路都是通过
# 根据最后两个维度的数据(形状为 (3,2) 的数组)设置特定参数得到的
res = vqc(data)
# 使用多维索引从结果中获取 QCircuit
from pyqpanda3.core import draw_qprog
for i1 in range(3):
cir = res.at([i1])
# 1> 在这里,你可以直接使用每个 QCircuit 对象,或者对其进行自定义处理。
# 2> 如果希望通过可视化方式理解 QCircuit 对象的结构,
# 请取消注释下面的两行代码。这些代码将使用 draw_qprog 接口
# 打印 QCircuit 对象的结构。
# if len(cir.count_ops()) > 0:
# print(draw_qprog(circuit=cir, param_show=True, expend_map={'all': 2}))

VQResult 对象为 VQCircuit 对象提供了有用的后处理功能。
如果你只想获取 res 中某个特定 QCircuit 对应的哈密顿量期望值,可使用以下代码。

请参考 Hamiltonian 了解更多关于 pyqpanda3.hamiltonian.Hamiltonian 的信息。

如果你想直接运行此示例代码来尝试此功能,最简单的方法是将第一个代码示例中的所有代码块复制到该代码中,并保存为 Python 脚本文件。

# 在具有哈密顿量作用的量子系统中执行量子程序的结果
from pyqpanda3.hamiltonian import Hamiltonian
from pyqpanda3.vqcircuit import ExpectationType
Ha = Hamiltonian(pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, })
# 计算 res.at([2])(一个 QCircuit 对象)的理论哈密顿量期望值
expectation = res.expval_hamiltonian(hamiltonian=Ha, idx_s=[2], exp_type=ExpectationType.THEORETICAL)
print("expectation1:", expectation)

运行文档中介绍的代码序列,从第一个代码示例到此代码块,对应的输出如下:

expectation1: -1.9289474504185782

如果你想批量获取 res 中所有 QCircuit 对象的哈密顿量期望值,以下代码可以有效实现该目标。

请参考 Hamiltonian 了解更多关于 pyqpanda3.hamiltonian.Hamiltonian 的信息。

如果你想直接运行此示例代码来尝试此功能,最简单的方法是将第一个代码示例中的所有代码块复制到该代码中,并保存为 Python 脚本文件。

# 计算 res 中所有 QCircuit 对象的理论哈密顿量期望值
expectations = res.expval_hamiltonian(hamiltonian=Ha, exp_type=ExpectationType.THEORETICAL)
# 1> 使用多维数组索引获取计算结果
for i1 in range(3):
# 2> 使用 expval_at([i1]) 获取 res.at([i1])(一个 QCircuit 对象)的理论哈密顿量期望值
expectation = res.expval_at([i1])
print(f"expectation1 [{i1}]:", expectation)

运行文档中介绍的代码序列,从第一个代码示例到此代码块,对应的输出如下:

expectations1 [0]: -1.214227039562041
expectations1 [1]: 0.12937804539398823
expectations1 [2]: -1.9289474504185782

如果你只想获取 res 中某个特定 QCircuit 对应的 PauliOperator 期望值,可使用以下代码。

请参考 PauliOperator 了解更多关于 pyqpanda3.hamiltonian.PauliOperator 的信息。

如果你想直接运行此示例代码来尝试此功能,最简单的方法是将第一个代码示例中的所有代码块复制到该代码中,并保存为 Python 脚本文件。

# 在具有 Pauli 算符作用的量子系统中执行量子程序的结果
from pyqpanda3.hamiltonian import PauliOperator
pauli = PauliOperator(pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, })
# 计算 res.at([2])(一个 QCircuit 对象)的理论 PauliOperator 期望值
expectation = res.expval_pauli_operator(pauli_operator=pauli, idx_s=[2], exp_type=ExpectationType.THEORETICAL)
print("expectation2:", expectation)

运行文档中介绍的代码序列,从第一个代码示例到此代码块,对应的输出如下:

expectation2: -1.9289474504185782

如果你想批量获取 res 中所有 QCircuit 对象的 PauliOperator 期望值,以下代码可以有效实现该目标。

请参考 PauliOperator 了解更多关于 pyqpanda3.hamiltonian.PauliOperator 的信息。

如果你想直接运行此示例代码来尝试此功能,最简单的方法是将第一个代码示例中的所有代码块复制到该代码中,并保存为 Python 脚本文件。

# 计算 res 中所有 QCircuit 对象的理论 PauliOperator 期望值
pauli = PauliOperator(pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, })
expectations = res.expval_pauli_operator(pauli_operator=pauli, exp_type=ExpectationType.THEORETICAL)
# 1> 使用多维数组索引获取计算结果
for i1 in range(3):
# 2> 使用 expval_at([i1]) 获取 res.at([i1])(一个 QCircuit 对象)的理论 PauliOperator 期望值
expectation = res.expval_at([i1])
print(f"expectation2 [{i1}]:", expectation)

运行文档中介绍的代码序列,从第一个代码示例到此代码块,对应的输出如下:

expectations2 [0]: -1.214227039562041
expectations2 [1]: 0.12937804539398823
expectations2 [2]: -1.9289474504185782