iqm-benchmarks 1.3__py3-none-any.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.
Potentially problematic release.
This version of iqm-benchmarks might be problematic. Click here for more details.
- iqm/benchmarks/__init__.py +31 -0
- iqm/benchmarks/benchmark.py +109 -0
- iqm/benchmarks/benchmark_definition.py +264 -0
- iqm/benchmarks/benchmark_experiment.py +163 -0
- iqm/benchmarks/compressive_gst/__init__.py +20 -0
- iqm/benchmarks/compressive_gst/compressive_gst.py +1029 -0
- iqm/benchmarks/entanglement/__init__.py +18 -0
- iqm/benchmarks/entanglement/ghz.py +802 -0
- iqm/benchmarks/logging_config.py +29 -0
- iqm/benchmarks/optimization/__init__.py +18 -0
- iqm/benchmarks/optimization/qscore.py +719 -0
- iqm/benchmarks/quantum_volume/__init__.py +21 -0
- iqm/benchmarks/quantum_volume/clops.py +726 -0
- iqm/benchmarks/quantum_volume/quantum_volume.py +854 -0
- iqm/benchmarks/randomized_benchmarking/__init__.py +18 -0
- iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl +0 -0
- iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl +0 -0
- iqm/benchmarks/randomized_benchmarking/clifford_rb/__init__.py +19 -0
- iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py +386 -0
- iqm/benchmarks/randomized_benchmarking/interleaved_rb/__init__.py +19 -0
- iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py +555 -0
- iqm/benchmarks/randomized_benchmarking/mirror_rb/__init__.py +19 -0
- iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py +810 -0
- iqm/benchmarks/randomized_benchmarking/multi_lmfit.py +86 -0
- iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py +892 -0
- iqm/benchmarks/readout_mitigation.py +290 -0
- iqm/benchmarks/utils.py +521 -0
- iqm_benchmarks-1.3.dist-info/LICENSE +205 -0
- iqm_benchmarks-1.3.dist-info/METADATA +190 -0
- iqm_benchmarks-1.3.dist-info/RECORD +42 -0
- iqm_benchmarks-1.3.dist-info/WHEEL +5 -0
- iqm_benchmarks-1.3.dist-info/top_level.txt +2 -0
- mGST/LICENSE +21 -0
- mGST/README.md +54 -0
- mGST/additional_fns.py +962 -0
- mGST/algorithm.py +733 -0
- mGST/compatibility.py +238 -0
- mGST/low_level_jit.py +694 -0
- mGST/optimization.py +349 -0
- mGST/qiskit_interface.py +282 -0
- mGST/reporting/figure_gen.py +334 -0
- mGST/reporting/reporting.py +710 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generation of figures
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from matplotlib import ticker
|
|
6
|
+
from matplotlib.colors import Normalize
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import numpy as np
|
|
9
|
+
import numpy.linalg as la
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
SMALL_SIZE = 8
|
|
13
|
+
MEDIUM_SIZE = 9
|
|
14
|
+
BIGGER_SIZE = 10
|
|
15
|
+
|
|
16
|
+
plt.rc("font", size=SMALL_SIZE) # controls default text sizes
|
|
17
|
+
plt.rc("axes", titlesize=SMALL_SIZE) # fontsize of the axes title
|
|
18
|
+
plt.rc("axes", labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
|
|
19
|
+
plt.rc("xtick", labelsize=SMALL_SIZE) # fontsize of the tick labels
|
|
20
|
+
plt.rc("ytick", labelsize=SMALL_SIZE) # fontsize of the tick labels
|
|
21
|
+
plt.rc("legend", fontsize=SMALL_SIZE) # legend fontsize
|
|
22
|
+
plt.rc("figure", titlesize=BIGGER_SIZE) # fontsize of the figure title
|
|
23
|
+
|
|
24
|
+
cmap = plt.colormaps.get_cmap("RdBu")
|
|
25
|
+
norm = Normalize(vmin=-1, vmax=1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def set_size(w, h, ax=None):
|
|
29
|
+
"""Forcing a figure to a specified size
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
w : floar
|
|
34
|
+
width in inches
|
|
35
|
+
h : float
|
|
36
|
+
height in inches
|
|
37
|
+
ax : matplotlib axes
|
|
38
|
+
The optional axes
|
|
39
|
+
"""
|
|
40
|
+
if not ax:
|
|
41
|
+
ax = plt.gca()
|
|
42
|
+
l = ax.figure.subplotpars.left
|
|
43
|
+
r = ax.figure.subplotpars.right
|
|
44
|
+
t = ax.figure.subplotpars.top
|
|
45
|
+
b = ax.figure.subplotpars.bottom
|
|
46
|
+
figw = float(w) / (r - l)
|
|
47
|
+
figh = float(h) / (t - b)
|
|
48
|
+
ax.figure.set_size_inches(figw, figh)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def plot_objf(res_list, delta, title):
|
|
52
|
+
"""Plots the objective function over iterations in the algorithm
|
|
53
|
+
|
|
54
|
+
Parameters:
|
|
55
|
+
res_list (List[float]): The residual values
|
|
56
|
+
delta (float): The success threshold
|
|
57
|
+
title (str): The plot title
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
"""
|
|
61
|
+
plt.semilogy(res_list)
|
|
62
|
+
plt.ylabel(f"Objective function")
|
|
63
|
+
plt.xlabel(f"Iterations")
|
|
64
|
+
plt.axhline(delta, color="green", label="conv. threshold")
|
|
65
|
+
plt.title(title)
|
|
66
|
+
plt.legend()
|
|
67
|
+
plt.show()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def generate_spam_err_pdf(filename, E, rho, E2, rho2, title=None, spam2_content="ideal"):
|
|
71
|
+
"""Generate pdf plots of two sets of POVM + state side by side in vector shape - Pauli basis
|
|
72
|
+
The input sets can be either POVM/state directly or a difference different SPAM parametrizations to
|
|
73
|
+
visualize errors.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
filename : str
|
|
78
|
+
The name under which the figures are saved in format "folder/name"
|
|
79
|
+
E : numpy array
|
|
80
|
+
POVM
|
|
81
|
+
rho : numpy array
|
|
82
|
+
Initial state
|
|
83
|
+
E2 : numpy array
|
|
84
|
+
POVM #2
|
|
85
|
+
rho2 : numpy array
|
|
86
|
+
Initial state #2
|
|
87
|
+
title : str
|
|
88
|
+
The Figure title
|
|
89
|
+
basis_labels : list[str]
|
|
90
|
+
A list of labels for the basis elements. For the Pauli basis ["I", "X", "Y", "Z"] or the multi-qubit version.
|
|
91
|
+
spam2_content : str
|
|
92
|
+
Label of the right SPAM plot to indicate whether it is the ideal SPAM parametrization or for instance
|
|
93
|
+
the error between the reconstructed and target SPAM
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
"""
|
|
98
|
+
r = rho.shape[0]
|
|
99
|
+
pdim = int(np.sqrt(r))
|
|
100
|
+
n_povm = E.shape[0]
|
|
101
|
+
fig, axes = plt.subplots(ncols=2, nrows=n_povm + 1, sharex=True)
|
|
102
|
+
plt.rc("image", cmap="RdBu")
|
|
103
|
+
|
|
104
|
+
ax = axes[0, 0]
|
|
105
|
+
ax.imshow(rho, vmin=-1, vmax=1) # change_basis(S_true_maps[0],"std","pp")
|
|
106
|
+
ax.set_xticks(np.arange(r))
|
|
107
|
+
ax.set_title(r"rho")
|
|
108
|
+
ax.yaxis.set_major_locator(ticker.NullLocator())
|
|
109
|
+
|
|
110
|
+
ax = axes[0, 1]
|
|
111
|
+
im0 = ax.imshow(rho2, vmin=-1, vmax=1) # change_basis(S_true_maps[0],"std","pp")
|
|
112
|
+
ax.set_xticks(np.arange(r))
|
|
113
|
+
ax.set_title(r"rho - " + spam2_content)
|
|
114
|
+
ax.yaxis.set_major_locator(ticker.NullLocator())
|
|
115
|
+
|
|
116
|
+
for i in range(n_povm):
|
|
117
|
+
ax = axes[1 + i, 0]
|
|
118
|
+
ax.imshow(E[i], vmin=-1, vmax=1) # change_basis(S_true_maps[0],"std","pp")
|
|
119
|
+
ax.set_xticks(np.arange(pdim))
|
|
120
|
+
ax.set_xticklabels(np.arange(pdim) + 1)
|
|
121
|
+
ax.set_title(f"E%i" % (i + 1))
|
|
122
|
+
ax.yaxis.set_major_locator(ticker.NullLocator())
|
|
123
|
+
ax.xaxis.set_major_locator(ticker.NullLocator())
|
|
124
|
+
|
|
125
|
+
ax = axes[1 + i, 1]
|
|
126
|
+
ax.imshow(E2[i], vmin=-1, vmax=1) # change_basis(S_true_maps[0],"std","pp")
|
|
127
|
+
ax.set_xticks(np.arange(pdim))
|
|
128
|
+
ax.set_xticklabels(np.arange(pdim) + 1)
|
|
129
|
+
ax.set_title(f"E%i - " % (i + 1) + spam2_content)
|
|
130
|
+
ax.yaxis.set_major_locator(ticker.NullLocator())
|
|
131
|
+
ax.xaxis.set_major_locator(ticker.NullLocator())
|
|
132
|
+
|
|
133
|
+
cbar = fig.colorbar(im0, ax=axes.ravel().tolist(), pad=0.1)
|
|
134
|
+
cbar.ax.set_ylabel(r"Pauli basis coefficient", labelpad=5, rotation=90)
|
|
135
|
+
|
|
136
|
+
if title:
|
|
137
|
+
fig.suptitle(title)
|
|
138
|
+
if r > 16:
|
|
139
|
+
fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), ax=axes, pad=0, shrink=0.6)
|
|
140
|
+
fig.subplots_adjust(left=0, right=0.7, top=0.90, bottom=0.05, wspace=-0.6, hspace=0.4)
|
|
141
|
+
else:
|
|
142
|
+
fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), ax=axes, pad=0)
|
|
143
|
+
fig.subplots_adjust(left=0, right=0.7, top=0.90, bottom=0.05, wspace=-0.6, hspace=0.8)
|
|
144
|
+
|
|
145
|
+
set_size(3, 2)
|
|
146
|
+
plt.savefig(filename, dpi=150, transparent=True)
|
|
147
|
+
plt.close()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def generate_spam_err_std_pdf(
|
|
151
|
+
filename, E, rho, E2, rho2, basis_labels=False, title=None, magnification=10, return_fig=False
|
|
152
|
+
):
|
|
153
|
+
"""Generate pdf plots of two sets of POVM + state side by side in matrix shape - standard basis
|
|
154
|
+
The input sets can be either POVM/state directly or a difference different SPAM parametrizations to
|
|
155
|
+
visualize errors.
|
|
156
|
+
|
|
157
|
+
Parameters
|
|
158
|
+
----------
|
|
159
|
+
filename : str
|
|
160
|
+
The name under which the figures are saved in format "folder/name"
|
|
161
|
+
E : numpy array
|
|
162
|
+
POVM
|
|
163
|
+
rho : numpy array
|
|
164
|
+
Initial state
|
|
165
|
+
E2 : numpy array
|
|
166
|
+
POVM #2
|
|
167
|
+
rho2 : numpy array
|
|
168
|
+
Initial state #2
|
|
169
|
+
title : str
|
|
170
|
+
The Figure title
|
|
171
|
+
basis_labels : list[str]
|
|
172
|
+
A list of labels for the basis elements. For the standard basis this could be ["00", "01",...]
|
|
173
|
+
magnification : float
|
|
174
|
+
A factor to be applied to magnify errors in the rightmost plot.
|
|
175
|
+
return_fig : bool
|
|
176
|
+
If set to True, a figure object is returned by the function, otherwise the plot is saved as <filename>
|
|
177
|
+
Returns
|
|
178
|
+
-------
|
|
179
|
+
"""
|
|
180
|
+
dim = rho.shape[0]
|
|
181
|
+
pdim = int(np.sqrt(dim))
|
|
182
|
+
n_povm = E.shape[0]
|
|
183
|
+
|
|
184
|
+
fig, axes = plt.subplots(ncols=3, nrows=n_povm + 1, gridspec_kw={"width_ratios": [1, 1, 1]}, sharex=True)
|
|
185
|
+
plt.rc("image", cmap="RdBu")
|
|
186
|
+
|
|
187
|
+
for i in range(n_povm + 1):
|
|
188
|
+
if i == 0:
|
|
189
|
+
plot_matrices = [np.real(rho), np.real(rho2), np.real(rho - rho2)]
|
|
190
|
+
axes[i, 0].set_ylabel(f"rho", rotation=90, fontsize="large")
|
|
191
|
+
else:
|
|
192
|
+
plot_matrices = [np.real(E[i - 1]), np.real(E2[i - 1]), np.real(E[i - 1] - E2[i - 1]) * magnification]
|
|
193
|
+
axes[i, 0].set_ylabel(f"E_%i" % (i - 1), rotation=90, fontsize="large")
|
|
194
|
+
|
|
195
|
+
for j in range(3):
|
|
196
|
+
ax = axes[i, j]
|
|
197
|
+
ax.patch.set_facecolor("whitesmoke")
|
|
198
|
+
ax.set_aspect("equal")
|
|
199
|
+
for (x, y), w in np.ndenumerate(plot_matrices[j].reshape(pdim, pdim)):
|
|
200
|
+
size = np.sqrt(np.abs(w))
|
|
201
|
+
rect = plt.Rectangle(
|
|
202
|
+
[x + (1 - size) / 2, y + (1 - size) / 2],
|
|
203
|
+
size,
|
|
204
|
+
size,
|
|
205
|
+
facecolor=cmap((w + 1) / 2),
|
|
206
|
+
edgecolor=cmap((w + 1) / 2),
|
|
207
|
+
)
|
|
208
|
+
# print(cmap(size))
|
|
209
|
+
ax.add_patch(rect)
|
|
210
|
+
ax.invert_yaxis()
|
|
211
|
+
ax.set_xticks(np.arange(pdim + 1), labels=[])
|
|
212
|
+
|
|
213
|
+
ax.set_yticks(np.arange(pdim + 1), labels=[])
|
|
214
|
+
ax.tick_params(which="major", length=0) # Turn dummy ticks invisible
|
|
215
|
+
ax.tick_params(which="minor", top=True, labeltop=True, bottom=False, labelbottom=False, length=0, pad=1)
|
|
216
|
+
|
|
217
|
+
if pdim > 4:
|
|
218
|
+
ax.grid(visible="True", alpha=0.4, lw=0.1)
|
|
219
|
+
ax.set_xticks(np.arange(pdim) + 0.5, minor=True, labels=basis_labels, rotation=45, fontsize=2)
|
|
220
|
+
ax.set_yticks(np.arange(pdim) + 0.5, minor=True, labels=basis_labels, fontsize=2)
|
|
221
|
+
else:
|
|
222
|
+
ax.grid(visible="True", alpha=0.4)
|
|
223
|
+
ax.set_xticks(np.arange(pdim) + 0.5, minor=True, labels=basis_labels, rotation=45, fontsize=6)
|
|
224
|
+
ax.set_yticks(np.arange(pdim) + 0.5, minor=True, labels=basis_labels, fontsize=6)
|
|
225
|
+
if title:
|
|
226
|
+
fig.suptitle(title)
|
|
227
|
+
|
|
228
|
+
if dim > 16:
|
|
229
|
+
fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), ax=axes, pad=0, shrink=0.6)
|
|
230
|
+
fig.subplots_adjust(left=0, right=0.7, top=0.90, bottom=0.05, wspace=-0.6, hspace=0.4)
|
|
231
|
+
else:
|
|
232
|
+
fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), ax=axes, pad=0)
|
|
233
|
+
fig.subplots_adjust(left=0, right=0.7, top=0.90, bottom=0.05, wspace=-0.6, hspace=0.8)
|
|
234
|
+
|
|
235
|
+
if return_fig:
|
|
236
|
+
return fig
|
|
237
|
+
|
|
238
|
+
plt.savefig(filename, dpi=150, transparent=True)
|
|
239
|
+
plt.close()
|
|
240
|
+
return None
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def generate_gate_err_pdf(
|
|
244
|
+
filename, gates1, gates2, basis_labels=False, gate_labels=False, magnification=5, return_fig=False
|
|
245
|
+
):
|
|
246
|
+
"""Main routine to generate plots of reconstructed gates, ideal gates and the noise channels
|
|
247
|
+
of the reconstructed gates.
|
|
248
|
+
The basis is arbitrary but using gates in the Pauli basis is recommended.
|
|
249
|
+
|
|
250
|
+
Parameters
|
|
251
|
+
----------
|
|
252
|
+
filename : str
|
|
253
|
+
The name under which the figures are saved in format "folder/name"
|
|
254
|
+
gates1 : numpy array
|
|
255
|
+
A gate set in the same format as the "X"-tensor. These gates are assumed to be the GST estimates.
|
|
256
|
+
gates1 : numpy array
|
|
257
|
+
A gate set in the same format as the "X"-tensor. These are assumed to be the target gates.
|
|
258
|
+
basis_labels : list[str]
|
|
259
|
+
A list of labels for the basis elements. For the standard basis this could be ["00", "01",...]
|
|
260
|
+
and for the Pauli basis ["I", "X", "Y", "Z"] or the multi-qubit version.
|
|
261
|
+
gate_labels : list[str]
|
|
262
|
+
A list of names for the gates
|
|
263
|
+
magnification : float
|
|
264
|
+
A factor to be applied to magnify errors in the rightmost plot.
|
|
265
|
+
return_fig : bool
|
|
266
|
+
If set to True, a figure object is returned by the function, otherwise the plots are saved as <filename>
|
|
267
|
+
"""
|
|
268
|
+
d = gates1.shape[0]
|
|
269
|
+
dim = gates1[0].shape[0]
|
|
270
|
+
if not basis_labels:
|
|
271
|
+
basis_labels = np.arange(dim)
|
|
272
|
+
if not gate_labels:
|
|
273
|
+
gate_labels = [f"G%i" % k for k in range(d)]
|
|
274
|
+
plot3_title = r"id - G U^{-1}"
|
|
275
|
+
|
|
276
|
+
figures = []
|
|
277
|
+
for i in range(d):
|
|
278
|
+
if dim > 16:
|
|
279
|
+
fig, axes = plt.subplots(ncols=1, nrows=3, gridspec_kw={"height_ratios": [1, 1, 1]}, sharex=True)
|
|
280
|
+
else:
|
|
281
|
+
fig, axes = plt.subplots(ncols=3, nrows=1, gridspec_kw={"width_ratios": [1, 1, 1]}, sharex=True)
|
|
282
|
+
dim = gates1[0].shape[0]
|
|
283
|
+
plot_matrices = [
|
|
284
|
+
np.real(gates1[i]),
|
|
285
|
+
np.real(gates2[i]),
|
|
286
|
+
magnification * (np.eye(dim) - np.real(gates1[i] @ la.inv(gates2[i]))),
|
|
287
|
+
]
|
|
288
|
+
|
|
289
|
+
for j in range(3):
|
|
290
|
+
ax = axes[j]
|
|
291
|
+
ax.patch.set_facecolor("whitesmoke")
|
|
292
|
+
ax.set_aspect("equal")
|
|
293
|
+
for (x, y), w in np.ndenumerate(plot_matrices[j].T):
|
|
294
|
+
size = np.sqrt(np.abs(w))
|
|
295
|
+
rect = plt.Rectangle(
|
|
296
|
+
[x + (1 - size) / 2, y + (1 - size) / 2],
|
|
297
|
+
size,
|
|
298
|
+
size,
|
|
299
|
+
facecolor=cmap((w + 1) / 2),
|
|
300
|
+
edgecolor=cmap((w + 1) / 2),
|
|
301
|
+
)
|
|
302
|
+
ax.add_patch(rect)
|
|
303
|
+
ax.invert_yaxis()
|
|
304
|
+
ax.set_xticks(np.arange(dim + 1), labels=[])
|
|
305
|
+
ax.set_yticks(np.arange(dim + 1), labels=[])
|
|
306
|
+
|
|
307
|
+
if dim > 16:
|
|
308
|
+
ax.grid(visible="True", alpha=0.4, lw=0.1)
|
|
309
|
+
ax.set_xticks(np.arange(dim) + 0.5, minor=True, labels=basis_labels, fontsize=2, rotation=45)
|
|
310
|
+
else:
|
|
311
|
+
ax.grid(visible="True", alpha=0.4)
|
|
312
|
+
ax.set_xticks(np.arange(dim) + 0.5, minor=True, labels=basis_labels, rotation=45)
|
|
313
|
+
ax.set_yticks(np.arange(dim) + 0.5, minor=True, labels=basis_labels)
|
|
314
|
+
ax.tick_params(which="major", length=0) # Turn dummy ticks invisible
|
|
315
|
+
ax.tick_params(which="minor", top=True, labeltop=True, bottom=False, labelbottom=False, length=0)
|
|
316
|
+
|
|
317
|
+
axes[0].set_title(r"G (estimate)", fontsize="large")
|
|
318
|
+
axes[0].set_ylabel(gate_labels[i], rotation=90, fontsize="large")
|
|
319
|
+
axes[1].set_title(r"U (ideal gate)", fontsize="large")
|
|
320
|
+
axes[2].set_title(plot3_title, fontsize="large")
|
|
321
|
+
fig.suptitle(f"Process matrices in the Pauli basis", va="bottom")
|
|
322
|
+
|
|
323
|
+
if dim > 16:
|
|
324
|
+
fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), ax=axes.tolist(), pad=0, shrink=0.6)
|
|
325
|
+
fig.subplots_adjust(left=0.1, right=0.76, top=0.85, bottom=0.03)
|
|
326
|
+
set_size(0.5 * np.sqrt(dim), 1.3 * np.sqrt(dim))
|
|
327
|
+
else:
|
|
328
|
+
fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), ax=axes.tolist(), pad=0)
|
|
329
|
+
fig.subplots_adjust(left=0.1, right=0.76, top=0.85, bottom=0.03, hspace=0.2)
|
|
330
|
+
set_size(2 * np.sqrt(dim), 0.8 * np.sqrt(dim))
|
|
331
|
+
figures.append(fig)
|
|
332
|
+
if not return_fig:
|
|
333
|
+
plt.savefig(filename + f"G%i.pdf" % i, dpi=150, transparent=True, bbox_inches="tight")
|
|
334
|
+
return figures
|