Skip to content

Quantum Teleportation ​

Teleport an unknown quantum state from one qubit to another using entanglement, classical communication, and dynamic circuits with mid-circuit measurement and conditional corrections.


Problem ​

What is Quantum Teleportation? ​

Quantum teleportation is a protocol that transfers an unknown quantum state from one location (Alice) to another (Bob) using two classical bits and one shared Bell pair. Despite the name, no matter or energy is transported -- only quantum information.

The protocol was proposed by Bennett, Brassard, Crepeau, Jozsa, Peres, and Wootters in 1993 and has been demonstrated experimentally over distances ranging from centimeters to over 1,000 km (using the Micius satellite).

Alice starts with a qubit in an unknown state:

|ψ⟩=α|0⟩+β|1⟩,|α|2+|β|2=1

After the protocol, Bob holds a qubit in exactly the same state |ψ⟩, while Alice's original qubit is destroyed (measured).

The No-Cloning Theorem ​

A natural question arises: can we simply copy the quantum state? The no-cloning theorem proves that an unknown quantum state cannot be copied perfectly. There is no unitary operation U such that:

U(|ψ⟩⊗|0⟩)=|ψ⟩⊗|ψ⟩∀|ψ⟩

Proof by contradiction. Suppose such a U exists. Then for two arbitrary states |ψ⟩ and |ϕ⟩:

U(|ψ⟩⊗|0⟩)=|ψ⟩⊗|ψ⟩U(|ϕ⟩⊗|0⟩)=|ϕ⟩⊗|ϕ⟩

Taking the inner product of both sides:

⟨ψ|ϕ⟩=(⟨ψ|ϕ⟩)2

This holds only if ⟨ψ|ϕ⟩=0 or ⟨ψ|ϕ⟩=1, i.e., the states are either orthogonal or identical. For general states, cloning is impossible.

Teleportation circumvents the no-cloning theorem because the original state is destroyed during measurement. The information is transferred, not duplicated.

mermaid
graph TD
    A["Unknown state |psi> = alpha|0> + beta|1>"] --> B{"Can we copy it?"}
    B -->|"No-Cloning Theorem"| C["Cannot clone unknown quantum states"]
    B -->|"Teleportation"| D["Transfer (destroy original)"]
    D --> E["Alice measures her qubits"]
    E --> F["Sends 2 classical bits"]
    F --> G["Bob applies correction"]
    G --> H["Bob now holds |psi>"]

    style C fill:#FFCDD2
    style H fill:#C8E6C9

Why Teleportation Matters ​

Quantum teleportation is not just a theoretical curiosity. It is a building block for:

  • Quantum communication. Teleportation enables quantum key distribution and quantum repeater networks for long-distance quantum communication.

  • Quantum computing architectures. In modular and distributed quantum computers, teleportation moves quantum information between processing nodes.

  • Gate teleportation. Certain quantum gates (notably the T gate in fault-tolerant computing) are implemented via teleportation using specially prepared resource states.

  • Quantum error correction. Lattice surgery for surface codes uses teleportation-based state injection and logical gate operations.

  • Foundational physics. Teleportation has been used to demonstrate quantum non-locality and to test quantum mechanics at ever-larger distance scales.

mermaid
graph TD
    T["Quantum Teleportation"] --> A["Quantum Repeaters"]
    T --> B["Distributed QC"]
    T --> C["Gate Teleportation"]
    T --> D["Error Correction"]
    T --> E["Quantum Networking"]

    style T fill:#1565C0,color:#fff
    style A fill:#42A5F5,color:#fff
    style B fill:#42A5F5,color:#fff
    style C fill:#42A5F5,color:#fff
    style D fill:#42A5F5,color:#fff
    style E fill:#42A5F5,color:#fff

Solution ​

Protocol Overview ​

The teleportation protocol uses three qubits and two classical bits:

QubitRoleHolder
q0Unknown state |ψ⟩ to teleportAlice
q1Alice's half of the Bell pairAlice
q2Bob's half of the Bell pairBob

The protocol has five steps:

  1. Prepare the unknown state |ψ⟩=α|0⟩+β|1⟩ on q0.

  2. Create a Bell pair between q1 and q2: apply H to q1, then CNOT with control q1 and target q2.

  3. Bell measurement on Alice's qubits (q0, q1): apply CNOT with control q0 and target q1, then H on q0, then measure both into classical bits.

  4. Send the two classical measurement results (m0,m1) to Bob.

  5. Conditional correction on q2: apply Zm0Xm1.

After correction, q2 is in the state |ψ⟩.

mermaid
flowchart TD
    subgraph Step1["Step 1: Prepare"]
        A1["|psi> on q0"]
    end
    subgraph Step2["Step 2: Bell Pair"]
        A2["H(q1)"]
        A3["CNOT(q1, q2)"]
        A2 --> A3
    end
    subgraph Step3["Step 3: Bell Measurement"]
        A4["CNOT(q0, q1)"]
        A5["H(q0)"]
        A6["Measure q0 -> c0"]
        A7["Measure q1 -> c1"]
        A4 --> A5 --> A6
        A5 --> A7
    end
    subgraph Step4["Step 4: Classical Channel"]
        A8["Send (c0, c1) to Bob"]
    end
    subgraph Step5["Step 5: Conditional Correction"]
        A9["qif c0: Z(q2)"]
        A10["qif c1: X(q2)"]
        A9 --> A10
    end

    Step1 --> Step2 --> Step3 --> Step4 --> Step5

    style Step1 fill:#E3F2FD
    style Step2 fill:#E8F5E9
    style Step3 fill:#FFF3E0
    style Step4 fill:#F3E5F5
    style Step5 fill:#FFEBEE

Correction Table ​

The measurement outcomes determine which correction Bob must apply:

m0 (qubit 0)m1 (qubit 1)Bob's CorrectionProbability
00Identity (I)1/4
01X1/4
10Z1/4
11Z⋅X1/4

Each outcome occurs with equal probability 1/4, regardless of the input state |ψ⟩. The correction is always a Pauli operator.

Circuit Diagram ​

mermaid
flowchart LR
    subgraph Qubits
        Q0["q0: |psi>"]
        Q1["q1: |0>"]
        Q2["q2: |0>"]
    end

    subgraph BellPair["Create Bell Pair"]
        H1["H"]
        CX1["CNOT"]
    end

    subgraph BellMeas["Bell Measurement"]
        CX2["CNOT"]
        H2["H"]
        M0["Measure -> c0"]
        M1["Measure -> c1"]
    end

    subgraph Correction["Conditional"]
        CZ["qif c0: Z(q2)"]
        CX3["qif c1: X(q2)"]
    end

    Q0 --> CX2 --> H2 --> M0
    Q1 --> CX2
    Q1 --> CX1
    H1 --> CX1
    Q2 --> CX1
    M0 --> CZ --> CX3
    M1 --> CZ
    Q2 --> CZ
    Q2 --> CX3
    CX3 --> Result["q2 = |psi>"]

Why Dynamic Circuits Are Required ​

Teleportation requires mid-circuit measurement and conditional gate application. The correction operations depend on measurement outcomes that are only known at runtime. This is fundamentally different from a static circuit where all gates are fixed in advance.

pyqpanda3 provides the qif construct for exactly this purpose:

python
from pyqpanda3 import core

# Measure a qubit, then conditionally apply a gate
prog = core.QProg()
prog << core.measure(0, 0)  # Measure q0 -> cbit 0

correction = core.QProg()
correction << core.Z(1)     # Apply Z to q1 if cbit[0] == 1

no_op = core.QProg()        # Do nothing otherwise

prog << core.qif([0]).then(correction).qelse(no_op)

Code ​

Teleporting a Known State ​

The simplest verification: teleport |1⟩ (prepared by applying X to |0⟩) and check that Bob's qubit ends up in |1⟩.

python
from pyqpanda3 import core

# Qubit layout:
#   q0: the state |psi> = |1> to teleport
#   q1: Alice's half of the Bell pair
#   q2: Bob's half of the Bell pair (receives |psi>)

prog = core.QProg()

# Step 1: Prepare |psi> = |1> on q0
prog << core.X(0)

# Step 2: Create Bell pair between q1 and q2
prog << core.H(1)
prog << core.CNOT(1, 2)

# Step 3: Bell measurement on (q0, q1)
prog << core.CNOT(0, 1)
prog << core.H(0)
prog << core.measure(0, 0)  # m0 -> cbit 0
prog << core.measure(1, 1)  # m1 -> cbit 1

# Step 4: Bob's conditional corrections using qif
# If m0 == 1, apply Z to q2
z_correction = core.QProg()
z_correction << core.Z(2)
no_z = core.QProg()
prog << core.qif([0]).then(z_correction).qelse(no_z)

# If m1 == 1, apply X to q2
x_correction = core.QProg()
x_correction << core.X(2)
no_x = core.QProg()
prog << core.qif([1]).then(x_correction).qelse(no_x)

# Step 5: Measure Bob's qubit to verify
prog << core.measure(2, 2)

# Run the circuit
machine = core.CPUQVM()
machine.run(prog, shots=10000)
counts = machine.result().get_counts()
print("Teleportation of |1> results:", counts)

# Extract just Bob's measurement outcome (qubit 2, at cbit 2 which is the first character k[0])
bob_1 = sum(v for k, v in counts.items() if k[0] == '1')
bob_0 = sum(v for k, v in counts.items() if k[0] == '0')
print(f"Bob's qubit: |0> = {bob_0}, |1> = {bob_1}")
print(f"Fidelity: {bob_1 / (bob_0 + bob_1):.4f}")

运行结果:

Teleportation of |1> results: {'100': 2477, '110': 2552, '101': 2416, '111': 2555}
Bob's qubit: |0> = 0, |1> = 10000
Fidelity: 1.0000

Expected output:

Teleportation of |1> results: {'100': 2477, '110': 2552, '101': 2416, '111': 2555}
Bob's qubit: |0> = 0, |1> = 10000
Fidelity: 1.0000

All four measurement patterns appear with roughly equal probability (1/4 each), but Bob's qubit (cbit 2, the leftmost bit in the measurement string) is always 1, confirming perfect teleportation.

Teleporting an Arbitrary State RY(theta)|0> ​

To demonstrate that the protocol works for any state, not just computational basis states, we teleport RY(θ)|0⟩. This produces a general superposition whose Bloch-sphere angle is θ:

RY(θ)|0⟩=cos⁡θ2|0⟩+sin⁡θ2|1⟩
python
from pyqpanda3 import core
import numpy as np

theta = 0.7  # Arbitrary angle in radians

# Build the teleportation circuit for RY(theta)|0>
prog = core.QProg()

# Step 1: Prepare |psi> = RY(theta)|0> on q0
prog << core.RY(0, theta)

# Step 2: Bell pair between q1 and q2
prog << core.H(1)
prog << core.CNOT(1, 2)

# Step 3: Bell measurement on (q0, q1)
prog << core.CNOT(0, 1)
prog << core.H(0)
prog << core.measure(0, 0)
prog << core.measure(1, 1)

# Step 4: Conditional corrections on q2
z_corr = core.QProg()
z_corr << core.Z(2)
no_z = core.QProg()
prog << core.qif([0]).then(z_corr).qelse(no_z)

x_corr = core.QProg()
x_corr << core.X(2)
no_x = core.QProg()
prog << core.qif([1]).then(x_corr).qelse(no_x)

# Final measurement of Bob's qubit
prog << core.measure(2, 2)

# Run the teleportation
machine = core.CPUQVM()
machine.run(prog, shots=50000)
counts = machine.result().get_counts()

# Compute the probability that Bob measures |1>
bob_1 = sum(v for k, v in counts.items() if k[0] == '1')
bob_0 = sum(v for k, v in counts.items() if k[0] == '0')
total = bob_0 + bob_1
measured_prob_1 = bob_1 / total

# Theoretical probability
expected_prob_1 = np.sin(theta / 2) ** 2

print(f"Theta: {theta}")
print(f"Expected P(|1>): {expected_prob_1:.6f}")
print(f"Measured P(|1>): {measured_prob_1:.6f}")
print(f"Error: {abs(measured_prob_1 - expected_prob_1):.6f}")

运行结果:

Theta: 0.7
Expected P(|1>): 0.117579
Measured P(|1>): 0.119240
Error: 0.001661

Expected output (results vary due to shot noise):

Theta: 0.7
Expected P(|1>): 0.117579
Measured P(|1>): 0.119240
Error: 0.001661

The measured probability closely matches the theoretical value. The small discrepancy is due to finite-shot statistical noise, which decreases as the number of shots increases.

Verifying Fidelity with Statevector Comparison ​

For a more precise verification, we compare the teleported state directly against the original state using the statevector inner product. We run two simulations: one for the original state, and one for the teleported state (without measurement on the target qubit).

python
from pyqpanda3 import core
import numpy as np

theta = 1.23  # Arbitrary angle

# --- Reference: prepare the original state on a single qubit ---
ref_prog = core.QProg()
ref_prog << core.RY(0, theta)

ref_machine = core.CPUQVM()
ref_machine.run(ref_prog, shots=1)
ref_sv = ref_machine.result().get_state_vector()

# The original state on qubit 0
original_state = np.array(ref_sv[:2])  # |00> and |01> amplitudes
original_state = original_state / np.linalg.norm(original_state)

# --- Teleportation: prepare and transfer ---
# We run the unitary part (no measurement, no correction) and then
# check each branch separately using the statevector.
# For an exact fidelity check, use DensityMatrixSimulator (see below).

# Prepare the full teleportation unitary (Steps 1-3, no measurement)
unitary_prog = core.QProg()
unitary_prog << core.RY(0, theta)
unitary_prog << core.H(1)
unitary_prog << core.CNOT(1, 2)
unitary_prog << core.CNOT(0, 1)
unitary_prog << core.H(0)

unitary_machine = core.CPUQVM()
unitary_machine.run(unitary_prog, shots=1)
teleport_sv = unitary_machine.result().get_state_vector()

# The 8-amplitude state vector for 3 qubits is (little-endian):
#   |q2 q1 q0> = |000>, |001>, |010>, |011>, |100>, |101>, |110>, |111>
# After Bell measurement, the state collapses based on (m0, m1).
# For (m0,m1) = (0,0): q2 should be in |psi>, no correction needed.

# Extract Bob's uncorrected state for measurement outcome (0,0)
# Indices where q0=0, q1=0 (i.e., (i & 3) == 0): |000>=idx 0, |100>=idx 4
bob_uncorrected_00 = np.array([teleport_sv[0], teleport_sv[4]])
bob_uncorrected_00 = bob_uncorrected_00 / np.linalg.norm(bob_uncorrected_00)

# Fidelity for branch (0,0): no correction needed
fidelity_00 = abs(np.dot(np.conj(original_state), bob_uncorrected_00)) ** 2
print(f"Fidelity for branch (0,0): {fidelity_00:.10f}")
print(f"Perfect teleportation: {abs(fidelity_00 - 1.0) < 1e-10}")

运行结果:

Fidelity for branch (0,0): 1.0000000000
Perfect teleportation: True

Expected output:

Fidelity for branch (0,0): 1.0000000000
Perfect teleportation: True

Exact Fidelity with DensityMatrixSimulator ​

The DensityMatrixSimulator provides an exact, shot-noise-free way to analyze the teleported state. We compute the density matrix of Bob's qubit after the full protocol and compare it to the ideal state.

python
from pyqpanda3 import core
import numpy as np

theta = 0.85

# Step 1: Compute the ideal target density matrix.
# |psi> = cos(theta/2)|0> + sin(theta/2)|1>
alpha = np.cos(theta / 2)
beta = np.sin(theta / 2)
psi_ideal = np.array([alpha, beta])

# Step 2: Run teleportation with deferred measurement.
# Instead of classically-conditioned corrections (qif), we use
# quantum-controlled gates applied before measurement. This is
# mathematically equivalent by the principle of deferred measurement.
prog = core.QProg()
prog << core.RY(0, theta)
prog << core.H(1)
prog << core.CNOT(1, 2)
prog << core.CNOT(0, 1)
prog << core.H(0)
prog << core.CZ(0, 2)      # Z correction (deferred measurement)
prog << core.CNOT(1, 2)    # X correction (deferred measurement)
prog << core.measure(0, 0)
prog << core.measure(1, 1)

dm_sim = core.DensityMatrixSimulator()
dm_sim.run(prog)

# Step 3: Get the reduced density matrix for Bob's qubit (qubit 2)
rho_bob = dm_sim.reduced_density_matrix([2])

# Step 4: Compute fidelity. For a pure target state:
# F = <psi|rho_bob|psi>
fidelity = np.real(psi_ideal.conj() @ rho_bob @ psi_ideal)

print(f"Target state: cos({theta}/2)|0> + sin({theta}/2)|1>")
print(f"alpha = {alpha:.6f}, beta = {beta:.6f}")
print(f"Bob's reduced density matrix:\n{rho_bob}")
print(f"Teleportation fidelity: {fidelity:.10f}")
print(f"Perfect fidelity: {abs(fidelity - 1.0) < 1e-8}")

运行结果:

Target state: cos(0.85/2)|0> + sin(0.85/2)|1>
alpha = 0.911039, beta = 0.412321
Bob's reduced density matrix:
[[0.82999157+0.j 0.3756402 +0.j]
 [0.3756402 +0.j 0.17000843+0.j]]
Teleportation fidelity: 1.0000000000
Perfect fidelity: True

Expected output:

Target state: cos(0.85/2)|0> + sin(0.85/2)|1>
alpha = 0.911039, beta = 0.412321
Bob's reduced density matrix:
[[0.82999157+0.j 0.3756402 +0.j]
 [0.3756402 +0.j 0.17000843+0.j]]
Teleportation fidelity: 1.0000000000
Perfect fidelity: True

The reduced density matrix of Bob's qubit matches |ψ⟩⟨ψ| exactly, confirming perfect teleportation. Note the non-zero off-diagonal elements indicating a coherent superposition, as expected.

Teleportation with Noise Simulation ​

Real quantum hardware introduces errors through gate imperfections, decoherence, and measurement noise. This example simulates teleportation with realistic depolarizing noise and quantifies the fidelity degradation.

python
from pyqpanda3 import core
import numpy as np

theta = 0.85
alpha = np.cos(theta / 2)
beta = np.sin(theta / 2)
psi_ideal = np.array([alpha, beta])

def teleport_reduced_state(theta):
    """Run ideal teleportation and return Bob's reduced density matrix."""
    prog = core.QProg()
    prog << core.RY(0, theta)
    prog << core.H(1) << core.CNOT(1, 2)
    prog << core.CNOT(0, 1) << core.H(0)
    prog << core.CZ(0, 2) << core.CNOT(1, 2)
    prog << core.measure(0, 0) << core.measure(1, 1)
    dm = core.DensityMatrixSimulator()
    dm.run(prog)
    return dm.reduced_density_matrix([2])

# --- Ideal teleportation ---
rho_ideal = teleport_reduced_state(theta)

# --- Apply depolarizing noise analytically ---
# We model the cumulative effect of gate errors: each gate with error
# rate p depolarizes the state slightly. The net effect on Bob's qubit
# is a mixture of the ideal state and the maximally mixed state I/2.
p_h = 0.01      # 1% depolarizing on single-qubit gates
p_cnot = 0.02   # 2% depolarizing on two-qubit gates
n_h = 3         # number of H gates affecting Bob's state
n_cnot = 2      # number of CNOT gates affecting Bob's state
survival = (1 - p_h) ** n_h * (1 - p_cnot) ** n_cnot
rho_noisy = survival * rho_ideal + (1 - survival) * np.eye(2) / 2

# Compute fidelity for both
fid_ideal = np.real(psi_ideal.conj() @ rho_ideal @ psi_ideal)
fid_noisy = np.real(psi_ideal.conj() @ rho_noisy @ psi_ideal)

print(f"Ideal teleportation fidelity:  {fid_ideal:.6f}")
print(f"Noisy teleportation fidelity:  {fid_noisy:.6f}")
print(f"Fidelity loss due to noise:    {fid_ideal - fid_noisy:.6f}")

# Compare purity of Bob's qubit in both cases
purity_ideal = np.trace(rho_ideal @ rho_ideal).real
purity_noisy = np.trace(rho_noisy @ rho_noisy).real
print(f"\nBob's qubit purity (ideal):  {purity_ideal:.6f}")
print(f"Bob's qubit purity (noisy):  {purity_noisy:.6f}")

运行结果:

Ideal teleportation fidelity:  1.000000
Noisy teleportation fidelity:  0.965938
Fidelity loss due to noise:    0.034062

Bob's qubit purity (ideal):  1.000000
Bob's qubit purity (noisy):  0.934196

Expected output:

Ideal teleportation fidelity:  1.000000
Noisy teleportation fidelity:  0.965938
Fidelity loss due to noise:    0.034062

Bob's qubit purity (ideal):  1.000000
Bob's qubit purity (noisy):  0.934196

The noise reduces the fidelity below 1.0 and introduces mixedness (purity < 1) into Bob's qubit. The exact values depend on the noise model parameters.

Comparing Noise Channels ​

Different physical error mechanisms degrade teleportation fidelity differently. This example applies several noise channels and measures the impact.

python
from pyqpanda3 import core
import numpy as np

theta = 1.0
alpha = np.cos(theta / 2)
beta = np.sin(theta / 2)
psi_ideal = np.array([alpha, beta])

def teleport_ideal_rho(theta):
    """Run ideal teleportation and return Bob's reduced density matrix."""
    prog = core.QProg()
    prog << core.RY(0, theta)
    prog << core.H(1) << core.CNOT(1, 2)
    prog << core.CNOT(0, 1) << core.H(0)
    prog << core.CZ(0, 2) << core.CNOT(1, 2)
    prog << core.measure(0, 0) << core.measure(1, 1)
    dm = core.DensityMatrixSimulator()
    dm.run(prog)
    return dm.reduced_density_matrix([2])

rho_ideal = teleport_ideal_rho(theta)

# Define noise channels as functions on a 2x2 density matrix
X = np.array([[0, 1], [1, 0]], dtype=complex)
Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
Z = np.array([[1, 0], [0, -1]], dtype=complex)

def apply_bit_flip(rho, p):
    return (1 - p) * rho + p * X @ rho @ X

def apply_phase_flip(rho, p):
    return (1 - p) * rho + p * Z @ rho @ Z

def apply_depolarizing(rho, p):
    return (1 - 3 * p / 4) * rho + (p / 4) * (X @ rho @ X + Y @ rho @ Y + Z @ rho @ Z)

def apply_amp_damping(rho, gamma):
    E0 = np.array([[1, 0], [0, np.sqrt(1 - gamma)]], dtype=complex)
    E1 = np.array([[0, np.sqrt(gamma)], [0, 0]], dtype=complex)
    return E0 @ rho @ E0.conj().T + E1 @ rho @ E1.conj().T

def apply_phase_damping(rho, lam):
    E0 = np.array([[1, 0], [0, np.sqrt(1 - lam)]], dtype=complex)
    E1 = np.array([[0, 0], [0, np.sqrt(lam)]], dtype=complex)
    return E0 @ rho @ E0.conj().T + E1 @ rho @ E1.conj().T

# Apply each channel to Bob's reduced density matrix
error_rate = 0.03
n_single = 4   # approximate number of single-qubit gates in the circuit
n_two = 2      # approximate number of two-qubit gates
p_eff = 1 - (1 - error_rate) ** (n_single + n_two)

channels = {
    "No noise":           lambda r: r,
    "Bit Flip (X)":       lambda r: apply_bit_flip(r, p_eff),
    "Phase Flip (Z)":     lambda r: apply_phase_flip(r, p_eff),
    "Depolarizing":       lambda r: apply_depolarizing(r, p_eff),
    "Amplitude Damping":  lambda r: apply_amp_damping(r, p_eff),
    "Phase Damping":      lambda r: apply_phase_damping(r, p_eff),
}

print(f"{'Channel':<22s}  {'Fidelity':>8s}")
print("-" * 35)

for name, channel in channels.items():
    rho_noisy = channel(rho_ideal)
    fid = np.real(psi_ideal.conj() @ rho_noisy @ psi_ideal)
    print(f"{name:<22s}  {fid:>8.4f}")

运行结果:

Channel                 Fidelity
-----------------------------------
No noise                  1.0000
Bit Flip (X)              0.9512
Phase Flip (Z)            0.8817
Depolarizing              0.9165
Amplitude Damping         0.9898
Phase Damping             0.9691

Expected output (approximate):

Channel                 Fidelity
-----------------------------------
No noise                  1.0000
Bit Flip (X)              0.9512
Phase Flip (Z)            0.8817
Depolarizing              0.9165
Amplitude Damping         0.9898
Phase Damping             0.9691

Key observations:

  • Depolarizing noise is the most destructive because it applies a combination of X, Y, and Z errors simultaneously.
  • Phase damping and phase flip have identical effect on teleportation fidelity because both introduce Z-type errors that propagate through the CNOT gates.
  • Amplitude damping is asymmetric: it preferentially drives |1⟩ toward |0⟩, biasing the measurement outcomes.

Sweep over Multiple Angles ​

Verify that teleportation works for all input states by sweeping θ across a range of values.

python
from pyqpanda3 import core
import numpy as np

def run_teleportation(theta, shots=10000):
    """Run teleportation of RY(theta)|0> and return Bob's |1> probability."""
    prog = core.QProg()
    prog << core.RY(0, theta)
    prog << core.H(1)
    prog << core.CNOT(1, 2)
    prog << core.CNOT(0, 1)
    prog << core.H(0)
    prog << core.measure(0, 0)
    prog << core.measure(1, 1)

    z_corr = core.QProg()
    z_corr << core.Z(2)
    no_z = core.QProg()
    prog << core.qif([0]).then(z_corr).qelse(no_z)

    x_corr = core.QProg()
    x_corr << core.X(2)
    no_x = core.QProg()
    prog << core.qif([1]).then(x_corr).qelse(no_x)

    prog << core.measure(2, 2)

    machine = core.CPUQVM()
    machine.run(prog, shots=shots)
    counts = machine.result().get_counts()

    bob_1 = sum(v for k, v in counts.items() if k[0] == '1')
    return bob_1 / shots


print(f"{'theta':>6s}  {'Expected':>10s}  {'Measured':>10s}  {'Error':>10s}")
print("-" * 44)

for theta in np.linspace(0, np.pi, 10):
    expected = np.sin(theta / 2) ** 2
    measured = run_teleportation(theta)
    error = abs(measured - expected)
    print(f"{theta:>6.3f}  {expected:>10.6f}  {measured:>10.6f}  {error:>10.6f}")

运行结果:

theta    Expected    Measured       Error
--------------------------------------------
 0.000    0.000000    0.000000    0.000000
 0.349    0.030154    0.030900    0.000746
 0.698    0.116978    0.110900    0.006078
 1.047    0.250000    0.251900    0.001900
 1.396    0.413176    0.416800    0.003624
 1.745    0.586824    0.589700    0.002876
 2.094    0.750000    0.748700    0.001300
 2.443    0.883022    0.877800    0.005222
 2.793    0.969846    0.971300    0.001454
 3.142    1.000000    1.000000    0.000000

Expected output:

theta    Expected    Measured       Error
--------------------------------------------
 0.000    0.000000    0.000000    0.000000
 0.349    0.030154    0.030900    0.000746
 0.698    0.116978    0.110900    0.006078
 1.047    0.250000    0.251900    0.001900
 1.396    0.413176    0.416800    0.003624
 1.745    0.586824    0.589700    0.002876
 2.094    0.750000    0.748700    0.001300
 2.443    0.883022    0.877800    0.005222
 2.793    0.969846    0.971300    0.001454
 3.142    1.000000    1.000000    0.000000

The measured probabilities closely track the expected values across the full range of θ, confirming that teleportation works for any input state.


Explanation ​

Mathematical Derivation ​

The three-qubit initial state (after Steps 1 and 2) is:

|Ψ0⟩=|ψ⟩q0⊗|Φ+⟩q1q2

Substituting |ψ⟩=α|0⟩+β|1⟩ and |Φ+⟩=12(|00⟩+|11⟩):

|Ψ0⟩=12(α|0⟩(|00⟩+|11⟩)+β|1⟩(|00⟩+|11⟩))

Expanding in the computational basis of three qubits:

|Ψ0⟩=12(α|000⟩+α|011⟩+β|100⟩+β|111⟩)

After CNOT(0, 1) ​

The CNOT with control q0 and target q1 flips q1 when q0=|1⟩:

|Ψ1⟩=12(α|000⟩+α|011⟩+β|110⟩+β|101⟩)

Note: |100⟩→|110⟩ and |111⟩→|101⟩.

After H(0) ​

Applying Hadamard to q0 transforms:

H|0⟩=12(|0⟩+|1⟩),H|1⟩=12(|0⟩−|1⟩)

Grouping by the measurement outcomes (m0,m1) on qubits (q0,q1):

∥Ψ2⟩=12(∥00⟩q0q1⊗(α∥0⟩+β∥1⟩)q2+∥01⟩q0q1⊗(α∥1⟩+β∥0⟩)q2+∥10⟩q0q1⊗(α∥0⟩−β∥1⟩)q2+∥11⟩q0q1⊗(α∥1⟩−β∥0⟩)q2)

This is the key decomposition. For each measurement outcome (m0,m1), Bob's qubit q2 is in a known state that is related to |ψ⟩ by a Pauli correction.

Bell Basis Decomposition ​

The state after the Bell measurement can be written compactly as:

|Ψ2⟩=12∑a,b∈{0,1}|a,b⟩⊗XbZa|ψ⟩

This elegant expression shows that:

  1. The measurement outcomes (a,b) are uniformly random: each occurs with probability 14.

  2. For each outcome, Bob's qubit is exactly XbZa|ψ⟩, which can be corrected back to |ψ⟩ by applying ZaXb (using X2=Z2=I).

  3. The correction ZaXb is always a Pauli operator, which is efficient to implement.

mermaid
flowchart TD
    A["|psi> x |Phi+>"] --> B["CNOT(q0,q1)"]
    B --> C["H(q0)"]
    C --> D{"Measure (m0,m1)"}
    D -->|"00"| E["q2 = |psi> (no correction)"]
    D -->|"01"| F["q2 = X|psi> (apply Z)"]
    D -->|"10"| G["q2 = Z|psi> (apply X)"]
    D -->|"11"| H["q2 = ZX|psi> (apply XZ)"]
    E --> I["q2 = |psi>"]
    F --> I
    G --> I
    H --> I

    style D fill:#FF9800,color:#fff
    style I fill:#4CAF50,color:#fff

Detailed Correction Derivation ​

Let us verify each branch explicitly.

Branch (m0,m1)=(0,0):

q2=α|0⟩+β|1⟩=|ψ⟩

No correction needed. Bob already has |ψ⟩.

Branch (m0,m1)=(0,1):

q2=β|0⟩+α|1⟩=X|ψ⟩

Bob applies X:

X⋅X|ψ⟩=X2|ψ⟩=|ψ⟩✓

Branch (m0,m1)=(1,0):

q2=α|0⟩−β|1⟩=Z|ψ⟩

Bob applies Z:

Z⋅Z|ψ⟩=Z2|ψ⟩=|ψ⟩✓

Branch (m0,m1)=(1,1):

q2=β|0⟩−α|1⟩=XZ|ψ⟩

Bob applies Z then X:

XZ⋅XZ|ψ⟩=X(ZX)Z|ψ⟩=X(−XZ)Z|ψ⟩=−XXZZ|ψ⟩=−|ψ⟩

Since ZX=−XZ (the Pauli operators anticommute), and X2=Z2=I:

XZ⋅XZ=−XXZZ=−I

This gives −|ψ⟩, which differs from |ψ⟩ by a global phase of −1. Global phases are physically unobservable, so the state is indeed |ψ⟩. Alternatively, applying the correction as Zm0Xm1 gives ZX⋅XZ|ψ⟩=ZI⋅Z|ψ⟩=Z2|ψ⟩=|ψ⟩, which is cleaner.

The correction table in full:

(m0,m1)Bob's StateCorrectionResult
(0, 0)|ψ⟩I|ψ⟩
(0, 1)X|ψ⟩X|ψ⟩
(1, 0)Z|ψ⟩Z|ψ⟩
(1, 1)XZ|ψ⟩ZX|ψ⟩

Resource Analysis ​

The teleportation protocol requires:

ResourceQuantity
Qubits3 (1 data + 2 Bell pair)
Entangling gates (CNOT)2 (1 for Bell pair + 1 for Bell measurement)
Single-qubit gates2 (Hadamard for Bell pair + Hadamard for measurement)
Measurements2 (mid-circuit)
Classical bits sent2
Conditional gatesUp to 2 (one Z, one X)
Total circuit depth~5 layers

The circuit depth is constant (does not scale with the complexity of the teleported state), making teleportation efficient for any input state.

Why the Original State Is Destroyed ​

The no-cloning theorem guarantees that the original state on q0 cannot be preserved. In the protocol, Alice measures q0 and q1 in the Bell basis. This measurement collapses the state, and the information about |ψ⟩ is no longer on q0.

Formally, after measuring (m0,m1)=(a,b), the post-measurement state is:

ρq0q1q2=|a,b⟩⟨a,b|⊗XbZa|ψ⟩⟨ψ|ZaXb

The reduced state of q0 is just |a⟩⟨a|, which is a computational basis state containing no information about α or β. All the quantum information has been transferred to q2 via the entanglement and classical communication.

Connection to Bell States ​

The teleportation protocol relies on a shared Bell pair |Φ+⟩=12(|00⟩+|11⟩). Any of the four Bell states can be used; the correction table simply changes:

Bell State UsedCorrection Table
|Φ+⟩=12(|00⟩+|11⟩)As above (standard)
|Φ−⟩=12(|00⟩−|11⟩)Swap Z↔I for m0=1
|Ψ+⟩=12(|01⟩+|10⟩)Swap X↔I for m1=1
|Ψ−⟩=12(|01⟩−|10⟩)Both swaps combined

The Bell state must be shared before the protocol begins. In practice, this means either:

  • Alice creates the Bell pair and sends one qubit to Bob (quantum communication)
  • A third party creates the Bell pair and distributes one qubit to each
  • The Bell pair is generated by a quantum network node

Entanglement as a Resource ​

Teleportation consumes one unit of entanglement (one ebit, measured by the entropy of entanglement S(ρA)=1 bit) and two bits of classical communication to transmit one qubit of quantum information.

mermaid
graph LR
    A["1 ebit<br/>(Bell pair)"] --> C["Teleportation<br/>Protocol"]
    B["2 classical bits"] --> C
    C --> D["1 qubit<br/>transferred"]

    style A fill:#E3F2FD
    style B fill:#FFF3E0
    style D fill:#E8F5E9

This trade-off is optimal: it is impossible to teleport a qubit using less than one ebit and two classical bits. This follows from the fact that:

  • One ebit is necessary because without entanglement, the no-communication theorem forbids transmitting quantum information via classical channels alone.

  • Two classical bits are necessary because Alice's Bell measurement has four equally likely outcomes, and Bob needs to distinguish all four to apply the correct Pauli correction.

Practical Tips ​

1. Verify with known states first. Before teleporting an unknown state, test with |0⟩ and |1⟩ to confirm the correction logic is correct. These are easy to verify: the output should always be |0⟩ or |1⟩ with 100% fidelity.

2. Use DensityMatrixSimulator for debugging. When the CPUQVM results look wrong, switch to DensityMatrixSimulator to inspect the exact density matrix of Bob's qubit. This eliminates shot noise from the debugging process.

3. Check correction order. The corrections must be applied as Zm0Xm1, not Xm1Zm0. Because Pauli operators anticommute (ZX=−XZ), the wrong order introduces a global phase. While global phases are usually harmless, they matter in controlled operations and interference experiments.

4. Model hardware noise realistically. For hardware predictions, use gate-specific, qubit-specific noise models with error rates from calibration data. Typical superconducting hardware has 0.05-0.1% single-qubit gate error and 0.5-2% two-qubit gate error.

5. The teleportation circuit is a good hardware benchmark. Running teleportation on real hardware and measuring the output fidelity provides a direct assessment of entangling gate quality, readout fidelity, and overall system coherence. A fidelity below ~0.8 typically indicates significant hardware issues.

6. Dynamic circuits are essential. Teleportation cannot be implemented as a static circuit because the corrections depend on measurement outcomes. In pyqpanda3, use qif for the conditional Pauli corrections as shown in the code examples above.

Released under the MIT License.