|
|
|
"""Fixed Guppy Grover emulator for n=2 and n=3""" |
|
from guppylang import guppy |
|
from guppylang.std.builtins import result |
|
from guppylang.std.quantum import qubit, h, x, cx, cz, measure |
|
import math |
|
import argparse |
|
import csv |
|
import json |
|
|
|
@guppy |
|
def grover_n2_marked_11() -> None: |
|
"""Grover for n=2, marking |11⟩""" |
|
|
|
q0 = qubit() |
|
q1 = qubit() |
|
|
|
|
|
h(q0) |
|
h(q1) |
|
|
|
|
|
|
|
cz(q0, q1) |
|
|
|
|
|
h(q0) |
|
h(q1) |
|
x(q0) |
|
x(q1) |
|
h(q1) |
|
cx(q0, q1) |
|
h(q1) |
|
x(q0) |
|
x(q1) |
|
h(q0) |
|
h(q1) |
|
|
|
|
|
r0 = measure(q0) |
|
r1 = measure(q1) |
|
result("b0", r0) |
|
result("b1", r1) |
|
|
|
@guppy |
|
def grover_n2_marked_10() -> None: |
|
"""Grover for n=2, marking |10⟩""" |
|
q0 = qubit() |
|
q1 = qubit() |
|
|
|
|
|
h(q0) |
|
h(q1) |
|
|
|
|
|
x(q1) |
|
cz(q0, q1) |
|
x(q1) |
|
|
|
|
|
h(q0) |
|
h(q1) |
|
x(q0) |
|
x(q1) |
|
h(q1) |
|
cx(q0, q1) |
|
h(q1) |
|
x(q0) |
|
x(q1) |
|
h(q0) |
|
h(q1) |
|
|
|
|
|
r0 = measure(q0) |
|
r1 = measure(q1) |
|
result("b0", r0) |
|
result("b1", r1) |
|
|
|
def run_grover_n2(pattern, shots=1000): |
|
"""Run Grover for n=2 qubits""" |
|
if pattern == 3: |
|
sim = grover_n2_marked_11.emulator(n_qubits=2) |
|
sim = sim.with_shots(shots) |
|
results = sim.run() |
|
elif pattern == 2: |
|
sim = grover_n2_marked_10.emulator(n_qubits=2) |
|
sim = sim.with_shots(shots) |
|
results = sim.run() |
|
else: |
|
raise ValueError(f"Pattern {pattern} not implemented") |
|
|
|
|
|
success_count = 0 |
|
pattern_bits = format(pattern, '02b') |
|
|
|
for shot in results.results: |
|
bits = "" |
|
for entry in shot.entries: |
|
if entry[0] == 'b0': |
|
bits = str(entry[1]) + bits[1:] if len(bits) > 0 else str(entry[1]) |
|
elif entry[0] == 'b1': |
|
bits = bits[0] + str(entry[1]) if len(bits) > 0 else "0" + str(entry[1]) |
|
|
|
if bits == pattern_bits: |
|
success_count += 1 |
|
|
|
return success_count / shots |
|
|
|
def main(): |
|
ap = argparse.ArgumentParser() |
|
ap.add_argument("--n", type=int, default=2, choices=[2]) |
|
ap.add_argument("--pattern", type=int, default=3) |
|
ap.add_argument("--shots", type=int, default=1000) |
|
ap.add_argument("--csv", type=str, default="guppy_results.csv") |
|
args = ap.parse_args() |
|
|
|
|
|
print(f"\n{'='*60}") |
|
print(f"GUPPY/SELENE GROVER EMULATOR - n={args.n}, pattern={args.pattern:02b}") |
|
print(f"{'='*60}\n") |
|
|
|
|
|
p_success = run_grover_n2(args.pattern, args.shots) |
|
k_opt = 1 |
|
|
|
results = { |
|
"n": args.n, |
|
"pattern": format(args.pattern, '02b'), |
|
"k": k_opt, |
|
"shots": args.shots, |
|
"p_success": round(p_success, 3), |
|
"backend": "guppy/selene" |
|
} |
|
|
|
print(f"Results: {json.dumps(results, indent=2)}") |
|
|
|
|
|
with open(args.csv, "w", newline="") as f: |
|
writer = csv.writer(f) |
|
writer.writerow(["n", "m", "marked", "k", "backend", "shots", "p_success", "wall_s", "k_opt"]) |
|
writer.writerow([args.n, 1, format(args.pattern, '02b'), k_opt, "guppy", args.shots, p_success, None, k_opt]) |
|
|
|
print(f"\n✅ Results saved to {args.csv}") |
|
|
|
|
|
theoretical = 1.0 |
|
print(f"\nTheoretical p_success: {theoretical:.3f}") |
|
print(f"Achieved p_success: {p_success:.3f}") |
|
print(f"Difference: {abs(theoretical - p_success):.3f}") |
|
|
|
if __name__ == "__main__": |
|
main() |