超密编码
本节演示了超密编码(Superdense Coding, SDC)协议。我们首先使用Qiskit的模拟器来测试我们的量子电路,然后在真正的量子计算机上进行测试。
1. 超密编码与量子隐形传态的区别
量子隐形传态与超密编码有着密切的联系,为了避免混淆我们需要澄清两者的区别。
量子隐形传态是利用两比特的经典通信和一个贝尔对将量子比特( \ket{\psi} )的状态从一个位置传送到另一个位置的过程。换句话说,我们可以说它是一个协议,在一个位置上破坏一个量子比特的量子态,并在一个遥远的位置上利用共享纠缠在一个量子比特上重新创建它。超密编码是一种允许某人仅使用一个通信比特向另一方发送两个经典比特的过程。
隐形传态协议可以被认为是超密编码协议的翻转版本,从某种意义上说,Alice和Bob只是“交换了他们的设备”。
2. 过程
2.1 步骤1
这个过程从第三方开始,我们叫他Charlie。处于纠缠态的两个量子比特是由Charlie准备的。他开始时初始化两个量子比特为基态 \ket{0} 。他对第一个量子比特应用Hadamard门( H )来产生叠加。然后,他应用CNOT门( CX ),使用第一个量子比特作为控制,第二个量子比特作为目标。这就是我们之前提到的纠缠态(贝尔对)。
结果状态
我们从以下状态开始:
其中,发送给Alice的量子比特标记为A,发送给Bob的量子比特标记为b。Charlie首先对第一个量子比特应用Hadamard门,这产生了叠加,我们得到状态:
然后Charlie应用CNOT门。CNOT门纠缠两个量子比特,即如果控制为 |1\rangle ,则翻转目标。请注意,控制量子比特是我们最右边的量子比特。
2.2 步骤2
Charlie将第一个量子比特发送给Alice,第二个量子比特发送给Bob。该协议的目标是让Alice使用她的量子比特向Bob发送2个经典比特的信息。但在此之前,她需要根据她想要发送的两个比特信息,对她的量子比特应用一组量子门:
超密编码的编码规则(Alice协议):
要发送的信息 | 应用门 | 结果状态( \cdot\tfrac{1}{\sqrt{2}} ) |
---|---|---|
00 | I | \ket{00} + \ket{11} |
01 | X | \ket{10} + \ket{01} |
10 | Z | \ket{00} - \ket{11} |
11 | ZX | -\ket{10} + \ket{01} |
因此,如果她想发送一个00,她对她的量子比特不做任何操作(应用identity( I )门)。如果她想发送01,那么她应用 X 门。根据她想要发送的内容,她应用适当的门,然后将她的量子比特发送给Bob,以进行过程的最后一步。
2.3 步骤3
Bob接收到Alice的量子比特(最左边的量子比特),并使用他的量子比特来解码Alice的消息。请注意,他不需要了解状态就能解码——他只是使用恢复操作。
Bob应用CNOT门,使用最左边的量子比特作为控制,最右边的量子比特作为目标。然后他应用一个Hadamard门,最后对两个量子比特进行测量,以提取Alice的信息。
Bob接收( \cdot\tfrac{1}{\sqrt{2}} ) | 经过CNOT门( \cdot\tfrac{1}{\sqrt{2}} ) | 经过H门 |
---|---|---|
\ket{00} + \ket{11} | \ket{00} + \ket{10} | \ket{00} |
\ket{10} + \ket{01} | \ket{11} + \ket{01} | \ket{01} |
\ket{00} - \ket{11} | \ket{00} - \ket{10} | \ket{10} |
-\ket{10} + \ket{01} | -\ket{11} + \ket{01} | -\ket{11} |
3. 超密编码协议的仿真
# Importing everything
from qiskit import QuantumCircuit
from qiskit import IBMQ, Aer, transpile, assemble
from qiskit.visualization import plot_histogram
我们知道,要创建一个纠缠对,我们需要应用一个H门和一个CNOT。让我们创建一个函数,该函数接受一个QuantumCircuit
,并使索引为a
和b
的量子比特纠缠:
def create_bell_pair():
"""
Returns:
QuantumCircuit: Circuit that produces a Bell pair
"""
qc = QuantumCircuit(2)
qc.h(1)
qc.cx(1, 0)
return qc
接下来,我们需要对消息进行编码。可以发送的消息有四种:00、10、01或11。让我们创建一个函数,接收此消息并为我们应用适当的门:
def encode_message(qc, qubit, msg):
"""Encodes a two-bit message on qc using the superdense coding protocol
Args:
qc (QuantumCircuit): Circuit to encode message on
qubit (int): Which qubit to add the gate to
msg (str): Two-bit message to send
Returns:
QuantumCircuit: Circuit that, when decoded, will produce msg
Raises:
ValueError if msg is wrong length or contains invalid characters
"""
if len(msg) != 2 or not set(msg).issubset({"0","1"}):
raise ValueError(f"message '{msg}' is invalid")
if msg[1] == "1":
qc.x(qubit)
if msg[0] == "1":
qc.z(qubit)
return qc
最后,我们需要解码我们的消息,我们知道可以使用一个CNOT和一个H门来实现这一点。让我们也来创建一个函数为我们做这件事:
def decode_message(qc):
qc.cx(1, 0)
qc.h(1)
return qc
最后,我们可以把这些放在一起来完成我们的协议。
# Charlie creates the entangled pair between Alice and Bob
qc = create_bell_pair()
# We'll add a barrier for visual separation
qc.barrier()
# At this point, qubit 0 goes to Alice and qubit 1 goes to Bob
# Next, Alice encodes her message onto qubit 1. In this case,
# we want to send the message '10'. You can try changing this
# value and see how it affects the circuit
message = '10'
qc = encode_message(qc, 1, message)
qc.barrier()
# Alice then sends her qubit to Bob.
# After recieving qubit 0, Bob applies the recovery protocol:
qc = decode_message(qc)
# Finally, Bob measures his qubits to read Alice's message
qc.measure_all()
# Draw our output
qc.draw()
3.1 可视化测量结果
aer_sim = Aer.get_backend('aer_simulator')
qobj = assemble(qc)
result = aer_sim.run(qobj).result()
counts = result.get_counts(qc)
print(counts)
plot_histogram(counts)
{‘10’: 1024}
我们的模拟器模拟了一台完美的量子计算机。我们可以看到,在没有误差的情况下,我们有100%的机会测量到正确的信息。
4. 真实量子计算机上的超密编码
我们现在可以看到这在一台真正的量子计算机上工作。首先,我们想加载我们的帐户,以获得最不繁忙的量子系统:
from qiskit import IBMQ
from qiskit.providers.ibmq import least_busy
shots = 1024
# Load local account information
IBMQ.load_account()
# Get the least busy backend
provider = IBMQ.get_provider(hub='ibm-q')
backend = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= 2
and not x.configuration().simulator
and x.status().operational==True))
print("least busy backend: ", backend)
# Run our circuit
t_qc = transpile(qc, backend, optimization_level=3)
job = backend.run(t_qc)
least busy backend: ibmq_belem
# Monitoring our job
from qiskit.tools.monitor import job_monitor
job_monitor(job)
Job Status: job has successfully run
# Plotting our result
result = job.result()
plot_histogram(result.get_counts(qc))
正如我们所看到的,在真正的量子计算机中运行时,有来自其他三个状态的一些结果。这些是由于门中和量子比特退相干的误差。我们将在后面的章节中进一步了解这些误差。
correct_results = result.get_counts(qc)[message]
accuracy = (correct_results/shots)*100
print(f"Accuracy = {accuracy:.2f}%")
Accuracy = 89.55%
import qiskit.tools.jupyter
%qiskit_version_table
版本信息
Qiskit Software | Version |
---|---|
qiskit-terra | 0.18.0 |
qiskit-aer | 0.8.2 |
qiskit-ignis | 0.6.0 |
qiskit-ibmq-provider | 0.15.0 |
qiskit-aqua | 0.9.4 |
qiskit | 0.28.0 |
System information | |
---|---|
Python | 3.7.7 (default, May 6 2020, 04:59:01) [Clang 4.0.1 (tags/RELEASE_401/final)] |
OS | Darwin |
CPUs | 8 |
Memory (Gb) | 32.0 |
Mon Aug 23 19:51:51 2021 BST