持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
QuTrunk使用教程之Bell Pair电路及Deutsch算法
QuTrunk是启科量子自主研发的量子编程框架。QuTrunk基于Python提供了量子编程API,对量子编程相关的基本概念做了代码层面的抽象封装和实现,如Qubit代表单个量子比特,每个量子比特默认持有一个经典比特,方便存放量子比特对测量结果,例如num_qubits = 15,输出print("num_qubits:", num_qubits, "num_elems:", num_elems, "num_reps:", num_reps)。量子编程框架QuTrunk中的门操作是量子算法的基本组成单元,其中主要包括H, Measure, CNOT, Toffoli, P, R, Rx, Ry, Rz, S, Sdg, T, Tdg, X, Y, Z, NOT, Swap, SqrtSwap, SqrtX, All, C, Rxx, Ryy, Rzz。下文将以Bell Pair(贝尔线路)和Deutsch算法算法为例,主要介绍如何使用QuTrunk实现各种量子门操作。下文的解析内容包括如何利用QuTrunk准备量子编程所需的环境、定义量子函数、量子逻辑门的操作及各指令的作用等。
1.量子逻辑门:H与CNOT实例
1.1Bell Pair
步骤1:环境准备
- 代码块:
from qutrunk.circuit import QCircuit
from qutrunk.circuit.gates import H, CNOT, Measure
-
量子线路:以上代码模块中
core.circuit提供量子线路功能。 -
量子逻辑门操作:
from qutrunk.core.gates import H, CNOT, Measure可以准备H门、CNOT门和测量操作。
步骤2:初始化量子线路,分配量子寄存器
- 代码块:
qc = QCircuit()
qr = qc.allocate(2)
步骤3:应用量子逻辑门
- 代码块:
H * qr[0]
CNOT * (qr[0], qr[1])
Measure * qr[0]
Measure * qr[1]
# print circuit
qc.print()
- 量子逻辑门的表示方式1:
量子逻辑门+qr[量子态]。如H * qr[0]表示将哈达玛门作用于|0〉态上,产生量子叠加态;CNOT * (qr[0], qr[1])表示将CNOT门分别作用于与|0〉态和|1〉态上,其中|0〉处在控制位、|1〉处在目标位,只有当控制位为|1〉态时目标位发生翻转;Measure * qr[1]
CNOT门
—————-●(控制位)————————
|
—————⊕(目标位)————————
-
打印线路:量子线路部分代码编辑好之后,直接打印量子线路。
-
根据逻辑门操作预测所得结果:|00〉+|10〉态。
-
量子逻辑门的表示方式2:除将量子逻辑线路直接以代码形式编辑外,还可以使用启科量子的自研量子可视化编辑器。
首先,下载QuBranch后,点击【命令】选项;
其次,在框内输入quan,一键选择quan:量子编程可视化;
拖拽量子逻辑门置于量子比特的时序线之上,此时会发现右侧代码编辑栏自动显示相应代码,且编辑器底部显示相应的量子态概率柱状图;
完整的Bell-Pair量子线路如下:
步骤4:Bell Pair量子线路运行及结果返回
- 代码块:
# run circuit
res = qc.run(shots=1024)
# print result
print(res.get_measure())
print(res.get_counts())
目前QuTrunk已经通过运行代码直接可以输出量子线路图。
步骤5:输出运行结果
- 结果显示:
*qreg q[2]
creg c[2]
H * q[0]
MCX(1) * (q[0], q[1])
Measure * q[0]
Measure * q[1]
[{"00": 505}, {"11": 519}]*
-
定义量子寄存器:以上定义量子寄存器是通过qreg操作完成的。指令为
qreg q[2]表示定义一个名为q的2位量子寄存器;同理,指令creg c[2]表示定义一个名为c的经典寄存器。 -
测量结果:测量结果为[{"00": 505}, {"11": 519}]。该结果表示量子线路运行次数分别为505、519,共计运行1024次。对以上程序进行多次运行,发现结果都不相同,比如第二、三次的运行结果分别为[{"00": 507}, {"11": 517}]、[{"00": 528}, {"11": 496}]。
1.2Deutsch算法
1.2.1问题描述
Deutsch算法主要解决判断函数类型问题。对两个不同类型的函数,通过两个输入和最后的结果输出,判断函数属于常数函数还是平衡函数。Deutsch算法最大的贡献在于为之后的量子算法提供了启发性的思路,并不能具体解决实际问题。
1.2.2Deutsch算法
步骤1:环境准备
- 代码块:
from qutrunk.circuit import QCircuit
from qutrunk.circuit.gates import H, Measure, All, X, CNOT
# allocate
qc = QCircuit()
qureg = qc.allocate(2)
-
量子线路:以上代码模块中
qutrunk.circuit提供量子线路功能。 -
量子逻辑门操作:
from qutrunk.circuit.gates import H, Measure, All, X, CNOT可以准备H门、CNOT门和测量操作。
步骤2:逻辑门操作
- 代码块:
X * qureg[1]
All(H) * qureg
CNOT * (qureg[0], qureg[1])
H * qureg[0]
All(Measure) * qureg
- 如量子线路图所示,首先需要将|0⟩态操作为|1⟩态。这时需要使用X门操作,X门计算公式为:|0⟩→|1⟩,|1⟩→|0⟩。代码块中的指令
X | qureg[1]操作后将可得到一个|1⟩态。Deutsch算法的量子线路如上图所示。本文中的Deutsch算法示例暂时只使用两个量子比特。
|0⟩——————X——————|1⟩
- 对单个量子比特进行H门或者CNOT门操作并储存,可以使用指令
H | qureg[0]或者CNOT | (qureg[0], qureg[1])。对多个量子比特进行门操作,可以直接使用指令All(逻辑操作) | qureg,如All(Measure) | qureg。当量子比特数较少时,也可以参照Bell-Pair线路分别对量子比特进行门操作,比如Measure * qr[0];Measure * qr[1]。
步骤3:输出结果
- **输出结果如下:**输出结果可以看成三个部分,分别为比特存储及逻辑门计算操作部分、测量部分、结果部分
> *qreg q[2]
creg c[2]
X * q[1]
H * q[0]
H * q[1]
MCX(1) * (q[0], q[1])
H * q[0]
Measure * q[0]
Measure * q[1]
The result of Deutsch: 1*
- 寄存操作部分:表示对比特位为2的量子比特寄存操作。
*qreg q[2]
creg c[2]
- 输出结果为"执行Deutsch算法,测量得到的结果是:1":最终的结果为概率值即振幅的平方。当最后结果为0时,可判断函数为常数函数;当最后结果为1时,可判断函数为平衡函数。经过多次运行,该程序的最终结果始终为1。
结尾
以上案例中仅涉及到少量的量子逻辑门使用如H, X,CNOT和逻辑操作Measure等。QuTrunk使用教程系列还将继续以具体算法为例解析更多其他量子逻辑门的使用。