feat(args): add args functionality

This commit is contained in:
Kristofers Solo 2025-04-22 19:13:13 +03:00
parent 70c8d50ec9
commit 083f60ffa2
4 changed files with 72 additions and 23 deletions

View File

@ -1,10 +1,11 @@
[project]
name = "grovers-visualizer"
version = "0.2.0"
version = "0.3.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"argparse>=1.4.0",
"numpy>=2.2.4",
"qiskit-aer>=0.17.0",
"qiskit[visualization]>=2.0.0",

View File

@ -10,36 +10,23 @@ from math import asin, sqrt
from typing import TYPE_CHECKING, Callable
import matplotlib.pyplot as plt
from matplotlib.axes import Axes
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from grovers_visualizer.circuit import diffusion, oracle
from grovers_visualizer.parse import parse_args
from grovers_visualizer.plot import draw_grover_circle, plot_amplitudes_live
from grovers_visualizer.state import QubitState
from grovers_visualizer.utils import all_states, optimal_grover_iterations
if TYPE_CHECKING:
from matplotlib.axes import Axes
from matplotlib.figure import Figure
def plot_counts(ax: Axes, counts: dict[str, int], target_state: QubitState) -> None:
"""Display a bar chart for the measurement results."""
# Sort the states
states = list(counts.keys())
frequencies = [counts[s] for s in states]
ax.clear()
ax.bar(states, frequencies, color="skyblue")
ax.set_xlabel("Measured State")
ax.set_ylabel("Counts")
ax.set_title(f"Measurement Counts for Target: {target_state}")
ax.set_ylim(0, max(frequencies) * 1.2)
def main() -> None:
target_state = QubitState("1010")
args = parse_args()
target_state = args.target
n_qubits = len(target_state)
basis_states = [str(bit) for bit in all_states(n_qubits)]
optimal_iterations = optimal_grover_iterations(n_qubits)
@ -66,7 +53,7 @@ def main() -> None:
plot_amplitudes_live(ax_bar, bars, sv, basis_states, step_label, iteration, target_state, optimal_iterations)
draw_grover_circle(ax_circle, iteration, optimal_iterations, theta, state_angle)
plt.pause(0.5)
plt.pause(args.speed)
# Start with Hadamard
qc = QuantumCircuit(n_qubits)
@ -74,14 +61,24 @@ def main() -> None:
iterate_and_plot(None, "Hadamard (Initialization)", 0)
iteration = 1
while plt.fignum_exists(fig.number):
running = True
def on_key(event) -> None:
nonlocal running
if event.key == "q":
running = False
cid = fig.canvas.mpl_connect("key_press_event", on_key)
while plt.fignum_exists(fig.number) and running:
iterate_and_plot(lambda qc: oracle(qc, target_state), "Oracle (Query Phase)", iteration)
iterate_and_plot(lambda qc: diffusion(qc, n_qubits), "Diffusion (Inversion Phase)", iteration)
iteration += 1
if args.iterations > 0 and iteration > args.iterations:
break
fig.canvas.mpl_disconnect(cid)
plt.ioff()
plt.show()
if __name__ == "__main__":

View File

@ -0,0 +1,40 @@
from argparse import ArgumentParser
from dataclasses import dataclass
from grovers_visualizer.state import QubitState
@dataclass
class Args:
target: QubitState
iterations: int
speed: float
def parse_args() -> Args:
parser = ArgumentParser(description="Grover's Algorithm Visualizer")
parser.add_argument(
"target",
type=str,
help="Target bitstring (e.g., 1010)",
)
parser.add_argument(
"-i",
"--iterations",
type=int,
default=0,
help="Number of Grover iterations (default: 0 (infinite))",
)
parser.add_argument(
"-s",
"--speed",
type=float,
default=0.5,
help="Pause duration (seconds) between steps (deafult: 0.5)",
)
ns = parser.parse_args()
return Args(
target=QubitState(ns.target),
iterations=ns.iterations,
speed=ns.speed,
)

13
uv.lock
View File

@ -2,6 +2,15 @@ version = 1
revision = 1
requires-python = ">=3.13"
[[package]]
name = "argparse"
version = "1.4.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/18/dd/e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4", size = 70508 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314", size = 23000 },
]
[[package]]
name = "contourpy"
version = "1.3.1"
@ -70,9 +79,10 @@ wheels = [
[[package]]
name = "grovers-visualizer"
version = "0.2.0"
version = "0.3.0"
source = { editable = "." }
dependencies = [
{ name = "argparse" },
{ name = "numpy" },
{ name = "qiskit", extra = ["visualization"] },
{ name = "qiskit-aer" },
@ -91,6 +101,7 @@ dev = [
[package.metadata]
requires-dist = [
{ name = "argparse", specifier = ">=1.4.0" },
{ name = "numpy", specifier = ">=2.2.4" },
{ name = "pyqt6", marker = "extra == 'mpl'", specifier = ">=6.9.0" },
{ name = "qiskit", extras = ["visualization"], specifier = ">=2.0.0" },