Quantum Teleportation in Python — Deep Dive

The Mathematics of Teleportation

To understand the protocol precisely, we need to track the quantum state through each step.

Alice wants to teleport an arbitrary qubit state: |ψ⟩ = α|0⟩ + β|1⟩

The shared Bell pair between Alice (qubit B) and Bob (qubit C) is: |Φ⁺⟩ = (1/√2)(|00⟩ + |11⟩)

The combined three-qubit system starts as: |ψ⟩_A ⊗ |Φ⁺⟩_BC = (α|0⟩ + β|1⟩) ⊗ (1/√2)(|00⟩ + |11⟩)

Expanding and regrouping in the Bell basis for qubits A and B:

= (1/2)[|Φ⁺⟩_AB(α|0⟩ + β|1⟩)_C + |Φ⁻⟩_AB(α|0⟩ - β|1⟩)_C + |Ψ⁺⟩_AB(α|1⟩ + β|0⟩)_C + |Ψ⁻⟩_AB(α|1⟩ - β|0⟩)_C]

Each Bell measurement outcome leaves Bob’s qubit in a known transformation of |ψ⟩:

Bell state measuredBob’s stateCorrection needed
Φ⁺⟩ (00)α|0⟩ + β|1⟩
Φ⁻⟩ (01)α|0⟩ - β|1⟩
Ψ⁺⟩ (10)α|1⟩ + β|0⟩
Ψ⁻⟩ (11)α|1⟩ - β|0⟩

Implementation in Qiskit

Basic Teleportation Circuit

from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
import numpy as np

def teleportation_circuit(state_params=None):
    """
    Full quantum teleportation protocol.
    state_params: (theta, phi) for the state to teleport
    """
    qc = QuantumCircuit(3, 2)

    # Step 0: Prepare the state to teleport on qubit 0
    if state_params:
        theta, phi = state_params
        qc.ry(theta, 0)
        qc.rz(phi, 0)
    else:
        # Default: teleport |+⟩ state
        qc.h(0)

    qc.barrier()

    # Step 1: Create Bell pair between qubits 1 and 2
    qc.h(1)
    qc.cx(1, 2)

    qc.barrier()

    # Step 2: Alice's Bell measurement on qubits 0 and 1
    qc.cx(0, 1)
    qc.h(0)
    qc.measure(0, 0)  # First classical bit
    qc.measure(1, 1)  # Second classical bit

    qc.barrier()

    # Step 3: Bob's conditional corrections
    # Classical bit 1 → X correction on qubit 2
    qc.x(2).c_if(1, 1)
    # Classical bit 0 → Z correction on qubit 2
    qc.z(2).c_if(0, 1)

    return qc

# Build and run
qc = teleportation_circuit(state_params=(np.pi/3, np.pi/4))
print(qc.draw())

sim = AerSimulator()
qc_with_measure = qc.copy()
qc_with_measure.measure(2, 0)  # Measure Bob's qubit

transpiled = transpile(qc_with_measure, sim)
result = sim.run(transpiled, shots=10000).result()
counts = result.get_counts()
print(f"Measurement results: {counts}")

Verification with Statevector

To prove teleportation works perfectly, compare statevectors:

from qiskit.quantum_info import Statevector, state_fidelity

def verify_teleportation(theta, phi):
    """Verify teleportation by comparing input and output states."""

    # Prepare the target state
    target_circuit = QuantumCircuit(1)
    target_circuit.ry(theta, 0)
    target_circuit.rz(phi, 0)
    target_state = Statevector.from_instruction(target_circuit)

    # Run teleportation without measurement (use deferred measurement)
    qc = QuantumCircuit(3)
    qc.ry(theta, 0)
    qc.rz(phi, 0)

    # Bell pair
    qc.h(1)
    qc.cx(1, 2)

    # Bell measurement (without collapsing)
    qc.cx(0, 1)
    qc.h(0)

    # Corrections (using controlled gates instead of classical feedback)
    qc.cx(1, 2)  # X correction
    qc.cz(0, 2)  # Z correction

    # Get final statevector
    sv = Statevector.from_instruction(qc)

    # Trace out qubits 0 and 1 to get Bob's state
    # After successful teleportation, qubit 2 should match target
    reduced = sv.trace([0, 1])

    fidelity = state_fidelity(target_state.to_operator(), reduced)
    return fidelity

# Test with various states
for theta in [0, np.pi/4, np.pi/2, np.pi]:
    for phi in [0, np.pi/3, np.pi]:
        f = verify_teleportation(theta, phi)
        print(f"θ={theta:.2f}, φ={phi:.2f}: fidelity={f:.6f}")
        assert abs(f - 1.0) < 1e-10, "Teleportation failed!"

Implementation in Cirq

import cirq
import numpy as np

def teleport_cirq(state_to_teleport):
    """Teleportation using Cirq with classical feedback."""
    msg = cirq.NamedQubit("message")
    alice = cirq.NamedQubit("alice")
    bob = cirq.NamedQubit("bob")

    circuit = cirq.Circuit()

    # Prepare state to teleport
    circuit.append(cirq.ry(state_to_teleport[0]).on(msg))
    circuit.append(cirq.rz(state_to_teleport[1]).on(msg))

    # Create Bell pair
    circuit.append(cirq.H(alice))
    circuit.append(cirq.CNOT(alice, bob))

    # Bell measurement
    circuit.append(cirq.CNOT(msg, alice))
    circuit.append(cirq.H(msg))
    circuit.append(cirq.measure(msg, key='m1'))
    circuit.append(cirq.measure(alice, key='m2'))

    # Classical feedback with Cirq's classical control
    circuit.append(cirq.X(bob).with_classical_controls('m2'))
    circuit.append(cirq.Z(bob).with_classical_controls('m1'))

    return circuit

circuit = teleport_cirq([np.pi/3, np.pi/4])
print(circuit)

simulator = cirq.Simulator()
result = simulator.simulate(circuit)

Entanglement Swapping

Entanglement swapping extends teleportation to create entanglement between particles that never interacted:

def entanglement_swapping():
    """
    Particles 1-2 are entangled. Particles 3-4 are entangled.
    Bell measurement on 2-3 entangles 1-4 (which never met).
    """
    qc = QuantumCircuit(4, 4)

    # Bell pair 1: qubits 0 and 1
    qc.h(0)
    qc.cx(0, 1)

    # Bell pair 2: qubits 2 and 3
    qc.h(2)
    qc.cx(2, 3)

    qc.barrier()

    # Bell measurement on qubits 1 and 2
    qc.cx(1, 2)
    qc.h(1)
    qc.measure(1, 0)
    qc.measure(2, 1)

    # Corrections on qubit 3
    qc.x(3).c_if(1, 1)
    qc.z(3).c_if(0, 1)

    # Now qubits 0 and 3 are entangled!
    qc.measure(0, 2)
    qc.measure(3, 3)

    return qc

qc = entanglement_swapping()
sim = AerSimulator()
result = sim.run(transpile(qc, sim), shots=10000).result()
counts = result.get_counts()

# Verify: qubits 0 and 3 should be correlated
for outcome, count in sorted(counts.items()):
    bits = outcome.replace(' ', '')
    q0, q3 = bits[1], bits[0]  # Qiskit reverses bit order
    print(f"{outcome}: {count} (q0={q0}, q3={q3})")

Quantum Repeater Chain

For long-distance quantum communication, repeaters use entanglement swapping in sequence:

def quantum_repeater_chain(n_segments, noise_per_segment=0.0):
    """
    Chain of entanglement swapping to extend quantum communication range.
    n_segments: number of intermediate segments
    """
    n_qubits = 2 * (n_segments + 1)  # Two qubits per segment
    n_classical = 2 * n_segments      # Two bits per swapping measurement

    qc = QuantumCircuit(n_qubits, n_classical)

    # Create Bell pairs for each segment
    for seg in range(n_segments + 1):
        q1 = 2 * seg
        q2 = 2 * seg + 1
        qc.h(q1)
        qc.cx(q1, q2)

        if noise_per_segment > 0:
            # Simulate channel noise with depolarizing errors
            # (In real Qiskit, use noise models)
            pass

    qc.barrier()

    # Entanglement swapping at each intermediate node
    for node in range(n_segments):
        q_left = 2 * node + 1       # Right qubit of left segment
        q_right = 2 * (node + 1)    # Left qubit of right segment
        c_base = 2 * node

        qc.cx(q_left, q_right)
        qc.h(q_left)
        qc.measure(q_left, c_base)
        qc.measure(q_right, c_base + 1)

        # Correction on the rightmost qubit of the chain
        target = 2 * (n_segments + 1) - 1
        qc.x(target).c_if(c_base + 1, 1)
        qc.z(target).c_if(c_base, 1)

    return qc

# 3-segment repeater chain
chain = quantum_repeater_chain(3)
print(f"Chain uses {chain.num_qubits} qubits, {chain.num_clbits} classical bits")

Teleportation on Noisy Hardware

On real quantum devices, teleportation fidelity degrades:

from qiskit_aer.noise import NoiseModel, depolarizing_error

def noisy_teleportation(error_rate):
    """Simulate teleportation with realistic noise."""
    noise_model = NoiseModel()
    noise_model.add_all_qubit_quantum_error(
        depolarizing_error(error_rate, 1), ['h', 'x', 'z', 'ry', 'rz']
    )
    noise_model.add_all_qubit_quantum_error(
        depolarizing_error(error_rate * 5, 2), ['cx']
    )

    qc = teleportation_circuit(state_params=(np.pi/4, 0))
    qc.measure(2, 0)

    sim = AerSimulator(noise_model=noise_model)
    transpiled = transpile(qc, sim)
    result = sim.run(transpiled, shots=10000).result()

    return result.get_counts()

# Compare ideal vs noisy
print("Ideal:", noisy_teleportation(0.0))
print("1% noise:", noisy_teleportation(0.01))
print("5% noise:", noisy_teleportation(0.05))

Teleportation-Based Quantum Computing

Measurement-based quantum computing uses teleportation as a computational primitive:

def gate_teleportation(gate_name='T'):
    """
    Teleport a gate: apply a gate to a qubit using only
    Bell measurements and pre-prepared resource states.
    """
    qc = QuantumCircuit(3, 2)

    # Prepare resource state (gate applied to half of Bell pair)
    qc.h(1)
    qc.cx(1, 2)
    if gate_name == 'T':
        qc.t(2)  # T gate applied to resource state
    elif gate_name == 'S':
        qc.s(2)

    # Input state on qubit 0
    qc.h(0)  # Example: |+⟩ state

    qc.barrier()

    # Teleportation protocol
    qc.cx(0, 1)
    qc.h(0)
    qc.measure(0, 0)
    qc.measure(1, 1)

    # Corrections (may need additional Clifford corrections
    # depending on the teleported gate)
    qc.x(2).c_if(1, 1)
    qc.z(2).c_if(0, 1)

    return qc

This technique is fundamental to fault-tolerant quantum computing, where non-Clifford gates (like the T gate) are implemented via “magic state” distillation and gate teleportation.

Real-World Teleportation Experiments

  • 2017: Chinese team teleported a photon’s state from Earth to the Micius satellite (1,400 km)
  • 2020: Fermilab demonstrated teleportation over 44 km of fiber optic cable
  • 2022: Teams in the Netherlands demonstrated teleportation between non-neighboring nodes in a 3-node quantum network
  • 2024-2025: Multiple groups demonstrated teleportation with error-corrected logical qubits

These experiments validate the protocol that Python simulations model, bridging theory and physical implementation.

One thing to remember: Quantum teleportation isn’t a parlor trick — it’s the fundamental data transfer protocol for quantum networks. Every time a future quantum internet moves information between nodes, it will use this exact protocol, and Python simulations are how researchers design and optimize it today.

pythonquantum-computingquantum-teleportationphysics

See Also