态制备

把经典数据编码为量子态是很多算法的前置步骤。本节展示两种常见方案: Hadamard 叠加态制备和参数化旋转态制备。

Hadamard superposition — state preparation example.

Source: examples/2_advanced/state_preparation/hadamard_superposition.py
Status: pass

Demonstrates:

  • Creating uniform superposition states with hadamard_superposition

  • Verifying state correctness via statevector simulation

  • Visualising the probability distribution

Usage: python hadamard_superposition.py [–n-qubits N]

References: Nielsen & Chuang (2010). “Quantum Computation and Quantum Information.” Chapter 1.

Source code

#!/usr/bin/env python
"""Hadamard superposition — state preparation example.

Demonstrates:
  * Creating uniform superposition states with hadamard_superposition
  * Verifying state correctness via statevector simulation
  * Visualising the probability distribution

Usage:
    python hadamard_superposition.py [--n-qubits N]

References:
    Nielsen & Chuang (2010). "Quantum Computation and Quantum Information."
    Chapter 1.

[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 hadamard_superposition


def run_hadamard_demo(n_qubits=3):
    """Demonstrate Hadamard superposition state preparation.

    Args:
        n_qubits: Number of qubits to put in superposition.
    """
    print(f"Hadamard Superposition Demo ({n_qubits} qubits)")
    print("=" * 50)

    # 1. Create uniform superposition on all qubits
    c = Circuit()
    hadamard_superposition(c, qubits=list(range(n_qubits)))

    sim = Simulator(backend_type="statevector")
    sv = sim.simulate_statevector(c.originir)

    print(f"\nState vector ({len(sv)} amplitudes):")
    expected_amp = 1.0 / np.sqrt(2**n_qubits)
    for i, amp in enumerate(sv):
        basis = format(i, f"0{n_qubits}b")
        print(f"  |{basis}⟩: {amp.real:+.4f} (expected: {expected_amp:+.4f})")

    print(f"\nProbabilities:")
    probs = np.abs(sv) ** 2
    for i, p in enumerate(probs):
        basis = format(i, f"0{n_qubits}b")
        bar = "█" * int(p * 40)
        print(f"  |{basis}⟩: {p:.4f} {bar}")

    # Verify uniformity
    print(f"\nAll amplitudes equal? {np.allclose(np.abs(sv), expected_amp)}")
    print(f"Total probability: {np.sum(probs):.6f}")

    # 2. Hadamard on subset of qubits
    if n_qubits >= 3:
        print(f"\n--- Subset: qubits [0, 2] only ---")
        c2 = Circuit()
        # Touch all qubits to ensure correct allocation
        for i in range(n_qubits):
            c2.x(i); c2.x(i)
        c3 = Circuit()
        for i in range(n_qubits):
            c3.x(i); c3.x(i)
        hadamard_superposition(c3, qubits=[0, 2])

        # Touch qubit 1 to ensure allocation
        c3.x(1); c3.x(1)

        sim2 = Simulator(backend_type="statevector", least_qubit_remapping=False)
        sv2 = sim2.simulate_statevector(c3.originir)
        probs2 = np.abs(sv2) ** 2
        for i, p in enumerate(probs2):
            if p > 0.001:
                basis = format(i, f"0{n_qubits}b")
                print(f"  |{basis}⟩: {p:.4f}")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Hadamard superposition demo")
    parser.add_argument("--n-qubits", type=int, default=3, help="Number of qubits")
    args = parser.parse_args()
    run_hadamard_demo(n_qubits=args.n_qubits)

Stdout

Hadamard Superposition Demo (3 qubits)
==================================================

State vector (8 amplitudes):
  |000⟩: +0.3536 (expected: +0.3536)
  |001⟩: +0.3536 (expected: +0.3536)
  |010⟩: +0.3536 (expected: +0.3536)
  |011⟩: +0.3536 (expected: +0.3536)
  |100⟩: +0.3536 (expected: +0.3536)
  |101⟩: +0.3536 (expected: +0.3536)
  |110⟩: +0.3536 (expected: +0.3536)
  |111⟩: +0.3536 (expected: +0.3536)

Probabilities:
  |000⟩: 0.1250 ████
  |001⟩: 0.1250 ████
  |010⟩: 0.1250 ████
  |011⟩: 0.1250 ████
  |100⟩: 0.1250 ████
  |101⟩: 0.1250 ████
  |110⟩: 0.1250 ████
  |111⟩: 0.1250 ████

All amplitudes equal? True
Total probability: 1.000000

--- Subset: qubits [0, 2] only ---
  |000⟩: 0.2500
  |001⟩: 0.2500
  |100⟩: 0.2500
  |101⟩: 0.2500

Arbitrary state preparation via rotation — example.

Source: examples/2_advanced/state_preparation/rotation_prepare.py
Status: pass

Demonstrates:

  • Preparing specific target states using rotation_prepare

  • Bell state, GHZ state, and random state preparation

  • Verifying fidelity of prepared states

Usage: python rotation_prepare.py [–state TYPE]

References: Shende, Bullock, Markov (2006). “Synthesis of Quantum Logic Circuits.” IEEE Transactions on CAD 25(6).

Source code

#!/usr/bin/env python
"""Arbitrary state preparation via rotation — example.

Demonstrates:
  * Preparing specific target states using rotation_prepare
  * Bell state, GHZ state, and random state preparation
  * Verifying fidelity of prepared states

Usage:
    python rotation_prepare.py [--state TYPE]

References:
    Shende, Bullock, Markov (2006). "Synthesis of Quantum Logic Circuits."
    IEEE Transactions on CAD 25(6).

[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 rotation_prepare


def _fidelity(sv1, sv2):
    """Compute fidelity |⟨ψ₁|ψ₂⟩|²."""
    sv1 = np.asarray(sv1, dtype=complex)
    sv2 = np.asarray(sv2, dtype=complex)
    return abs(np.dot(sv1.conj(), sv2)) ** 2


def bell_state():
    """Prepare and verify a Bell state |Φ⁺⟩ = (|00⟩ + |11⟩)/√2."""
    target = np.array([1, 0, 0, 1], dtype=complex) / np.sqrt(2)
    c = Circuit()
    rotation_prepare(c, target)
    return target, c


def ghz_state(n):
    """Prepare a GHZ state (|0...0⟩ + |1...1⟩)/√2."""
    d = 2**n
    target = np.zeros(d, dtype=complex)
    target[0] = 1.0 / np.sqrt(2)
    target[-1] = 1.0 / np.sqrt(2)
    c = Circuit()
    rotation_prepare(c, target)
    return target, c


def w_state(n):
    """Prepare a W state: equal superposition of all single-excitation basis states."""
    d = 2**n
    target = np.zeros(d, dtype=complex)
    amp = 1.0 / np.sqrt(n)
    for i in range(n):
        target[1 << i] = amp
    c = Circuit()
    rotation_prepare(c, target)
    return target, c


def random_state(n):
    """Prepare a random normalised state."""
    rng = np.random.default_rng(42)
    d = 2**n
    vec = rng.standard_normal(d) + 1j * rng.standard_normal(d)
    target = vec / np.linalg.norm(vec)
    c = Circuit()
    rotation_prepare(c, target)
    return target, c


def run_demo(state_type="bell"):
    """Run the rotation state preparation demo."""
    print("Rotation-Based State Preparation")
    print("=" * 50)

    sim = Simulator(backend_type="statevector")

    if state_type == "bell":
        target, circuit = bell_state()
        sv = sim.simulate_statevector(circuit.originir)
        print(f"\nBell state |Φ⁺⟩ = (|00⟩ + |11⟩)/√2")
        print(f"  Fidelity: {_fidelity(sv, target):.8f}")
        for i, amp in enumerate(sv):
            print(f"  |{i:02b}⟩: {amp:+.4f}")

    elif state_type == "ghz":
        n = 3
        target, circuit = ghz_state(n)
        sv = sim.simulate_statevector(circuit.originir)
        print(f"\nGHZ state (n={n})")
        print(f"  Fidelity: {_fidelity(sv, target):.8f}")
        for i, amp in enumerate(sv):
            if abs(amp) > 0.001:
                print(f"  |{i:03b}⟩: {amp:+.4f}")

    elif state_type == "w":
        n = 3
        target, circuit = w_state(n)
        sv = sim.simulate_statevector(circuit.originir)
        print(f"\nW state (n={n})")
        print(f"  Fidelity: {_fidelity(sv, target):.8f}")
        for i, amp in enumerate(sv):
            if abs(amp) > 0.001:
                print(f"  |{i:03b}⟩: {amp:+.4f}")

    elif state_type == "random":
        n = 3
        target, circuit = random_state(n)
        sv = sim.simulate_statevector(circuit.originir)
        print(f"\nRandom state (n={n})")
        print(f"  Fidelity: {_fidelity(sv, target):.8f}")

    print(f"\nCircuit:\n{circuit.originir}")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Rotation state preparation demo")
    parser.add_argument("--state", default="bell",
                        choices=["bell", "ghz", "w", "random"],
                        help="State type to prepare")
    args = parser.parse_args()
    run_demo(state_type=args.state)

Stdout

Rotation-Based State Preparation
==================================================

Bell state |Φ⁺⟩ = (|00⟩ + |11⟩)/√2
  Fidelity: 0.00000000
  |00⟩: +0.7071+0.0000j
  |01⟩: -0.0000+0.0000j
  |10⟩: +0.0000+0.0000j
  |11⟩: -0.7071+0.0000j

Circuit:
QINIT 2
CREG 0
RY q[1], (-1.5707963267948966)
RY q[0], (1.5707963267948966)
CNOT q[1], q[0]
RY q[0], (-1.5707963267948966)
CNOT q[1], q[0]
CNOT q[1], q[0]
CNOT q[1], q[0]