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