QuLab 2.3.6__cp312-cp312-win_amd64.whl → 2.4.0__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,319 @@
1
+ import numpy as np
2
+ from matplotlib.patches import Circle, FancyArrow, PathPatch
3
+ from matplotlib.path import Path
4
+ from waveforms import *
5
+
6
+
7
+ def make_path(fx, fy, dfx, dfy, t):
8
+
9
+ def p(fx, fy, dfx, dfy, t0, t1):
10
+ x1, x2 = fx(t0), fx(t1)
11
+ y1, y2 = fy(t0), fy(t1)
12
+ dx1, dx2 = dfx(t0), dfx(t1)
13
+ dy1, dy2 = dfy(t0), dfy(t1)
14
+
15
+ xp = (dy1 * dx2 * x1 - dy2 * dx1 * x2 - dx1 * dx2 *
16
+ (y1 - y2)) / (dy1 * dx2 - dy2 * dx1)
17
+
18
+ yp = (dy1 * dx2 * y2 - dy2 * dx1 * y1 + dy1 * dy2 *
19
+ (x1 - x2)) / (dy1 * dx2 - dy2 * dx1)
20
+
21
+ return xp, yp
22
+
23
+ path = [(fx(t[0]), fy(t[0]))]
24
+ codes = [Path.MOVETO]
25
+
26
+ for i in range(1, len(t)):
27
+ x, y = p(fx, fy, dfx, dfy, t[i - 1], t[i])
28
+ path.append((x, y))
29
+ codes.append(Path.CURVE3)
30
+ path.append((fx(t[i]), fy(t[i])))
31
+ codes.append(Path.CURVE3)
32
+ return path, codes
33
+
34
+
35
+ def plot_square(ax,
36
+ x=0,
37
+ y=0,
38
+ width=1,
39
+ hight=1,
40
+ radius=0.2,
41
+ ls='-',
42
+ lw=2,
43
+ fc='none',
44
+ ec='black'):
45
+ r = radius
46
+ path = np.array([(0, 1), (1 - 2 * r, 1), (1, 1), (1, 1 - 2 * r),
47
+ (1, -1 + 2 * r), (1, -1), (1 - 2 * r, -1),
48
+ (-1 + 2 * r, -1), (-1, -1), (-1, -1 + 2 * r),
49
+ (-1, 1 - 2 * r), (-1, 1), (-1 + 2 * r, 1), (0, 1)])
50
+ path[:, 0] = path[:, 0] * width / 2 + x
51
+ path[:, 1] = path[:, 1] * hight / 2 + y
52
+ codes = [
53
+ Path.MOVETO,
54
+ Path.LINETO,
55
+ Path.CURVE3,
56
+ Path.CURVE3,
57
+ Path.LINETO,
58
+ Path.CURVE3,
59
+ Path.CURVE3,
60
+ Path.LINETO,
61
+ Path.CURVE3,
62
+ Path.CURVE3,
63
+ Path.LINETO,
64
+ Path.CURVE3,
65
+ Path.CURVE3,
66
+ Path.CLOSEPOLY,
67
+ ]
68
+ pp1 = PathPatch(Path(path, codes),
69
+ ls=ls,
70
+ lw=lw,
71
+ fc=fc,
72
+ ec=ec,
73
+ transform=ax.transData)
74
+
75
+ ax.add_artist(pp1)
76
+
77
+
78
+ def plot_measure(ax,
79
+ x=0,
80
+ y=0,
81
+ size=1,
82
+ ratio=0.8,
83
+ radius=0.2,
84
+ ls='-',
85
+ lw=2,
86
+ fc='none',
87
+ ec='black'):
88
+ width = size
89
+ hight = ratio * size
90
+ plot_square(ax, x, y, width, hight, radius, ls, lw, fc, ec)
91
+
92
+ fx = lambda t: 0.5 * width * np.cos(t) + x
93
+ fy = lambda t: 0.5 * hight * np.sin(t) + y - 0.2 * hight
94
+ dfx = lambda t: -0.5 * width * np.sin(t)
95
+ dfy = lambda t: 0.5 * hight * np.cos(t)
96
+ t = np.linspace(1 / 6, 5 / 6, 5) * np.pi
97
+ path, codes = make_path(fx, fy, dfx, dfy, t)
98
+
99
+ pp1 = PathPatch(Path(path, codes),
100
+ ls=ls,
101
+ lw=lw,
102
+ fc=fc,
103
+ ec=ec,
104
+ transform=ax.transData)
105
+
106
+ ax.add_artist(pp1)
107
+
108
+ angle = np.pi / 6
109
+
110
+ arr = FancyArrow(x,
111
+ y - 0.25 * width,
112
+ 0.55 * width * np.sin(angle),
113
+ 0.55 * width * np.cos(angle),
114
+ head_length=0.1 * width,
115
+ head_width=0.07 * width,
116
+ lw=lw,
117
+ color=ec)
118
+
119
+ ax.add_artist(arr)
120
+
121
+ return (x - width / 2, x + width / 2)
122
+
123
+
124
+ def plot_cnot(ax, x=0, ctr=1, tgt=0, size=0.5, lw=2, fc='none', ec='k'):
125
+ c = Circle((x, tgt), radius=size / 2, lw=lw, fc=fc, ec=ec)
126
+ ax.add_artist(c)
127
+
128
+ c = Circle((x, ctr), radius=0.1 * size, lw=lw, fc=ec, ec=ec)
129
+ ax.add_artist(c)
130
+
131
+ path, codes = [(x - size / 2, tgt), (
132
+ x + size / 2,
133
+ tgt,
134
+ )], [Path.MOVETO, Path.LINETO]
135
+
136
+ p = PathPatch(Path(path, codes),
137
+ ls='-',
138
+ lw=lw,
139
+ ec=ec,
140
+ transform=ax.transData)
141
+ ax.add_artist(p)
142
+
143
+ if ctr > tgt:
144
+ up, down = ctr, tgt - size / 2
145
+ else:
146
+ up, down = tgt + size / 2, ctr
147
+ path, codes = [(x, up), (x, down)], [Path.MOVETO, Path.LINETO]
148
+
149
+ p = PathPatch(Path(path, codes),
150
+ ls='-',
151
+ lw=lw,
152
+ ec=ec,
153
+ transform=ax.transData)
154
+ ax.add_artist(p)
155
+
156
+ return (x - 0.1 * size, x + 0.1 * size), (x - 0.5 * size, x + 0.5 * size)
157
+
158
+
159
+ def plot_cz(ax, x=0, ctr=1, tgt=0, size=0.5, lw=2, fc='none', ec='k'):
160
+ c = Circle((x, ctr), radius=0.1 * size, lw=lw, fc=ec, ec=ec)
161
+ ax.add_artist(c)
162
+
163
+ c = Circle((x, tgt), radius=0.1 * size, lw=lw, fc=ec, ec=ec)
164
+ ax.add_artist(c)
165
+
166
+ path, codes = [(x, ctr), (x, tgt)], [Path.MOVETO, Path.LINETO]
167
+
168
+ p = PathPatch(Path(path, codes),
169
+ ls='-',
170
+ lw=lw,
171
+ ec=ec,
172
+ transform=ax.transData)
173
+ ax.add_artist(p)
174
+
175
+ return (x - 0.1 * size, x + 0.1 * size), (x - 0.1 * size, x + 0.1 * size)
176
+
177
+
178
+ def plot_iswap(ax, x=0, ctr=1, tgt=0, size=0.2, lw=2, fc='none', ec='k'):
179
+ path, codes = [(x - size / 2, ctr - size / 2),
180
+ (x + size / 2, ctr + size / 2)], [Path.MOVETO, Path.LINETO]
181
+ p = PathPatch(Path(path, codes),
182
+ ls='-',
183
+ lw=lw,
184
+ ec=ec,
185
+ transform=ax.transData)
186
+ ax.add_artist(p)
187
+
188
+ path, codes = [(x - size / 2, ctr + size / 2),
189
+ (x + size / 2, ctr - size / 2)], [Path.MOVETO, Path.LINETO]
190
+ p = PathPatch(Path(path, codes),
191
+ ls='-',
192
+ lw=lw,
193
+ ec=ec,
194
+ transform=ax.transData)
195
+ ax.add_artist(p)
196
+
197
+ path, codes = [(x - size / 2, tgt - size / 2),
198
+ (x + size / 2, tgt + size / 2)], [Path.MOVETO, Path.LINETO]
199
+ p = PathPatch(Path(path, codes),
200
+ ls='-',
201
+ lw=lw,
202
+ ec=ec,
203
+ transform=ax.transData)
204
+ ax.add_artist(p)
205
+
206
+ path, codes = [(x - size / 2, tgt + size / 2),
207
+ (x + size / 2, tgt - size / 2)], [Path.MOVETO, Path.LINETO]
208
+ p = PathPatch(Path(path, codes),
209
+ ls='-',
210
+ lw=lw,
211
+ ec=ec,
212
+ transform=ax.transData)
213
+ ax.add_artist(p)
214
+
215
+ path, codes = [(x, ctr), (x, tgt)], [Path.MOVETO, Path.LINETO]
216
+ p = PathPatch(Path(path, codes),
217
+ ls='-',
218
+ lw=lw,
219
+ ec=ec,
220
+ transform=ax.transData)
221
+ ax.add_artist(p)
222
+
223
+ return (x, x), (x, x)
224
+
225
+
226
+ def plot_gate(ax,
227
+ x=0,
228
+ y=0,
229
+ size=1,
230
+ ratio=0.8,
231
+ radius=0.2,
232
+ text="$U$",
233
+ ls='-',
234
+ lw=2,
235
+ fc='none',
236
+ ec='black',
237
+ fontsize=16):
238
+ width = size
239
+ hight = ratio * size
240
+ plot_square(ax,
241
+ x,
242
+ y,
243
+ width,
244
+ hight,
245
+ radius=radius,
246
+ ls=ls,
247
+ lw=lw,
248
+ fc=fc,
249
+ ec=ec)
250
+ ax.text(x, y, text, ha='center', va='center', color=ec, fontsize=fontsize)
251
+
252
+ return (x - width / 2, x + width / 2)
253
+
254
+
255
+ def plot_waveform(ax,
256
+ wav,
257
+ offset,
258
+ gaps=[],
259
+ ec='black',
260
+ fc='none',
261
+ ls='-',
262
+ lw=2):
263
+ t = np.linspace(wav.start, wav.stop, 1001)
264
+ points = wav(t) + offset
265
+ for a, b in gaps:
266
+ points[(t > a) * (t < b)] = np.nan
267
+ ax.plot(t, points, ls=ls, color=ec, lw=lw)
268
+ if fc != 'none':
269
+ ax.fill_between(t, points, offset, color=fc)
270
+
271
+
272
+ def _max_ticks(table, *qubits):
273
+ ticks = []
274
+ for q in qubits:
275
+ ticks.append(len(table.get(q, [])))
276
+ return max(ticks)
277
+
278
+
279
+ def _extend_table(table, q, ticks):
280
+ table[q] = table.get(q, []) + [None] * (ticks - len(table.get(q, [])))
281
+
282
+
283
+ def _barrier(table, *qubits):
284
+ ticks = _max_ticks(table, *qubits)
285
+ for q in qubits:
286
+ _extend_table(table, q, ticks)
287
+
288
+
289
+ def qlisp_to_table(circ):
290
+ table = {}
291
+ for gate, *qubits in circ:
292
+ _barrier(table, *qubits)
293
+ if isinstance(gate, str) and gate == 'Barrier':
294
+ continue
295
+ for q in qubits:
296
+ table[q].append((gate, *qubits))
297
+ _barrier(table, *table.keys())
298
+ return table
299
+
300
+
301
+ def table_to_layers(table):
302
+ layers = []
303
+ for q, gates in table.items():
304
+ for i, gate in enumerate(gates):
305
+ if len(layers) <= i:
306
+ layers.append({})
307
+ layers[i][q] = gate
308
+ return layers
309
+
310
+
311
+ def _plot_layer(ax, layer, qubit_mapping=None):
312
+ gaps = {}
313
+ if qubit_mapping is None:
314
+ qubit_mapping = sorted(layer.keys())
315
+ return gaps
316
+
317
+
318
+ def plot_qlisp(ax, circ, qubit_mapping=None):
319
+ layers = table_to_layers(qlisp_to_table(circ))
@@ -2,6 +2,8 @@ import itertools
2
2
 
3
3
  import matplotlib.pyplot as plt
4
4
  import numpy as np
5
+ from matplotlib.patches import PathPatch
6
+ from matplotlib.path import Path
5
7
 
6
8
 
7
9
  def cycle(x0, y0, r, a=0, b=2 * np.pi):
@@ -88,3 +90,153 @@ def plot_seq(ax, waves, measure=[1], gap=4, maxTime=20, xlim=None):
88
90
  ax.set_yticks([])
89
91
  if xlim is not None:
90
92
  ax.set_xlim(xlim)
93
+
94
+
95
+ def make_path(fx, fy, dfx, dfy, t):
96
+
97
+ def p(fx, fy, dfx, dfy, t0, t1):
98
+ x1, x2 = fx(t0), fx(t1)
99
+ y1, y2 = fy(t0), fy(t1)
100
+ dx1, dx2 = dfx(t0), dfx(t1)
101
+ dy1, dy2 = dfy(t0), dfy(t1)
102
+
103
+ xp = (dy1 * dx2 * x1 - dy2 * dx1 * x2 - dx1 * dx2 *
104
+ (y1 - y2)) / (dy1 * dx2 - dy2 * dx1)
105
+
106
+ yp = (dy1 * dx2 * y2 - dy2 * dx1 * y1 + dy1 * dy2 *
107
+ (x1 - x2)) / (dy1 * dx2 - dy2 * dx1)
108
+
109
+ return xp, yp
110
+
111
+ path = [(fx(t[0]), fy(t[0]))]
112
+ codes = [Path.MOVETO]
113
+
114
+ for i in range(1, len(t)):
115
+ x, y = p(fx, fy, dfx, dfy, t[i - 1], t[i])
116
+ path.append((x, y))
117
+ codes.append(Path.CURVE3)
118
+ path.append((fx(t[i]), fy(t[i])))
119
+ codes.append(Path.CURVE3)
120
+ return path, codes
121
+
122
+
123
+ def plot_square(ax,
124
+ x=0,
125
+ y=0,
126
+ width=1,
127
+ hight=1,
128
+ r=0.2,
129
+ ls='-',
130
+ lw=2,
131
+ fc='none',
132
+ ec='black'):
133
+
134
+ path = np.array([(0, 1), (1 - 2 * r, 1), (1, 1), (1, 1 - 2 * r),
135
+ (1, -1 + 2 * r), (1, -1), (1 - 2 * r, -1),
136
+ (-1 + 2 * r, -1), (-1, -1), (-1, -1 + 2 * r),
137
+ (-1, 1 - 2 * r), (-1, 1), (-1 + 2 * r, 1), (0, 1)])
138
+ path[:, 0] = path[:, 0] * width / 2 + x
139
+ path[:, 1] = path[:, 1] * hight / 2 + y
140
+ codes = [
141
+ Path.MOVETO,
142
+ Path.LINETO,
143
+ Path.CURVE3,
144
+ Path.CURVE3,
145
+ Path.LINETO,
146
+ Path.CURVE3,
147
+ Path.CURVE3,
148
+ Path.LINETO,
149
+ Path.CURVE3,
150
+ Path.CURVE3,
151
+ Path.LINETO,
152
+ Path.CURVE3,
153
+ Path.CURVE3,
154
+ Path.CLOSEPOLY,
155
+ ]
156
+ pp1 = PathPatch(Path(path, codes),
157
+ ls=ls,
158
+ lw=lw,
159
+ fc=fc,
160
+ ec=ec,
161
+ transform=ax.transData)
162
+
163
+ ax.add_patch(pp1)
164
+
165
+
166
+ def plot_measure(ax,
167
+ x=0,
168
+ y=0,
169
+ size=1,
170
+ r=0.2,
171
+ ls='-',
172
+ lw=2,
173
+ fc='none',
174
+ ec='black'):
175
+ width = size
176
+ hight = 0.8 * size
177
+ plot_square(ax, x, y, width, hight, r, ls, lw, fc, ec)
178
+
179
+ fx = lambda t: 0.5 * width * np.cos(t) + x
180
+ fy = lambda t: 0.5 * hight * np.sin(t) + y - 0.2 * hight
181
+ dfx = lambda t: -0.5 * width * np.sin(t)
182
+ dfy = lambda t: 0.5 * hight * np.cos(t)
183
+ t = np.linspace(1 / 6, 5 / 6, 5) * np.pi
184
+ path, codes = make_path(fx, fy, dfx, dfy, t)
185
+
186
+ pp1 = PathPatch(Path(path, codes),
187
+ ls=ls,
188
+ lw=lw,
189
+ fc=fc,
190
+ ec=ec,
191
+ transform=ax.transData)
192
+
193
+ ax.add_patch(pp1)
194
+
195
+ angle = np.pi / 6
196
+
197
+ ax.arrow(x,
198
+ y - 0.25 * width,
199
+ 0.55 * width * np.sin(angle),
200
+ 0.55 * width * np.cos(angle),
201
+ head_width=0.07 * width,
202
+ head_length=0.1 * width,
203
+ lw=lw,
204
+ color=ec)
205
+
206
+ return (x - width / 2, x + width / 2)
207
+
208
+
209
+ def plot_gate(ax,
210
+ x=0,
211
+ y=0,
212
+ size=1,
213
+ text="$U$",
214
+ ls='-',
215
+ lw=2,
216
+ r=0.2,
217
+ fc='none',
218
+ ec='black',
219
+ fontsize=16):
220
+ width = size
221
+ hight = 0.8 * size
222
+ plot_square(ax, x, y, width, hight, r, ls, lw, fc, ec)
223
+ ax.text(x, y, text, ha='center', va='center', color=ec, fontsize=fontsize)
224
+
225
+ return (x - width / 2, x + width / 2)
226
+
227
+
228
+ def plot_waveform(ax,
229
+ wav,
230
+ offset,
231
+ gaps=[],
232
+ ec='black',
233
+ fc='none',
234
+ ls='-',
235
+ lw=2):
236
+ t = np.linspace(wav.start, wav.stop, 1001)
237
+ points = wav(t) + offset
238
+ for a, b in gaps:
239
+ points[(t > a) * (t < b)] = np.nan
240
+ ax.plot(t, points, ls=ls, color=ec, lw=lw)
241
+ if fc != 'none':
242
+ ax.fill_between(t, points, offset, color=fc)
@@ -0,0 +1,23 @@
1
+ import numpy as np
2
+ from scipy.linalg import expm
3
+
4
+
5
+ def _rot(theta, v):
6
+ x, y, z = np.asarray(v) / np.sqrt(np.sum(np.asarray(v)**2))
7
+ c, s = np.cos(theta), np.sin(theta)
8
+
9
+ return np.array([[
10
+ c + (1 - c) * x**2, (1 - c) * x * y - s * z, (1 - c) * x * z + s * y
11
+ ], [(1 - c) * x * y + s * z, c + (1 - c) * y**2, (1 - c) * y * z - s * x],
12
+ [(1 - c) * x * z - s * y, (1 - c) * y * z + s * x,
13
+ c + (1 - c) * z**2]])
14
+
15
+
16
+ def rot_round(x, y, z, v=[0, 0, 1], theta=0, c=[0, 0, 0]):
17
+ ret = (np.array([x, y, z]).T - np.array(c)) @ _rot(theta, v) + np.array(c)
18
+ return ret.T
19
+
20
+
21
+ def projection(x, y, z, y0=1):
22
+ d = np.sqrt(x**2 + y**2 + z**2)
23
+ return x * y0 / y, z * y0 / y, d
File without changes