Skip to content

Commit 65c0e39

Browse files
committed
Add Simon's Algorithm Simulation'
1 parent f357809 commit 65c0e39

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

quantum/simons_algorithm.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
Simon's Algorithm (Classical Simulation)
3+
4+
Simon's algorithm finds a hidden bitstring s such that
5+
f(x) = f(y) if and only if x XOR y = s.
6+
7+
Here we simulate the mapping behavior classically to
8+
illustrate how the hidden period can be discovered by
9+
analyzing collisions in f(x).
10+
11+
References:
12+
https://en.wikipedia.org/wiki/Simon's_problem
13+
"""
14+
15+
from collections.abc import Callable
16+
from itertools import product
17+
18+
19+
def xor_bits(a: list[int], b: list[int]) -> list[int]:
20+
"""
21+
Return the bitwise XOR of two equal-length bit lists.
22+
23+
>>> xor_bits([1, 0, 1], [1, 1, 0])
24+
[0, 1, 1]
25+
"""
26+
if len(a) != len(b):
27+
raise ValueError("Bit lists must be of equal length.")
28+
return [x ^ y for x, y in zip(a, b)]
29+
30+
31+
def simons_algorithm(f: Callable[[list[int]], list[int]], n: int) -> list[int]:
32+
33+
"""
34+
Simulate Simon's algorithm classically to find the hidden bitstring s.
35+
36+
Args:
37+
f: A function mapping n-bit input to n-bit output.
38+
n: Number of bits in the input.
39+
40+
Returns:
41+
The hidden bitstring s as a list of bits.
42+
43+
>>> # Example with hidden bitstring s = [1, 0, 1]
44+
>>> s = [1, 0, 1]
45+
>>> def f(x):
46+
... mapping = {
47+
... (0,0,0): (1,1,0),
48+
... (1,0,1): (1,1,0),
49+
... (0,0,1): (0,1,1),
50+
... (1,0,0): (0,1,1),
51+
... (0,1,0): (1,0,1),
52+
... (1,1,1): (1,0,1),
53+
... (0,1,1): (0,0,0),
54+
... (1,1,0): (0,0,0),
55+
... }
56+
... return mapping[tuple(x)]
57+
>>> simons_algorithm(f, 3)
58+
[1, 0, 1]
59+
"""
60+
mapping: dict[tuple[int, ...], tuple[int, ...]] = {}
61+
inputs = list(product([0, 1], repeat=n))
62+
63+
for x in inputs:
64+
fx = tuple(f(list(x)))
65+
if fx in mapping:
66+
y = mapping[fx]
67+
return xor_bits(list(x), list(y))
68+
mapping[fx] = x
69+
70+
# If no collision found, function might be constant
71+
return [0] * n
72+
73+
74+
if __name__ == "__main__":
75+
import doctest
76+
77+
doctest.testmod()

0 commit comments

Comments
 (0)