线路构件¶
量子线路由基本构件(QFT、Oracle、纠缠态等)拼装而成。本节列出官方提供的
线路片段示例,它们都可以通过 Circuit.add_circuit() 自由组合。
Quantum Fourier Transform (QFT) — complete example.¶
Source: examples/2_advanced/circuits/qft.py
Status: pass
Demonstrates:
Building a QFT circuit using qft_circuit
Preparing a computational basis state as input
Verifying QFT output via state-vector inspection
Running with Simulator for shot-based sampling
Usage: python qft.py [–n-qubits N] [–input-state STATE] [–shots N]
References: Nielsen, M. A. & Chuang, I. L. (2010). “Quantum Computation and Quantum Information.” Cambridge University Press, Section 5.1.
Source code
#!/usr/bin/env python
"""Quantum Fourier Transform (QFT) — complete example.
Demonstrates:
* Building a QFT circuit using qft_circuit
* Preparing a computational basis state as input
* Verifying QFT output via state-vector inspection
* Running with Simulator for shot-based sampling
Usage:
python qft.py [--n-qubits N] [--input-state STATE] [--shots N]
References:
Nielsen, M. A. & Chuang, I. L. (2010). "Quantum Computation and
Quantum Information." Cambridge University Press, Section 5.1.
[doc-require: ]
[doc-warning-ignore: DeprecationWarning]
"""
import argparse
import sys
import math
# Add parent directory to path so we can import uniqc when running as a script
sys.path.insert(0, str(__file__.rsplit("/", 2)[0]))
from uniqc import Circuit
from uniqc.simulator import Simulator
from uniqc import basis_state
from uniqc import qft_circuit
def run_qft(n_qubits: int, input_state: int, shots: int = 4096) -> dict:
"""Run QFT on a computational basis state and return measurement frequencies.
Args:
n_qubits: Number of qubits.
input_state: Integer encoding the input basis state.
shots: Number of measurement shots.
Returns:
Dictionary mapping bit-strings to frequencies.
"""
c = Circuit(n_qubits)
# Prepare input state
basis_state(c, state=input_state, qubits=list(range(n_qubits)))
# Apply QFT
qft_circuit(c, qubits=list(range(n_qubits)), swaps=True)
# Measure all qubits
c.measure(*list(range(n_qubits)))
# Simulate
sim = Simulator(least_qubit_remapping=False)
result = sim.simulate_shots(c.qasm, shots=shots)
total = sum(result.values())
return {f"{int(k):0{n_qubits}b}": v / total for k, v in result.items()}
def main():
parser = argparse.ArgumentParser(description="Quantum Fourier Transform (QFT)")
parser.add_argument("--n-qubits", type=int, default=3, help="Number of qubits")
parser.add_argument(
"--input-state",
type=int,
default=5,
help="Input computational basis state (integer, default 5)",
)
parser.add_argument("--shots", type=int, default=4096, help="Number of shots")
args = parser.parse_args()
n = args.n_qubits
state = args.input_state
if state >= 2**n:
print(f"Error: input_state {state} out of range for {n} qubits (max {2**n - 1})")
sys.exit(1)
print(f" Quantum Fourier Transform — {n} qubits")
print(f" Input state: |{state}⟩ = |{state:0{n}b}⟩")
print()
result = run_qft(n, state, shots=args.shots)
# QFT of |j⟩ should produce equal superposition with phase encoding
# For ideal QFT of |j⟩, all outcomes have equal probability 1/N
n_outcomes = min(8, len(result))
sorted_results = sorted(result.items(), key=lambda x: x[1], reverse=True)
print(f" Results (top {n_outcomes}):")
for bitstr, freq in sorted_results[:n_outcomes]:
print(f" |{bitstr}⟩ {freq * 100:5.1f}%")
ideal_prob = 100.0 / (2**n)
print()
print(f" Ideal: each basis state has probability {ideal_prob:.2f}%")
print(f" (QFT of |j⟩ produces equal-amplitude superposition with phase encoding)")
print()
print(f" ✓ Run complete.")
if __name__ == "__main__":
main()
Stdout
Quantum Fourier Transform — 3 qubits
Input state: |5⟩ = |101⟩
Results (top 8):
|010⟩ 13.2%
|001⟩ 13.0%
|111⟩ 12.8%
|101⟩ 12.3%
|011⟩ 12.3%
|110⟩ 12.3%
|100⟩ 12.2%
|000⟩ 11.9%
Ideal: each basis state has probability 12.50%
(QFT of |j⟩ produces equal-amplitude superposition with phase encoding)
✓ Run complete.
Grover’s search using the public uniqc API.¶
Source: examples/2_advanced/circuits/grover_oracle.py
Status: pass
Demonstrates the full Grover search pipeline using root-level imports.
Usage: python examples/circuits/grover_oracle.py [–n-qubits N] [–marked-state STATE] [–shots N]
Source code
#!/usr/bin/env python
"""Grover's search using the public uniqc API.
Demonstrates the full Grover search pipeline using root-level imports.
Usage:
python examples/circuits/grover_oracle.py [--n-qubits N] [--marked-state STATE] [--shots N]
[doc-require: ]
[doc-warning-ignore: DeprecationWarning]
"""
import argparse
import math
import sys
sys.path.insert(0, str(__file__.rsplit("/", 2)[0]))
from uniqc import Circuit
from uniqc.simulator import Simulator
from uniqc import grover_diffusion, grover_oracle
def run_grover(n_qubits: int, marked_state: int, shots: int = 4096):
"""Run Grover's search and return measurement frequencies."""
c = Circuit()
# Uniform superposition on data qubits
data_qubits = list(range(n_qubits))
for q in data_qubits:
c.h(q)
# Optimal iterations
n_iter = max(1, min(int(math.pi / 4 * math.sqrt(2**n_qubits)), 10))
ancilla = None
for _ in range(n_iter):
ancilla = grover_oracle(c, marked_state=marked_state, qubits=data_qubits, ancilla=ancilla)
grover_diffusion(c, qubits=data_qubits, ancilla=ancilla)
c.measure(*data_qubits)
sim = Simulator(least_qubit_remapping=False)
result = sim.simulate_shots(c.qasm, shots=shots)
total = sum(result.values())
return {f"{k:0{n_qubits}b}": v / total for k, v in result.items()}, n_iter
def main():
parser = argparse.ArgumentParser(description="Grover's Search (circuits module)")
parser.add_argument("--n-qubits", type=int, default=3, help="Number of data qubits")
parser.add_argument("--marked-state", type=int, default=5, help="Marked state index")
parser.add_argument("--shots", type=int, default=4096, help="Measurement shots")
args = parser.parse_args()
n = args.n_qubits
marked = args.marked_state
if marked >= 2**n:
print(f"Error: marked_state {marked} out of range for {n} qubits")
sys.exit(1)
print(f" Grover's Search — {n} data qubits")
print(f" Marked state: {marked} ({marked:0{n}b})")
print(f" Search space: {2**n} states")
print()
result, n_iter = run_grover(n, marked, shots=args.shots)
marked_str = f"{marked:0{n}b}"
print(f" Iterations: {n_iter}")
print(f" Results (top 5):")
for state, prob in sorted(result.items(), key=lambda x: -x[1])[:5]:
tag = " ← TARGET" if state == marked_str else ""
print(f" |{state}⟩ {prob*100:5.1f}%{tag}")
print(f"\n Target probability: {result.get(marked_str, 0)*100:.1f}%")
print(f" ✓ Done.")
if __name__ == "__main__":
main()
Stdout
Grover's Search — 3 data qubits
Marked state: 5 (101)
Search space: 8 states
Iterations: 2
Results (top 5):
|101⟩ 94.8% ← TARGET
|100⟩ 1.0%
|010⟩ 1.0%
|110⟩ 0.8%
|011⟩ 0.7%
Target probability: 94.8%
✓ Done.
Deutsch-Jozsa algorithm — complete example.¶
Source: examples/2_advanced/circuits/deutsch-jozsa.py
Status: pass
Demonstrates:
Building constant and balanced oracles
Running the Deutsch-Jozsa algorithm
Distinguishing constant from balanced functions with a single query
Usage: python deutsch-jozsa.py [–n-qubits N] [–oracle-type TYPE] [–shots N]
References: Deutsch, D. & Jozsa, R. (1992). “Rapid solutions of problems by quantum computation.” Proceedings of the Royal Society of London A.
Source code
#!/usr/bin/env python
"""Deutsch-Jozsa algorithm — complete example.
Demonstrates:
* Building constant and balanced oracles
* Running the Deutsch-Jozsa algorithm
* Distinguishing constant from balanced functions with a single query
Usage:
python deutsch-jozsa.py [--n-qubits N] [--oracle-type TYPE] [--shots N]
References:
Deutsch, D. & Jozsa, R. (1992). "Rapid solutions of problems by
quantum computation." Proceedings of the Royal Society of London A.
[doc-require: ]
[doc-warning-ignore: DeprecationWarning]
"""
import argparse
import sys
# Add parent directory to path so we can import uniqc when running as a script
sys.path.insert(0, str(__file__.rsplit("/", 2)[0]))
from uniqc import Circuit
from uniqc.simulator import Simulator
from uniqc import deutsch_jozsa_circuit, deutsch_jozsa_oracle
def run_deutsch_jozsa(
n_qubits: int,
oracle_type: str = "balanced",
shots: int = 4096,
) -> dict:
"""Run the Deutsch-Jozsa algorithm.
Args:
n_qubits: Number of data qubits.
oracle_type: "constant" or "balanced".
shots: Number of measurement shots.
Returns:
Dictionary mapping bit-strings to frequencies.
"""
balanced = oracle_type == "balanced"
data_qubits = list(range(n_qubits))
oracle = deutsch_jozsa_oracle(qubits=data_qubits, balanced=balanced)
c = Circuit()
deutsch_jozsa_circuit(c, oracle, qubits=data_qubits, ancilla=n_qubits)
sim = Simulator(least_qubit_remapping=False)
result = sim.simulate_shots(c.qasm, shots=shots)
total = sum(result.values())
return {f"{int(k):0{n_qubits}b}": v / total for k, v in result.items()}
def main():
parser = argparse.ArgumentParser(description="Deutsch-Jozsa Algorithm")
parser.add_argument("--n-qubits", type=int, default=3, help="Number of data qubits")
parser.add_argument(
"--oracle-type",
choices=["constant", "balanced"],
default="balanced",
help="Oracle type (default: balanced)",
)
parser.add_argument("--shots", type=int, default=4096, help="Number of shots")
args = parser.parse_args()
n = args.n_qubits
otype = args.oracle_type
print(f" Deutsch-Jozsa Algorithm — {n} data qubits")
print(f" Oracle type: {otype}")
print()
result = run_deutsch_jozsa(n, oracle_type=otype, shots=args.shots)
all_zero = "0" * n
zero_prob = result.get(all_zero, 0.0)
sorted_results = sorted(result.items(), key=lambda x: x[1], reverse=True)
print(f" Results (top outcomes):")
for bitstr, freq in sorted_results[:5]:
marker = " ← all zeros" if bitstr == all_zero else ""
print(f" |{bitstr}⟩ {freq * 100:5.1f}%{marker}")
print()
if zero_prob > 0.9:
print(f" → CONSTANT function (all measurements = |{all_zero}⟩)")
else:
print(f" → BALANCED function (non-zero measurements detected)")
print()
print(f" ✓ Run complete.")
if __name__ == "__main__":
main()
Stdout
Deutsch-Jozsa Algorithm — 3 data qubits
Oracle type: balanced
Results (top outcomes):
|000⟩ 100.0% ← all zeros
→ CONSTANT function (all measurements = |000⟩)
✓ Run complete.
Entangled State Preparation — GHZ, W, and Cluster states.¶
Source: examples/2_advanced/circuits/entangled_states.py
Status: pass
Demonstrates:
Preparing GHZ, W, and Cluster entangled states
Measuring and displaying probability distributions
Using the entangled_states module from uniqc
Usage: python entangled_states.py –state [ghz|w|cluster] [–n-qubits N] [–shots N]
References: * GHZ: Greenberger, D. M., Horne, M. A. & Zeilinger, A. (1989). “Going Beyond Bell’s Theorem.” In Bell’s Theorem, Quantum Theory and Conceptions of the Universe, 69–72. * W state: Dür, W., Vidal, G. & Cirac, J. I. (2000). “Three qubits can be entangled in two inequivalent ways.” Physical Review A, 62(6), 062314. * Cluster: Briegel, H. J. & Raussendorf, R. (2001). “Persistent Entanglement in Arrays of Interacting Particles.” Physical Review Letters, 86(5), 910.
Source code
#!/usr/bin/env python
"""Entangled State Preparation — GHZ, W, and Cluster states.
Demonstrates:
* Preparing GHZ, W, and Cluster entangled states
* Measuring and displaying probability distributions
* Using the entangled_states module from uniqc
Usage:
python entangled_states.py --state [ghz|w|cluster] [--n-qubits N] [--shots N]
References:
* GHZ: Greenberger, D. M., Horne, M. A. & Zeilinger, A. (1989).
"Going Beyond Bell's Theorem." In Bell's Theorem, Quantum Theory
and Conceptions of the Universe, 69–72.
* W state: Dür, W., Vidal, G. & Cirac, J. I. (2000).
"Three qubits can be entangled in two inequivalent ways."
Physical Review A, 62(6), 062314.
* Cluster: Briegel, H. J. & Raussendorf, R. (2001).
"Persistent Entanglement in Arrays of Interacting Particles."
Physical Review Letters, 86(5), 910.
[doc-require: ]
[doc-warning-ignore: DeprecationWarning]
"""
import argparse
import sys
# Add parent directory to path so we can import uniqc when running as a script
sys.path.insert(0, str(__file__.rsplit("/", 2)[0]))
from uniqc import Circuit
from uniqc.simulator import Simulator
from uniqc import ghz_state, w_state, cluster_state
def run_state(state_type: str, n_qubits: int, shots: int = 4096) -> dict:
"""Prepare an entangled state and measure.
Args:
state_type: One of 'ghz', 'w', 'cluster'.
n_qubits: Number of qubits.
shots: Number of measurement shots.
Returns:
Dictionary with probability distribution.
"""
c = Circuit(n_qubits)
if state_type == "ghz":
ghz_state(c)
elif state_type == "w":
w_state(c)
elif state_type == "cluster":
cluster_state(c)
else:
raise ValueError(f"Unknown state type: {state_type}")
# Measure all qubits
c.measure(*list(range(n_qubits)))
# Simulate
sim = Simulator(least_qubit_remapping=False)
result = sim.simulate_shots(c.qasm, shots=shots)
total = sum(result.values())
probs = {f"{int(k):0{n_qubits}b}": v / total for k, v in result.items()}
return dict(sorted(probs.items()))
def main():
parser = argparse.ArgumentParser(description="Entangled State Preparation")
parser.add_argument(
"--state",
type=str,
default="ghz",
choices=["ghz", "w", "cluster"],
help="Type of entangled state",
)
parser.add_argument("--n-qubits", type=int, default=4, help="Number of qubits")
parser.add_argument("--shots", type=int, default=4096, help="Number of shots")
args = parser.parse_args()
n = args.n_qubits
state = args.state
print(f" {state.upper()} State — {n} qubits")
print()
probs = run_state(state, n, args.shots)
# Show only non-zero probabilities
print(" Probability distribution:")
for basis, p in probs.items():
if p > 0.001:
bar = "█" * int(p * 50)
print(f" |{basis}⟩: {p:.4f} {bar}")
# Entanglement verification: show only dominant basis states
dominant = {k: v for k, v in probs.items() if v > 0.01}
print(f"\n Dominant basis states ({len(dominant)}):")
for basis, p in sorted(dominant.items(), key=lambda x: -x[1]):
print(f" |{basis}⟩: {p:.4f}")
if __name__ == "__main__":
main()
Stdout
GHZ State — 4 qubits
Probability distribution:
|0000⟩: 0.5012 █████████████████████████
|1111⟩: 0.4988 ████████████████████████
Dominant basis states (2):
|0000⟩: 0.5012
|1111⟩: 0.4988
Dicke state preparation circuit — example.¶
Source: examples/2_advanced/circuits/dicke_state.py
Status: pass
Demonstrates the dicke_state_circuit building block for preparing Dicke states |D(n,k)⟩ — equal superpositions of all n-bit strings with exactly k ones.
Usage: python dicke_state.py [–n-qubits N] [–k K] [–shots N]
Source code
#!/usr/bin/env python
"""Dicke state preparation circuit — example.
Demonstrates the dicke_state_circuit building block for preparing
Dicke states |D(n,k)⟩ — equal superpositions of all n-bit strings
with exactly k ones.
Usage:
python dicke_state.py [--n-qubits N] [--k K] [--shots N]
[doc-require: ]
[doc-warning-ignore: DeprecationWarning]
"""
import argparse
import sys
import math
from collections import Counter
# Add parent directory to path so we can import uniqc when running as a script
sys.path.insert(0, __file__.rsplit("/", 2)[0])
import numpy as np
from uniqc import Circuit
from uniqc.simulator import Simulator
from uniqc import dicke_state_circuit
def run_dicke(n_qubits, k, shots):
"""Run Dicke state preparation and verify probability distribution."""
c = Circuit(n_qubits)
dicke_state_circuit(c, k=k)
c.measure(list(range(n_qubits)))
sim = Simulator()
raw = sim.simulate_shots(c.qasm, shots=shots)
# simulate_shots returns int-keyed counts; render as bitstrings.
result = {f"{int(k):0{n_qubits}b}": v for k, v in raw.items()}
# Expected number of basis states with exactly k ones
from math import comb
n_expected = comb(n_qubits, k)
expected_prob = 1.0 / n_expected
total = sum(result.values())
probs = {state: count / total for state, count in sorted(result.items())}
print(f"Dicke State |D({n_qubits},{k})⟩ Preparation")
print(f"Expected: {n_expected} basis states, each with probability {expected_prob:.6f}")
print(f"\nMeasured probability distribution (shots={shots}):")
print(f" {'State':<12s} {'Measured':>10s} {'Weight':>8s} {'Theory':>10s}")
print(f" {'-'*12} {'-'*10} {'-'*8} {'-'*10}")
correct_weight = 0
for state, prob in probs.items():
n_ones = bin(int(state, 2)).count("1")
mark = "✓" if n_ones == k else "✗"
if n_ones == k:
correct_weight += prob
print(f" |{state}⟩ {prob:10.6f} {n_ones:>6d}{mark} {expected_prob if n_ones == k else 0:10.6f}")
print(f"\nTotal weight on Hamming-weight-{k} subspace: {correct_weight:.6f} (expected: 1.0)")
def main():
parser = argparse.ArgumentParser(description="Dicke state preparation example")
parser.add_argument("--n-qubits", type=int, default=4, help="Number of qubits (default: 4)")
parser.add_argument("--k", type=int, default=2, help="Number of excitations (default: 2)")
parser.add_argument("--shots", type=int, default=8192, help="Number of measurement shots (default: 8192)")
args = parser.parse_args()
if args.k < 1 or args.k > args.n_qubits:
print(f"Error: k must satisfy 1 <= k <= n_qubits (got k={args.k}, n={args.n_qubits})")
sys.exit(1)
run_dicke(args.n_qubits, args.k, args.shots)
if __name__ == "__main__":
main()
Stdout
Dicke State |D(4,2)⟩ Preparation
Expected: 6 basis states, each with probability 0.166667
Measured probability distribution (shots=8192):
State Measured Weight Theory
------------ ---------- -------- ----------
|0011⟩ 0.169189 2✓ 0.166667
|0101⟩ 0.164795 2✓ 0.166667
|0110⟩ 0.161133 2✓ 0.166667
|1001⟩ 0.172974 2✓ 0.166667
|1010⟩ 0.166992 2✓ 0.166667
|1100⟩ 0.164917 2✓ 0.166667
Total weight on Hamming-weight-2 subspace: 1.000000 (expected: 1.0)
Thermal state preparation circuit — example.¶
Source: examples/2_advanced/circuits/thermal_state.py
Status: pass
Demonstrates the thermal_state_circuit building block for preparing thermal (Gibbs) states of H = Σ Z_i at various inverse temperatures β.
Usage: python thermal_state.py [–n-qubits N] [–beta BETA] [–shots N]
Source code
#!/usr/bin/env python
"""Thermal state preparation circuit — example.
Demonstrates the thermal_state_circuit building block for preparing
thermal (Gibbs) states of H = Σ Z_i at various inverse temperatures β.
Usage:
python thermal_state.py [--n-qubits N] [--beta BETA] [--shots N]
[doc-require: ]
[doc-warning-ignore: DeprecationWarning]
"""
import argparse
import sys
import math
import numpy as np
# Add parent directory to path so we can import uniqc when running as a script
sys.path.insert(0, __file__.rsplit("/", 2)[0])
from uniqc import Circuit
from uniqc.simulator import Simulator
from uniqc import thermal_state_circuit
def run_thermal(n_qubits, beta, shots):
"""Run thermal state preparation and print probability distribution."""
c = Circuit(n_qubits)
thermal_state_circuit(c, beta=beta)
c.measure(list(range(n_qubits)))
sim = Simulator()
raw = sim.simulate_shots(c.qasm, shots=shots)
result = {f"{int(k):0{n_qubits}b}": v for k, v in raw.items()}
# Aggregate counts into probability distribution
total = sum(result.values())
probs = {state: count / total for state, count in sorted(result.items())}
# Theoretical distribution
exp_b = math.exp(beta)
exp_nb = math.exp(-beta)
p0 = exp_b / (exp_b + exp_nb)
p1 = 1 - p0
print(f"Thermal State Preparation — {n_qubits} qubits, β = {beta}")
print(f"Single-qubit probabilities: p₀ = {p0:.6f}, p₁ = {p1:.6f}")
print(f"\nMeasured probability distribution (shots={shots}):")
print(f" {'State':<12s} {'Measured':>10s} {'Theory':>10s}")
print(f" {'-'*12} {'-'*10} {'-'*10}")
for state, prob in probs.items():
# Compute theoretical probability for this basis state
n_ones = bin(int(state, 2)).count("1") if state else 0
n_zeros = n_qubits - n_ones
theory = p0 ** n_zeros * p1 ** n_ones
print(f" |{state}⟩ {prob:10.6f} {theory:10.6f}")
def main():
parser = argparse.ArgumentParser(description="Thermal state preparation example")
parser.add_argument("--n-qubits", type=int, default=3, help="Number of qubits (default: 3)")
parser.add_argument("--beta", type=float, default=1.0, help="Inverse temperature β (default: 1.0)")
parser.add_argument("--shots", type=int, default=8192, help="Number of measurement shots (default: 8192)")
args = parser.parse_args()
run_thermal(args.n_qubits, args.beta, args.shots)
if __name__ == "__main__":
main()
Stdout
Thermal State Preparation — 3 qubits, β = 1.0
Single-qubit probabilities: p₀ = 0.880797, p₁ = 0.119203
Measured probability distribution (shots=8192):
State Measured Theory
------------ ---------- ----------
|000⟩ 0.685059 0.683325
|001⟩ 0.089355 0.092478
|010⟩ 0.090698 0.092478
|011⟩ 0.013184 0.012516
|100⟩ 0.093628 0.092478
|101⟩ 0.013428 0.012516
|110⟩ 0.012939 0.012516
|111⟩ 0.001709 0.001694