mirror of
https://github.com/kristoferssolo/grovers-visualizer.git
synced 2026-02-04 06:42:03 +00:00
refactor: make subfiles
This commit is contained in:
0
src/grovers_visualizer/__init__.py
Normal file
0
src/grovers_visualizer/__init__.py
Normal file
0
src/grovers_visualizer/circuit.py
Normal file
0
src/grovers_visualizer/circuit.py
Normal file
120
src/grovers_visualizer/main.py
Normal file
120
src/grovers_visualizer/main.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python
|
||||
"""Grover's Algorithm Visualizer.
|
||||
|
||||
This script builds a Grover search circuit based on user input, runs the
|
||||
simulation using Qiskit's Aer simulator, and visualizes the results
|
||||
using matplotlib.
|
||||
"""
|
||||
|
||||
from itertools import product
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.axes import Axes
|
||||
from qiskit import QuantumCircuit
|
||||
from qiskit_aer import AerSimulator
|
||||
|
||||
|
||||
def x(qc: QuantumCircuit, target_state: str) -> None:
|
||||
for i, bit in enumerate(reversed(target_state)):
|
||||
if bit == "0":
|
||||
qc.x(i)
|
||||
|
||||
|
||||
def ccz(qc: QuantumCircuit, n: int) -> None:
|
||||
"""Multi-controlled Z (for 3 qubits, this is a CCZ)"""
|
||||
if n == 1:
|
||||
qc.z(0)
|
||||
elif n == 2:
|
||||
qc.cz(0, 1)
|
||||
else:
|
||||
qc.h(n - 1)
|
||||
qc.mcx(list(range(n - 1)), n - 1) # multi-controlled X (Toffoli for 3 qubits)
|
||||
qc.h(n - 1)
|
||||
|
||||
|
||||
def oracule(qc: QuantumCircuit, target_state: str) -> None:
|
||||
n = len(target_state)
|
||||
|
||||
x(qc, target_state)
|
||||
|
||||
ccz(qc, n)
|
||||
|
||||
# Undo the X gates
|
||||
x(qc, target_state)
|
||||
|
||||
|
||||
def diffusion(qc: QuantumCircuit, n: int) -> None:
|
||||
"""Apply the Grovers diffusion operator"""
|
||||
|
||||
qc.h(range(n))
|
||||
qc.x(range(n))
|
||||
|
||||
ccz(qc, n)
|
||||
|
||||
qc.x(range(n))
|
||||
qc.h(range(n))
|
||||
|
||||
|
||||
def grover_search(n: int, target_state: str) -> QuantumCircuit:
|
||||
qc = QuantumCircuit(n, n)
|
||||
|
||||
qc.h(range(n))
|
||||
|
||||
num_states = 2**n
|
||||
|
||||
iterations = int(np.floor(np.pi / 4 * np.sqrt(num_states)))
|
||||
for _ in range(iterations):
|
||||
oracule(qc, target_state)
|
||||
diffusion(qc, n)
|
||||
|
||||
qc.measure(range(n), range(n))
|
||||
return qc
|
||||
|
||||
|
||||
def plot_counts(ax: Axes, counts: dict[str, int], target_state: str) -> None:
|
||||
"""Create and 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:
|
||||
n_qubits = 3
|
||||
combinations = product(["0", "1"], repeat=n_qubits)
|
||||
states = ["".join(x) for x in combinations]
|
||||
shots = 1024
|
||||
|
||||
_, ax = plt.subplots(figsize=(8, 4))
|
||||
plt.ion()
|
||||
|
||||
for state in states:
|
||||
qc = grover_search(n_qubits, state)
|
||||
|
||||
print(qc.draw("text"))
|
||||
|
||||
simulator = AerSimulator()
|
||||
job = simulator.run(qc, shots=shots)
|
||||
result = job.result()
|
||||
counts: dict[str, int] = result.get_counts(qc)
|
||||
sorted_counts = dict(sorted(counts.items(), key=lambda x: x[1], reverse=True))
|
||||
|
||||
print(f"Target: {state}")
|
||||
print("\n".join(f"'{k}': {v}" for k, v in sorted_counts.items()))
|
||||
|
||||
plot_counts(ax, sorted_counts, state)
|
||||
plt.pause(1)
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
0
src/grovers_visualizer/plot.py
Normal file
0
src/grovers_visualizer/plot.py
Normal file
0
src/grovers_visualizer/state.py
Normal file
0
src/grovers_visualizer/state.py
Normal file
Reference in New Issue
Block a user