If you want a high-level explanation of quantum teleportation, read this article.
Quantum teleportation is a technique for transferring quantum information from a sender at one location to a receiver some distance away.
Let's say Alice wants to send a message to Bob. Specifically, suppose she wants to send the qubit state |𝜓⟩=𝛼|0⟩+𝛽|1⟩.
According to the "no-cloning" theorem, you cannot make an exact copy of an unknown quantum state. Therefore, Alice cannot generate a copy of |𝜓⟩ and send the copy to Bob as we cannot copy a superposition of state. However, if we were transmitting classical information, we can do this task of copying and sending the bits.
If two classical bits and an entangled qubit pair is used, Alice can transfer her state |𝜓⟩ to Bob. This is called quantum teleportation as at the end Bob will have |𝜓⟩ and Alice will not anymore. Quantum teleportation is important because this is the only way Alice can send information to Bob and not violate the law of conservation of information.
We will import the libraries:
import numpy as np
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute, BasicAer, IBMQ
from qiskit.visualization import plot_histogram, plot_bloch_multivector
from qiskit import *
import matplotlib.pyplot as plt
%matplotlib inline
from qiskit.visualization import plot_histogram
Since the quantum teleportation protocol uses 3 qubits, and 2 classical bits (stored in different registers), we will initialize the Quantum Registers and make our teleportation circuit.
qr = QuantumRegister(3)
cr1 = ClassicalRegister(1)
cr2 = ClassicalRegister(1)
teleportation_circuit = QuantumCircuit(qr, cr1, cr2)
A third party, Eve, needs to create an entangled pair of qubits. She will give one to Bob and one to Alice. The pair Eve creates is a special pair called a Bell pair. In order to create a bell pair between two qubits she must first transfer one of them to the X-basis (|+⟩ and |−⟩) using a Hadamard gate( the default basis used in Qiskit is the computational basis), and apply a CNOT gate onto the other qubit controlled by the one in the X-basis. The CNOT gate is a binary gate that is applied on two qubits that is the way used to create an entangled pair. We will write code to create a circuit and apply the CNOT gate.
def entanglement_bell_pair(qc, a, b):
qc.h(a) # Put qubit a into state |+> or |-> using hadamard gate
qc.cx(a,b) # CNOT with a as control and b as target
# Eve entangles qubits q1 and q2
entanglement_bell_pair(teleportation_circuit, 1, 2)
teleportation_circuit.draw(output='mpl')
Alice needs to apply a CNOT gate to 𝑞1 , controlled by |𝜓⟩ (the qubit she sends to Bob which is q0). Then Alice applies a Hadamard gate to |𝜓⟩.
def alice_state_qubits(qc, psi, a):
qc.cx(psi, a) #psi is the state of q0
qc.h(psi)
# call the function to our circuit
teleportation_circuit.barrier()
alice_state_qubits(teleportation_circuit, 0, 1)
teleportation_circuit.draw(output='mpl')
Next, Alice applies a measurement to both qubits that she owns, 𝑞1 and |𝜓⟩ , and stores this result in two classical bits. She then sends these two bits to Bob as we know that this will not violate the no-cloning theorem.
def measure_classical_send(qc, a, b):
qc.barrier()
qc.measure(a,0)
qc.measure(b,1)
measure_classical_send(teleportation_circuit, 0 ,1)
teleportation_circuit.draw(output='mpl')
Bob, who already has the qubit 𝑞2, applies quantum gates based on bits he receives
00 →→ Identity
01 →→ Apply 𝑋 gate
10 →→ Apply Z gate
11 →→ Apply 𝑍𝑋 gate
#based on cr1 and cr2 which store the classical bits
def bob_apply_gates(qc, qubit, cr1, cr2):
qc.z(qubit).c_if(cr1, 1) #if cr1 is 1 apply Z gate
qc.x(qubit).c_if(cr2, 1) #if cr2 is 1 apply x gate, look at table above
# Let's apply this to our circuit:
teleportation_circuit.barrier() # Use barrier to separate steps
bob_apply_gates(teleportation_circuit, 2, cr1, cr2)
teleportation_circuit.draw(output='mpl')
We will initialize Alice's qubit in a random state |𝜓⟩ . This state will be created using an Initialize gate on |𝑞0⟩ . First, we will create a random state function.
def random_state(nqubits):
"""Creates a random nqubit state vector"""
from numpy import append, array, sqrt
from numpy.random import random
real_parts = array([])
im_parts = array([])
for amplitude in range(2**nqubits):
real_parts = append(real_parts, (random()*2)-1)
im_parts = append(im_parts, (random()*2)-1)
# Combine into list of complex numbers:
amps = real_parts + 1j*im_parts
# Normalise
magnitude_squared = 0
for a in amps:
magnitude_squared += abs(a)**2
amps /= sqrt(magnitude_squared)
return amps
# specify a random state
psi = random_state(1)
Define initialization gate to create |𝜓⟩ from the state |0⟩ :
from qiskit.extensions import Initialize
init_gate = Initialize(psi)
Now, we will call all the functions we have created so far and test our quantum teleportation protocol.
qr = QuantumRegister(3)
cr1 = ClassicalRegister(1)
cr2 = ClassicalRegister(1)
qc = QuantumCircuit(qr, cr1, cr2)
#let's initialise Alice's q0
qc.append(init_gate, [0])
qc.barrier()
# teleportation protocol
entanglement_bell_pair(qc, 1, 2)
qc.barrier()
# Send q1 to Alice and q2 to Bob
alice_state_qubits(qc, 0, 1)
# alice sends to Bob
measure_classical_send(qc, 0, 1)
# Bob decodes qubits
bob_apply_gates(qc, 2, cr1, cr2)
qc.draw(output='mpl')
backend = BasicAer.get_backend('statevector_simulator')
out_vector = execute(qc, backend).result().get_statevector()
plot_bloch_multivector(out_vector)
Quantum teleportation is designed to send qubits between two parties.
On a real quantum computer, we would not be able to use the state-vector, so to check teleportation circuit is working, we need to do things slightly differently. You will remember that we used Initialize to turn our |0⟩ qubit into the state |𝜓⟩
|0⟩−→−−−−Initialize|𝜓⟩
Since all quantum gates are reversible, we can find the the inverse of Initialize using:
inverse_init_gate = init_gate.gates_to_uncompute()
qc.append(inverse_init_gate, [2])
qc.draw(output='mpl')
#add a new classical register to see the result
cr_result = ClassicalRegister(1)
qc.add_register(cr_result)
qc.measure(2,2)
qc.draw(output='mpl')
Plot the histogram of the results:
backend = BasicAer.get_backend('qasm_simulator')
counts = execute(qc, backend, shots=1024).result().get_counts()
plot_histogram(counts)
We can see that we have a 100% chance of measuring 𝑞2 (the leftmost bit in the string) in the state |0⟩ . This is the expected result, and indicates the teleportation protocol has worked properly.
About
Support
Every week, our team curates the most important news, events, and opportunities in the quantum space. Our subscribers gain early access to opportunities and exclusive interviews with prominent individuals. You don't want to miss out.