InteractiveQAOATool / src /viz /circuits.py
speederracer123's picture
Upload 17 files
d3527de verified
Raw
History Blame Contribute Delete
2.97 kB
"""
Qiskit circuit diagrams for each QAOA module and each construction stage.
Stages
------
"init" : Hadamard initialization only.
"cost" : Init + Cost Layer (Rz / Rzz gates).
"full" : Init + Cost Layer + Mixer Layer + measurement barrier.
Modes
-----
"standard" : 3-qubit unconstrained (sparse connectivity).
"equality" : 3-qubit equality penalty (fully connected K3).
"inequality" : 4-qubit slack variable (fully connected K4, q3 labelled s).
All functions return a Matplotlib Figure.
"""
import matplotlib
matplotlib.use("Agg") # non-interactive backend for Streamlit
import matplotlib.pyplot as plt
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
_GAMMA = Parameter("γ")
_BETA = Parameter("β")
def _make_circuit(stage: str, mode: str) -> QuantumCircuit:
"""Build the symbolic QuantumCircuit for the requested stage and mode."""
n = 4 if mode == "inequality" else 3
# Named qubit registers so the slack qubit shows as 's'
if mode == "inequality":
from qiskit.circuit import QuantumRegister
x_reg = QuantumRegister(3, "x")
s_reg = QuantumRegister(1, "s")
qc = QuantumCircuit(x_reg, s_reg)
all_qubits = list(range(4))
else:
qc = QuantumCircuit(n)
all_qubits = list(range(n))
# --- Initialization ---
qc.h(all_qubits)
if stage == "init":
return qc
# --- Cost Layer ---
qc.barrier(label="Cost U_C(γ)")
if mode == "standard":
# Linear terms: Z1, Z2
qc.rz(2 * _GAMMA, 0)
qc.rz(2 * _GAMMA, 1)
# Quadratic term: Z2 Z3
qc.rzz(2 * _GAMMA, 1, 2)
elif mode == "equality":
# Linear terms: Z1, Z2, Z3 (from both obj and penalty expansion)
qc.rz(2 * _GAMMA, [0, 1, 2])
# Quadratic terms: all pairs (K3 fully connected)
qc.rzz(2 * _GAMMA, 0, 1)
qc.rzz(2 * _GAMMA, 1, 2)
qc.rzz(2 * _GAMMA, 0, 2)
elif mode == "inequality":
# Linear terms: x1, x2, x3, s
qc.rz(2 * _GAMMA, all_qubits)
# Quadratic terms: all pairs (K4 fully connected)
for i in range(4):
for j in range(i + 1, 4):
qc.rzz(2 * _GAMMA, i, j)
if stage == "cost":
return qc
# --- Mixer Layer ---
qc.barrier(label="Mixer U_B(β)")
qc.rx(2 * _BETA, all_qubits)
qc.barrier(label="Measure")
qc.measure_all()
return qc
def draw_circuit(stage: str, mode: str, scale: float = 0.99) -> plt.Figure:
"""
Return a Matplotlib Figure of the QAOA circuit at the given stage/mode.
Parameters
----------
stage : "init" | "cost" | "full"
mode : "standard" | "equality" | "inequality"
scale : float
Passed to qc.draw(..., scale=scale) to control figure size.
"""
qc = _make_circuit(stage, mode)
fig = qc.draw("mpl", style="iqp", scale=scale, fold=-1)
plt.close("all") # prevent memory leak; fig is already captured
return fig