-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmirror_nn.py
94 lines (73 loc) · 2.59 KB
/
mirror_nn.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Demonstrate mirror circuit simplification
import math
import random
import sys
import time
from pyqrack import QrackSimulator, QrackCircuit
def bench_qrack(n):
circ = QrackCircuit()
lcv_range = range(n)
x_op = [0, 1, 1, 0]
gateSequence = [ 0, 3, 2, 1, 2, 1, 0, 3 ]
row_len = math.ceil(math.sqrt(n))
for _ in lcv_range:
# Single-qubit gates
for i in lcv_range:
th = random.uniform(0, 2 * math.pi)
ph = random.uniform(0, 2 * math.pi)
lm = random.uniform(0, 2 * math.pi)
cos0 = math.cos(th / 2);
sin0 = math.sin(th / 2);
u_op = [
cos0 + 0j, sin0 * (-math.cos(lm) + -math.sin(lm) * 1j),
sin0 * (math.cos(ph) + math.sin(ph) * 1j), cos0 * (math.cos(ph + lm) + math.sin(ph + lm) * 1j)
]
circ.mtrx(u_op, i)
# Nearest-neighbor couplers:
gate = gateSequence.pop(0)
gateSequence.append(gate)
for row in range(1, row_len, 2):
for col in range(row_len):
temp_row = row
temp_col = col
temp_row = temp_row + (1 if (gate & 2) else -1);
temp_col = temp_col + (1 if (gate & 1) else 0)
if (temp_row < 0) or (temp_col < 0) or (temp_row >= row_len) or (temp_col >= row_len):
continue
b1 = row * row_len + col
b2 = temp_row * row_len + temp_col
if (b1 >= n) or (b2 >= n):
continue
if random.uniform(0, 1) < 0.5:
tmp = b1
b1 = b2
b2 = tmp
circ.ucmtrx([b1], x_op, b2, 1)
# Dig into the (open source) code for yourself:
# Qrack does NOT have a special-case optimization
# when appending specifically the circuit inverse;
# it just simplifies to identity, gate-by-gate.
# (This is not necessarily true for every possible
# "mirror circuit," i.e. any circuit that
# simplifies to identity operator.)
start = time.perf_counter()
sim = QrackSimulator(n)
circ.run(sim)
circ.inverse().run(sim)
if sim.m_all() != 0:
raise Exception("Mirror circuit failed!")
seconds = time.perf_counter() - start
fidelity = sim.get_unitary_fidelity()
return (seconds, fidelity)
def main():
n = 50
if len(sys.argv) > 1:
n = int(sys.argv[1])
results = bench_qrack(n)
print(n, "qubits,",
results[0], "seconds,",
results[1], "fidelity"
)
return 0
if __name__ == '__main__':
sys.exit(main())