|
|
|
|
|
from guppylang import guppy |
|
from guppylang.std.builtins import result |
|
from guppylang.std.quantum import qubit, h, x, cx, cz, toffoli, measure |
|
import math, random, argparse, csv |
|
|
|
@guppy |
|
def grover_k_n2(b0: int, b1: int, k: int) -> None: |
|
q0 = qubit(); q1 = qubit() |
|
h(q0); h(q1) |
|
for _ in range(k): |
|
if b0 == 0: x(q0) |
|
if b1 == 0: x(q1) |
|
cz(q0, q1) |
|
if b0 == 0: x(q0) |
|
if b1 == 0: 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", 1 if r0 else 0); result("b1", 1 if r1 else 0) |
|
|
|
@guppy |
|
def grover_k_n3(b0: int, b1: int, b2: int, k: int) -> None: |
|
q0 = qubit(); q1 = qubit(); q2 = qubit() |
|
h(q0); h(q1); h(q2) |
|
for _ in range(k): |
|
if b0 == 0: x(q0) |
|
if b1 == 0: x(q1) |
|
if b2 == 0: x(q2) |
|
h(q2); toffoli(q0, q1, q2); h(q2) |
|
if b0 == 0: x(q0) |
|
if b1 == 0: x(q1) |
|
if b2 == 0: x(q2) |
|
h(q0); h(q1); h(q2); x(q0); x(q1); x(q2) |
|
h(q2); toffoli(q0, q1, q2); h(q2) |
|
x(q0); x(q1); x(q2); h(q0); h(q1); h(q2) |
|
r0 = measure(q0); r1 = measure(q1); r2 = measure(q2) |
|
result("b0", 1 if r0 else 0); result("b1", 1 if r1 else 0); result("b2", 1 if r2 else 0) |
|
|
|
def bits_from_int(n_bits, value): |
|
return [ (value >> (n_bits - 1 - i)) & 1 for i in range(n_bits) ] |
|
|
|
def main(): |
|
ap = argparse.ArgumentParser() |
|
ap.add_argument("--n", type=int, choices=[2,3], default=3) |
|
ap.add_argument("--pattern", type=int, default=5) |
|
ap.add_argument("--shots", type=int, default=2000) |
|
ap.add_argument("--k", type=int, default=None) |
|
ap.add_argument("--m", type=int, default=1) |
|
ap.add_argument("--csv", type=str, default="grover_guppy_results.csv") |
|
ap.add_argument("--seed", type=int, default=123) |
|
args = ap.parse_args() |
|
random.seed(args.seed) |
|
bits = bits_from_int(args.n, args.pattern) |
|
k = args.k if args.k is not None else max(1, int(round((math.pi/4)*math.sqrt((2**args.n)/args.m)))) |
|
if args.n == 2: |
|
sim = grover_k_n2.emulator(n_qubits=2).with_shots(args.shots).with_seed(args.seed).run(bits[0], bits[1], k) |
|
hits = sum(1 for shot in sim.results if f"{int(dict(shot.entries)['b0'])}{int(dict(shot.entries)['b1'])}" == f"{bits[0]}{bits[1]}") |
|
else: |
|
sim = grover_k_n3.emulator(n_qubits=3).with_shots(args.shots).with_seed(args.seed).run(bits[0], bits[1], bits[2], k) |
|
hits = sum(1 for shot in sim.results if f"{int(dict(shot.entries)['b0'])}{int(dict(shot.entries)['b1'])}{int(dict(shot.entries)['b2'])}" == f"{bits[0]}{bits[1]}{bits[2]}") |
|
p = hits / args.shots |
|
print({"n": args.n, "pattern_bits": bits, "k": k, "shots": args.shots, "p_success": round(p,3)}) |
|
with open(args.csv, "w", newline="") as f: |
|
w = csv.writer(f); w.writerow(["n","m","marked","k","backend","shots","p_success","wall_s","k_opt"]) |
|
w.writerow([args.n, args.m, "".join(map(str,bits)), k, "guppy", args.shots, p, None, k]) |
|
|
|
if __name__ == "__main__": |
|
main() |