Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Quantum Teleportation to examples. #1449

Merged
merged 9 commits into from
Mar 20, 2019
3 changes: 3 additions & 0 deletions examples/examples_perf_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import examples.bcs_mean_field
import examples.phase_estimator
import examples.basic_arithmetic
import examples.quantum_teleportation
import examples.superdense_coding


Expand Down Expand Up @@ -49,6 +50,8 @@ def test_example_runs_grover_perf(benchmark):
def test_example_runs_phase_estimator_perf(benchmark):
benchmark(examples.phase_estimator.main, qnums=(2,), repetitions=2)

def test_example_runs_quantum_teleportation(benchmark):
benchmark(examples.quantum_teleportation.main)

def test_example_runs_superdense_coding(benchmark):
benchmark(examples.superdense_coding.main)
3 changes: 3 additions & 0 deletions examples/examples_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import examples.bcs_mean_field
import examples.phase_estimator
import examples.basic_arithmetic
import examples.quantum_teleportation
import examples.superdense_coding


Expand Down Expand Up @@ -58,6 +59,8 @@ def test_example_runs_basic_arithmetic():
def test_example_runs_phase_estimator():
examples.phase_estimator.main(qnums=(2,), repetitions=2)

def test_example_runs_quantum_teleportation():
examples.quantum_teleportation.main()

def test_example_runs_superdense_coding():
examples.superdense_coding.main()
94 changes: 94 additions & 0 deletions examples/quantum_teleportation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"""Quantum Teleportation.
Quantum Teleportation is a process by which a quantum state can be transmitted
by sending only two classical bits of information. This is accomplished by
pre-sharing an entangled state between the sender (Alice) and the receiver
(Bob). This entangled state allows the receiver (Bob) of the two classical
bits of information to possess a qubit with the same state as the one held by
the sender (Alice).

In the following example output, qubit 0 (the Message) is set to a random state
by applying X and Y gates. By sending two classical bits of information after
qubit 0 (the Message) and qubit 1 (Alice's entangled qubit) are measured, the
final state of qubit 2 (Bob's entangled qubit) will be identical to the
original random state of qubit 0 (the Message). This is only possible given
that an entangled state is pre-shared between Alice and Bob.

=== REFERENCE ===
https://en.wikipedia.org/wiki/Quantum_teleportation
https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.70.1895

=== EXAMPLE OUTPUT ===
Circuit:
0: -----------X^0.25---Y^0.125---@---H---M-------@---
| | |
1: ---H---@----------------------X-------M---@---|---
| | |
2: -------X----------------------------------X---@---

Bloch Sphere of Message After Random X and Y Gates:
x: 0.2706 y: -0.7071 z: 0.6533

Bloch Sphere of Qubit 2 at Final State:
x: 0.2706 y: -0.7071 z: 0.6533

"""

import random
import numpy as np
import cirq


def make_quantum_teleportation_circuit(ranX, ranY):
circuit = cirq.Circuit()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cirq.Circuit.from_ops would avoid a lot of append boilerplate.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for this feedback. Please let me know if I misunderstood your comment, but I have amended the code to be as follows: message = sim.simulate(cirq.Circuit.from_ops([cirq.X(0)**ranX, cirq.Y(0)**ranY])) which avoids the append boilerplate to get the bloch sphere of the message.

Again, please do let me know if I misunderstood what you were looking for here and thanks so much for this suggestion!

msg, alice, bob = cirq.LineQubit.range(3)

# Creates Bell state to be shared between Alice and Bob
circuit.append([cirq.H(alice), cirq.CNOT(alice, bob)])
# Creates a random state for the Message
circuit.append([cirq.X(msg)**ranX, cirq.Y(msg)**ranY])
# Bell measurement of the Message and Alice's entangled qubit
circuit.append([cirq.CNOT(msg, alice), cirq.H(msg)])
circuit.append(cirq.measure(msg, alice))
# Uses the two classical bits from the Bell measurement to recover the
# original quantum Message on Bob's entangled qubit
circuit.append([cirq.CNOT(alice, bob), cirq.CZ(msg, bob)])

return circuit


def main():
ranX = random.random()
ranY = random.random()
circuit = make_quantum_teleportation_circuit(ranX, ranY)

print("Circuit:")
print(circuit)

sim = cirq.Simulator()

# Produces the message using random X and Y gates
message = sim.simulate(cirq.Circuit.from_ops(
[cirq.X(0)**ranX, cirq.Y(0)**ranY]))

print("\nBloch Sphere of Message After Random X and Y Gates:")
# Prints the Bloch Sphere of the Message after the X and Y gates
b0X, b0Y, b0Z = cirq.bloch_vector_from_state_vector(
message.final_state, 0)
print("x: ", np.around(b0X, 4),
"y: ", np.around(b0Y, 4),
"z: ", np.around(b0Z, 4))

# Records the final state of the simulation
final_results = sim.simulate(circuit)

print("\nBloch Sphere of Qubit 2 at Final State:")
# Prints the Bloch Sphere of Bob's entangled qubit at the final state
b2X, b2Y, b2Z = cirq.bloch_vector_from_state_vector(
final_results.final_state, 2)
print("x: ", np.around(b2X, 4),
"y: ", np.around(b2Y, 4),
"z: ", np.around(b2Z, 4))


if __name__ == '__main__':
main()