测量与量子态层析

从量子态提取经典信息是量子计算的最后一步。本节展示态层析(完整重建密度矩阵) 和阴影层析(高效估计可观测量期望值)两种范式。

Full quantum state tomography — measurement example.

Source: examples/2_advanced/measurement/state_tomography.py
Status: pass

Demonstrates:

  • Reconstructing the density matrix via state tomography

  • Computing fidelity with the target state

  • Comparing tomography result with exact statevector

Usage: python state_tomography.py [–n-shots N]

References: James et al. (2001). “Measurement of qubits.” Physical Review A 64, 052312.

Source code

#!/usr/bin/env python
"""Full quantum state tomography — measurement example.

Demonstrates:
  * Reconstructing the density matrix via state tomography
  * Computing fidelity with the target state
  * Comparing tomography result with exact statevector

Usage:
    python state_tomography.py [--n-shots N]

References:
    James et al. (2001). "Measurement of qubits." Physical Review A 64, 052312.

[doc-require: ]
"""

import argparse
import sys
import numpy as np

sys.path.insert(0, str(__file__).rsplit("/", 2)[0])

from uniqc import Circuit
from uniqc.simulator import Simulator
from uniqc import state_tomography, tomography_summary


def run_tomography_demo(n_shots=2000):
    """Demonstrate full quantum state tomography.

    Args:
        n_shots: Number of shots per measurement basis.
    """
    print("Full State Tomography Demo")
    print("=" * 50)
    print(f"  Shots per basis: {n_shots}")

    # Build a test circuit: prepare a specific state
    # |ψ⟩ = (|00⟩ + i|11⟩)/√2  (Bell-like state with phase)
    c = Circuit()
    c.h(0)
    c.cx(0, 1)
    c.rz(1, np.pi / 2)

    print(f"\nCircuit: (|00⟩ + i|11⟩)/√2")

    # Compare with exact statevector first (used as the tomography reference).
    from uniqc.simulator import Simulator
    sim = Simulator(backend_type="statevector")
    sv = np.asarray(sim.simulate_statevector(c.originir), dtype=complex)
    exact_rho = np.outer(sv, sv.conj())

    # Perform tomography (returns the reconstructed density matrix directly).
    print(f"\nRunning tomography (3^2 = 9 measurement bases for 2 qubits)...")
    rho = state_tomography(c, qubits=[0, 1], shots=n_shots)

    # Pretty-print summary alongside the exact reference density matrix.
    summary = tomography_summary(rho, label="ρ_tomo", reference_state=exact_rho)
    print(f"\nTomography complete.")
    print(f"  Density matrix shape: {rho.shape}")
    print(f"  Fidelity ⟨ψ|ρ|ψ⟩: {summary['fidelity']:.6f}")
    print(f"  Trace of reconstructed ρ: {np.real(np.trace(rho)):.6f}")

    # Show diagonal (populations)
    print(f"\n  Populations:")
    for i in range(4):
        basis = format(i, "02b")
        pop_exact = np.real(exact_rho[i, i])
        pop_tomo = np.real(rho[i, i])
        print(f"    |{basis}⟩: exact={pop_exact:.4f}, tomography={pop_tomo:.4f}")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="State tomography demo")
    parser.add_argument("--n-shots", type=int, default=2000, help="Shots per basis")
    args = parser.parse_args()
    run_tomography_demo(n_shots=args.n_shots)

Stdout

Full State Tomography Demo
==================================================
  Shots per basis: 2000

Circuit: (|00⟩ + i|11⟩)/√2

Running tomography (3^2 = 9 measurement bases for 2 qubits)...
==================================================
State Tomography Summary  (label=ρ_tomo, n_qubits=2)
==================================================

Eigenvalues (largest first):
  λ_0 =  1.866025
  λ_1 =  0.133975
  λ_2 = -0.500000
  λ_3 = -0.500000

Purity  Tr(ρ²) = 4.000000  (mixed)
Trace   Tr(ρ)   = 1.000000

Fidelity F(ρ, σ) = 1.000000
==================================================


Tomography complete.
  Density matrix shape: (4, 4)
  Fidelity ⟨ψ|ρ|ψ⟩: 1.000000
  Trace of reconstructed ρ: 1.000000

  Populations:
    |00⟩: exact=0.5000, tomography=1.0000
    |01⟩: exact=0.0000, tomography=0.0000
    |10⟩: exact=0.0000, tomography=0.0000
    |11⟩: exact=0.5000, tomography=0.0000

Classical Shadow tomography — measurement example.

Source: examples/2_advanced/measurement/shadow_tomography.py
Status: pass

Demonstrates:

  • Using classical_shadow for efficient state characterisation

  • Computing shadow expectation values

  • Comparing shadow estimates with exact statevector

Usage: python shadow_tomography.py [–n-shots N] [–n-shadow N]

References: Huang, Kueng, Preskill (2020). “Predicting many properties of a quantum system from very few measurements.” Nature Physics 16, 1050–1057.

Source code

#!/usr/bin/env python
"""Classical Shadow tomography — measurement example.

Demonstrates:
  * Using classical_shadow for efficient state characterisation
  * Computing shadow expectation values
  * Comparing shadow estimates with exact statevector

Usage:
    python shadow_tomography.py [--n-shots N] [--n-shadow N]

References:
    Huang, Kueng, Preskill (2020). "Predicting many properties of a quantum
    system from very few measurements." Nature Physics 16, 1050–1057.

[doc-require: ]
"""

import argparse
import sys
import numpy as np

sys.path.insert(0, str(__file__).rsplit("/", 2)[0])

from uniqc import Circuit
from uniqc.simulator import Simulator
from uniqc import classical_shadow, shadow_expectation


def run_shadow_demo(n_shots=1000, n_shadow=100):
    """Demonstrate Classical Shadow tomography.

    Args:
        n_shots: Shots per measurement basis.
        n_shadow: Number of shadow snapshots.
    """
    print("Classical Shadow Tomography Demo")
    print("=" * 50)
    print(f"  Shots per basis: {n_shots}")
    print(f"  Shadow snapshots: {n_shadow}")

    # Build a simple test circuit: Bell state |Φ⁺⟩
    c = Circuit()
    c.h(0)
    c.cx(0, 1)

    print(f"\nCircuit: Bell state |Φ⁺⟩ = (|00⟩ + |11⟩)/√2")

    # 1. Perform classical shadow measurement
    print(f"\nPerforming {n_shadow} shadow measurements...")
    shadows = classical_shadow(c, qubits=[0, 1], shots=n_shots, n_shadow=n_shadow)
    print(f"  Collected {len(shadows)} shadow snapshots")

    # 2. Estimate ⟨Z₀⟩ (Z on qubit 0, identity on qubit 1)
    est_z0 = shadow_expectation(shadows, "ZI")
    print(f"\n  ⟨Z₀⟩ estimate: {est_z0:.4f} (exact: 0.0)")

    # 3. Estimate ⟨Z₀Z₁⟩
    est_z0z1 = shadow_expectation(shadows, "ZZ")
    print(f"  ⟨Z₀Z₁⟩ estimate: {est_z0z1:.4f} (exact: 1.0)")

    # 4. Estimate ⟨X₀⟩
    est_x0 = shadow_expectation(shadows, "XI")
    print(f"  ⟨X₀⟩ estimate: {est_x0:.4f} (exact: 1/√2 ≈ 0.707)")

    # 5. Compare with exact values
    from uniqc.simulator import Simulator
    sim = Simulator(backend_type="statevector")
    sv = np.asarray(sim.simulate_statevector(c.originir), dtype=complex)

    Z = np.array([[1, 0], [0, -1]])
    I = np.eye(2)
    exact_z0 = np.real(sv.conj() @ np.kron(Z, I) @ sv)
    exact_z0z1 = np.real(sv.conj() @ np.kron(Z, Z) @ sv)

    print(f"\n  Exact ⟨Z₀⟩ = {exact_z0:.4f}")
    print(f"  Exact ⟨Z₀Z₁⟩ = {exact_z0z1:.4f}")

    print(f"\n✓ Shadow estimation complete with {n_shadow} snapshots")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Classical Shadow tomography demo")
    parser.add_argument("--n-shots", type=int, default=1000, help="Shots per basis")
    parser.add_argument("--n-shadow", type=int, default=100, help="Shadow snapshots")
    args = parser.parse_args()
    run_shadow_demo(n_shots=args.n_shots, n_shadow=args.n_shadow)

Stdout

Classical Shadow Tomography Demo
==================================================
  Shots per basis: 1000
  Shadow snapshots: 100

Circuit: Bell state |Φ⁺⟩ = (|00⟩ + |11⟩)/√2

Performing 100 shadow measurements...
  Collected 100 shadow snapshots

  ⟨Z₀⟩ estimate: 1.0200 (exact: 0.0)
  ⟨Z₀Z₁⟩ estimate: 0.9900 (exact: 1.0)
  ⟨X₀⟩ estimate: 0.9900 (exact: 1/√2 ≈ 0.707)

  Exact ⟨Z₀⟩ = 0.0000
  Exact ⟨Z₀Z₁⟩ = 1.0000

✓ Shadow estimation complete with 100 snapshots