量子计算
目录
量子计算入门
什么是量子?
“量子物理学”是一个广泛使用但鲜为人知的术语。它是一种数学模型,最初用于描述实验室中小物体的行为,它暴露了先前“经典”物理学理论的空白。量子理论解释了这种行为,并为我们提供了更完整的宇宙图景。我们已经意识到我们可以使用这种以前无法解释的行为来执行我们以前认为不可能的某些计算。我们称之为量子计算。
量子计算是让您的可以深入了解量子物理学的完美方式。它将量子物理学的核心概念提炼成最简单的形式,去除了物理世界的复杂性。本节将带您踏上发现(并解释!)一些奇怪的量子现象的短途旅程,并让您领略什么是“量子”。
经典概率回顾
为了涵盖量子现象,我们需要首先提醒自己“经典”概率。从这个意义上说,“经典”只是指前量子,即你应该在学校看到的正态概率树。如果您已经熟悉此材料,则应快速浏览它。如果您对此不是很感兴趣,那么请不要担心——我们只会涵盖一些最简单的概率问题。
概率树
希望您会记住学校的概率树。这个想法很简单——我们用一张图画出每一种可能发生的情况,然后我们可以计算出它发生的可能性。
假设我们有一枚硬币,首先,我们将它放在手中。如果我们随后抛掷这枚公平的硬币并观察它,我们有 50% 的机会再次看到正面,而有 50% 的机会看到反面。我们可以像这样在概率树上绘制它:
我们在每个分支的末尾绘制结果,并在分支上绘制每次出现的概率。同样,如果我们从反面状态开始并抛硬币,我们将有 50% 的机会看到正面,50% 的机会看到反面。
我们可以通过尝试来测试它是否有效。你可以物理地拿出一枚硬币,抛多次,并记录每个结果;您最终会看到大约 50% 的结果是正面,50% 是反面。大约 500 到 1000 次抛掷应该足以获得可靠的结果。
更进一步
看起来我们的概率树模型正确地预测了我们的实验结果。我们可以更进一步,将我们的概率树链接在一起,以预测事件链的结果。例如,假设我们从正面开始,抛硬币,然后再抛硬币,我们会看到什么?我们可以使用树来计算:
你可能还记得在学校,我们沿着分支相乘来计算每个事件组合的概率:
然后我们将结果加在一起以计算每个结果的概率:
并且我们可以看到抛两次后看到正面的概率是 50%,抛两次之后看到反面的概率也是 50%。
双掷硬币也一样,经过足够多的抛掷,我们的结果符合预期:测量正面或反面的机会均等。
量子币
现在我们对经典硬币有了完整的描述,是时候介绍一种量子“硬币”了。我们的量子硬币被称为“量子比特”。
量子比特是你只能在实验室里玩的东西,因为它们很难操纵。多年的科技进步创造了我们今天拥有的量子位,但通过量子计算学习的美妙之处在于我们可以忽略物理上的复杂性,只要记住当我们测量一个量子位时,它会是两个中的一个状态:我们称我们的量子比特的两个状态为 0 和 1,而不是两个状态 正面 和 反面。
量子抛硬币
让我们试验一下我们的量子硬币,看看它的行为方式。我们将进行一次量子抛掷,测量硬币的状态并记录下来。这就像上一节中的经典抛硬币。
我们将尝试使用概率树来描述我们的量子硬币。这看起来像是,从 0 状态开始,抛硬币给了我们 50-50 的机会来测量 0 或 1。让我们像处理经典硬币一样在树上绘制它:
类似地,从状态 1 开始,抛硬币给了我们 50-50 的机会测量到 0 或 1。概率树如下所示:
双量子掷硬币
我们现在有一个模型可以预测量子硬币的行为。像优秀的科学家一样,我们现在想在新的场景中测试它,看看它是否成立。让我们像以前一样尝试抛两次硬币。就像经典硬币一样,我们的量子硬币模型预测有 50-50 的机会测量 0 或 1,无论我们从哪个状态开始:
所以让我们试试吧!我们将抛两次量子硬币:
这与我们的预测完全不符!我们的模型让我们失望了!这与物理学家在 20 世纪初遇到的问题相同。寻找答案导致了量子物理学的发展,这就是我们将用来描述我们的量子掷硬币的东西。
量子模型
简而言之,量子论是负数的概率论。
这是什么意思?我们不能有负概率,因为那没有意义。为了适应这一点,我们使用了一个新的数量,我们称之为振幅,并将它们绘制在树上。为了解决我们不能有负概率以及所有概率加起来必须为 1 的事实,我们使用了一个数学技巧:我们对幅值求平方来计算概率。
让我们看一个例子。我们单次量子硬币抛掷的振幅树如下所示:
我们可以看到,从状态 0 开始,量子掷硬币为两个结果分配了相等的振幅。当我们对这些振幅进行平方时,它们会为我们提供测量 0 或 1 的正确概率(50-50 机会)。我们怎么知道振幅是二分之一的开方?因为它们是给我们正确答案的价值观!
从状态 1 开始,振幅树就不同了:
在这里,我们可以看到我们的第一个负数出现在 1 结果的振幅中。当我们对振幅求平方来计算概率时,这个负号消失了(记住负数乘以负数就是正数),我们看到上面测量的 50-50 的机会。有趣的结果是当我们将这些概率链接在一起时。
解释双量子抛硬币
就像经典概率一样,我们沿着分支乘以振幅来计算每个结果的振幅:
为了计算出测量每个结果的概率,我们将这些振幅相加,然后平方:
我们可以看到在状态 1 中找硬币(量子比特)的振幅相互抵消,我们称这种效应为干扰。您应该自己验证此模型在初始状态为 1 时是否有效。
什么是量子计算?
这很酷,但它有什么用呢?事实证明,这些干扰效应可以为我们所用;我们可以结合诸如量子抛硬币之类的操作来构建更高效的算法。这些算法可以利用干扰效应让错误的答案迅速抵消,让我们有很高的概率测出正确答案。这就是量子计算背后的理念。
量子电路教程入门
电路基础
在这里,我们提供了使用 Qiskit 的概述。Qiskit 提供了对量子计算机进行编程所必需的基本构建块。Qiskit 的基本单元是量子电路。使用 Qiskit 的基本工作流程包括两个阶段:构建和运行。Build 允许您生成代表您正在解决的问题的不同量子电路,而 Run 允许您在不同的后端运行它们。作业运行后,根据所需的输出收集数据并进行后处理。
import numpy as np
from qiskit import QuantumCircuit
构建电路
您的第一个程序所需的基本元素是 QuantumCircuit。我们首先创建一个由三个量子位组成的 QuantumCircuit
。
# Create a Quantum Circuit acting on a quantum register of three qubits
circ = QuantumCircuit(3)
使用寄存器创建电路后,您可以添加门(“操作”)来操作寄存器。随着教程的进行,您会发现更多的门和电路;下面是产生三量子位 GHZ 状态的量子电路示例
$$|\psi\rangle = \left(|000\rangle+|111\rangle\right)/\sqrt{2}.$$
为了创建这样的状态,我们从一个三量子比特的量子寄存器开始。默认情况下,寄存器中的每个量子位都被初始化为 . 为了形成 GHZ 状态,我们应用以下门:
- 一个 Hadamard 门 H 在量子位 0 上,使其进入叠加态 .
- 一个 Controlled-NOT 操作 () 在量子位 0 和量子位 1 之间。
- 量子位 0 和量子位 2 之间的一个 Controlled-NOT 操作。
在理想的量子计算机上,运行该电路产生的状态将是上面的 GHZ 状态。
在 Qiskit 中,可以在电路中逐一添加操作,如下所示。
# Add a H gate on qubit 0, putting this qubit in superposition.
circ.h(0)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 1, putting
# the qubits in a Bell state.
circ.cx(0, 1)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 2, putting
# the qubits in a GHZ state.
circ.cx(0, 2)
<qiskit.circuit.instructionset.InstructionSet at 0x7f12b87bddf0>
可视化电路
您可以使用 Qiskit 可视化您的电路 QuantumCircuit.draw()
,它以许多教科书中的形式绘制电路。
circ.draw('mpl')
在此电路中,量子位按顺序排列,量子位 0 在顶部,量子位 2 在底部。从左到右读取电路(这意味着电路中较早应用的门显示在更左侧)。
在表示多量子位系统的状态时,Qiskit 中使用的张量阶与大多数物理教科书中使用的不同。假设有 个量子比特和 个量子位被标记,则表示 . Qiskit 使用一种排序方式 ,其中量子比特位于张量积的左侧,因此基向量标记为 .
例如,如果量子位 0 处于状态 0,量子位 1 处于状态 0,量子位 2 处于状态 1,Qiskit 会将此状态表示为 ,而许多物理教科书将其表示为 .
这种标记差异会影响多量子位运算表示为矩阵的方式。例如,Qiskit 表示一个 controlled-X () 以量子位 0 为控制,量子位 1 为目标的操作
模拟电路
为了模拟电路,我们使用 Qiskit 中的 quant_info 模块。该模拟器返回量子态,这是一个复杂的维度向量 , 在哪里 是量子位的数量(所以要小心使用它,因为它很快就会变得太大而无法在你的机器上运行)。
模拟器有两个阶段。第一个是设置输入状态,第二个是通过量子电路演化状态。
from qiskit.quantum_info import Statevector
# Set the intial state of the simulator to the ground state using from_int
state = Statevector.from_int(0, 2**3)
# Evolve the state by the quantum circuit
state = state.evolve(circ)
#draw using latex
state.draw('latex')
$$\frac{\sqrt{2}}{2} |000\rangle+\frac{\sqrt{2}}{2} |111\rangle$$
from qiskit.visualization import array_to_latex
#Alternative way of representing in latex
array_to_latex(state)
$$ \begin{bmatrix} \frac{\sqrt{2}}{2} & 0 & 0 & 0 & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \ \end{bmatrix} $$
Qiskit 还提供了一个可视化工具箱,让您可以查看状态。
下面,我们使用可视化函数绘制 qsphere 和表示状态密度矩阵 的实部和虚部的 hinton。
state.draw('qsphere')
state.draw('hinton')
电路的单一表示
Qiskit 的 quant_info 模块也有一个运算符方法,可用于为电路制作单一运算符。这计算了 表示量子电路的矩阵。
from qiskit.quantum_info import Operator
U = Operator(circ)
# Show the results
U.data
数组([[ 0.70710678+0.j,0.70710678+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.70710678+0.j, -0.70710678+0.j],
[ 0.+0.j, 0.+0.j, 0.70710678+0.j,
0.70710678+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.70710678+0.j, -0.70710678+0.j,
0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j,
0.+0.j, 0.70710678+0.j, 0.70710678+0.j,
0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.70710678+0.j,
-0.70710678+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.70710678+0.j, 0.70710678+0.j],
[ 0.70710678+0.j, -0.70710678+0.j, 0.+0.j,
0.+0.j,0.+0.j,0.+0.j,
0.+0.j, 0.+0.j]])
OpenQASM 后端
上面的模拟器很有用,因为它们提供了有关理想电路输出的状态和电路的矩阵表示的信息。然而,一个真正的实验通过测量每个量子位来终止(通常在计算 , 基础)。没有测量,我们就无法获得有关状态的信息。测量导致量子系统坍缩成经典比特。
例如,假设我们对三量子位 GHZ 状态的每个量子位进行独立测量
$$ |\psi\rangle = (|000\rangle +|111\rangle)/\sqrt{2}, $$
然后让 表示结果的位串。回想一下,在 Qiskit 使用的量子位标签下, 将对应于 qubit 2 的结果, 表示 qubit 1 的结果,和 表示 qubit 0 的结果。
注意:这种位串表示法将最高有效位 (MSB) 放在左侧,将最低有效位 (LSB) 放在右侧。这是二进制位串的标准排序。我们以相同的方式对量子位进行排序(表示 MSB 的量子位具有索引 0),这就是 Qiskit 使用非标准张量积顺序的原因。
回想一下,获得结果 的概率由下式给出
$$ \mathrm{Pr}(xyz) = |\langle xyz | \psi \rangle |^{2} $$
因此,获得 000 或 111 的 GHZ 状态概率均为 1/2。
要模拟包含测量的电路,我们需要将测量添加到上面的原始电路,并使用不同的 Aer 后端。
# Create a Quantum Circuit
meas = QuantumCircuit(3, 3)
meas.barrier(range(3))
# map the quantum measurement to the classical bits
meas.measure(range(3), range(3))
# The Qiskit circuit object supports composition.
# Here the meas has to be first and front=True (putting it before)
# as compose must put a smaller circuit into a larger one.
qc = meas.compose(circ, range(3), front=True)
#drawing the circuit
qc.draw('mpl')
该电路添加了一个经典寄存器和三个用于将量子位结果映射到经典位的测量值。
为了模拟这个电路,我们使用了 qasm_simulator
Qiskit Aer。该电路的每次运行都会产生位串 000 或 111。要建立关于位串分布的统计数据(例如,估计 ),我们需要多次重复电路。电路重复的次数可以通过关键字 shots
在 execute
函数中指定。
# Adding the transpiler to reduce the circuit to QASM instructions
# supported by the backend
from qiskit import transpile
# Use AerSimulator
from qiskit_aer import AerSimulator
backend = AerSimulator()
# First we have to transpile the quantum circuit
# to the low-level QASM instructions used by the
# backend
qc_compiled = transpile(qc, backend)
# Execute the circuit on the qasm simulator.
# We've set the number of repeats of the circuit
# to be 1024, which is the default.
job_sim = backend.run(qc_compiled, shots=1024)
# Grab the results from the job.
result_sim = job_sim.result()
一旦你获得对象结果后,你可以通过函数 get_counts(circuit)
访问统计次数。这为你提供了你提交的电路的聚合二进制结果。
counts = result_sim.get_counts(qc_compiled)
print(counts)
{'000': 486, '111': 538}
大约 50% 的时间,输出位串是 000。Qiskit 还提供了一个函数 plot_histogram
,可以让你查看结果。
from qiskit.visualization import plot_histogram
plot_histogram(counts)
估计 和 的结果概率是通过获取汇总计数并除以拍摄次数(重复电路的次数)来计算。尝试更改 execute
函数中的 shots
关键字,看看估计的概率如何变化。
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.23.1 |
qiskit-aer | 0.11.2 |
qiskit-ibmq-provider | 0.20.0 |
qiskit | 0.41.0 |
qiskit-nature | 0.5.2 |
qiskit-finance | 0.3.4 |
qiskit-optimization | 0.5.0 |
qiskit-machine-learning | 0.5.0 |
System information | |
Python version | 3.8.16 |
Python compiler | GCC 11.3.0 |
Python build | default, Jan 11 2023 00:28:51 |
OS | Linux |
CPUs | 2 |
Memory (Gb) | 6.781219482421875 |
Fri Feb 03 18:56:55 2023 UTC |