iqm-benchmarks 2.26__py3-none-any.whl → 2.28__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.

@@ -0,0 +1,233 @@
1
+ # Copyright 2024 IQM Benchmarks developers
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ Plotting and visualization utility functions
17
+ """
18
+ from dataclasses import dataclass
19
+ from typing import Dict, Literal, Optional, Tuple
20
+
21
+ import matplotlib.pyplot as plt
22
+ import networkx as nx
23
+ import numpy as np
24
+ from qiskit.transpiler import CouplingMap
25
+ from rustworkx import PyGraph, spring_layout, visualization # pylint: disable=no-name-in-module
26
+
27
+ from iqm.benchmarks.utils import extract_fidelities
28
+
29
+
30
+ @dataclass
31
+ class GraphPositions:
32
+ """A class to store and generate graph positions for different chip layouts.
33
+
34
+ This class contains predefined node positions for various quantum chip topologies and
35
+ provides methods to generate positions for different layout types.
36
+
37
+ Attributes:
38
+ garnet_positions (Dict[int, Tuple[int, int]]): Mapping of node indices to (x,y) positions for Garnet chip.
39
+ deneb_positions (Dict[int, Tuple[int, int]]): Mapping of node indices to (x,y) positions for Deneb chip.
40
+ predefined_stations (Dict[str, Dict[int, Tuple[int, int]]]): Mapping of chip names to their position dictionaries.
41
+ """
42
+
43
+ garnet_positions = {
44
+ 0: (5.0, 7.0),
45
+ 1: (6.0, 6.0),
46
+ 2: (3.0, 7.0),
47
+ 3: (4.0, 6.0),
48
+ 4: (5.0, 5.0),
49
+ 5: (6.0, 4.0),
50
+ 6: (7.0, 3.0),
51
+ 7: (2.0, 6.0),
52
+ 8: (3.0, 5.0),
53
+ 9: (4.0, 4.0),
54
+ 10: (5.0, 3.0),
55
+ 11: (6.0, 2.0),
56
+ 12: (1.0, 5.0),
57
+ 13: (2.0, 4.0),
58
+ 14: (3.0, 3.0),
59
+ 15: (4.0, 2.0),
60
+ 16: (5.0, 1.0),
61
+ 17: (1.0, 3.0),
62
+ 18: (2.0, 2.0),
63
+ 19: (3.0, 1.0),
64
+ }
65
+
66
+ deneb_positions = {
67
+ 0: (2.0, 2.0),
68
+ 1: (1.0, 1.0),
69
+ 3: (2.0, 1.0),
70
+ 5: (3.0, 1.0),
71
+ 2: (1.0, 3.0),
72
+ 4: (2.0, 3.0),
73
+ 6: (3.0, 3.0),
74
+ }
75
+
76
+
77
+ predefined_stations = {"garnet": garnet_positions, "deneb": deneb_positions}
78
+
79
+ @staticmethod
80
+ def create_positions(
81
+ graph: PyGraph, topology: Optional[Literal["star", "crystal"]] = None
82
+ ) -> Dict[int, Tuple[float, float]]:
83
+ """Generate node positions for a given graph and topology.
84
+
85
+ Args:
86
+ graph (PyGraph): The graph to generate positions for.
87
+ topology (Optional[Literal["star", "crystal"]]): The type of layout to generate. Must be either "star" or "crystal".
88
+
89
+ Returns:
90
+ Dict[int, Tuple[float, float]]: A dictionary mapping node indices to (x,y) coordinates.
91
+ """
92
+ n_nodes = len(graph.node_indices())
93
+
94
+ if topology == "star":
95
+ # Place center node at (0,0)
96
+ pos = {0: (0.0, 0.0)}
97
+
98
+ if n_nodes > 1:
99
+ # Place other nodes in a circle around the center
100
+ angles = np.linspace(0, 2 * np.pi, n_nodes - 1, endpoint=False)
101
+ radius = 1.0
102
+
103
+ for i, angle in enumerate(angles, start=1):
104
+ x = radius * np.cos(angle)
105
+ y = radius * np.sin(angle)
106
+ pos[i] = (x, y)
107
+
108
+ # Crystal and other topologies
109
+ else:
110
+ # Fix first node position in bottom right
111
+ fixed_pos = {0: (1.0, 1.0)} # For more consistent layouts
112
+
113
+ # Get spring layout with one fixed position
114
+ pos = {
115
+ int(k): (float(v[0]), float(v[1]))
116
+ for k, v in spring_layout(graph, scale=2, pos=fixed_pos, num_iter=300, fixed={0}).items()
117
+ }
118
+ return pos
119
+
120
+
121
+ def plot_layout_fidelity_graph(
122
+ cal_url: str, qubit_layouts: Optional[list[list[int]]] = None, station: Optional[str] = None
123
+ ):
124
+ """Plot a graph showing the quantum chip layout with fidelity information.
125
+
126
+ Creates a visualization of the quantum chip topology where nodes represent qubits
127
+ and edges represent connections between qubits. Edge thickness indicates gate errors
128
+ (thinner edges mean better fidelity) and selected qubits are highlighted in orange.
129
+
130
+ Args:
131
+ cal_url: URL to retrieve calibration data from
132
+ qubit_layouts: List of qubit layouts where each layout is a list of qubit indices
133
+ station: Name of the quantum computing station to use predefined positions for.
134
+ If None, positions will be generated algorithmically.
135
+
136
+ Returns:
137
+ matplotlib.figure.Figure: The generated figure object containing the graph visualization
138
+ """
139
+ edges_cal, fidelities_cal, topology = extract_fidelities(cal_url)
140
+ weights = -np.log(np.array(fidelities_cal))
141
+ edges_graph = [tuple(edge) + (weight,) for edge, weight in zip(edges_cal, weights)]
142
+
143
+ graph = PyGraph()
144
+
145
+ # Add nodes
146
+ nodes: set[int] = set()
147
+ for edge in edges_graph:
148
+ nodes.update(edge[:2])
149
+ graph.add_nodes_from(list(nodes))
150
+
151
+ # Add edges
152
+ graph.add_edges_from(edges_graph)
153
+
154
+ # Define qubit positions in plot
155
+ if station is not None and station.lower() in GraphPositions.predefined_stations:
156
+ pos = GraphPositions.predefined_stations[station.lower()]
157
+ else:
158
+ pos = GraphPositions.create_positions(graph, topology)
159
+
160
+ # Define node colors
161
+ node_colors = ["lightgrey" for _ in range(len(nodes))]
162
+ if qubit_layouts is not None:
163
+ for qb in {qb for layout in qubit_layouts for qb in layout}:
164
+ node_colors[qb] = "orange"
165
+
166
+ # Ensuring weights are in correct order for the plot
167
+ edge_list = graph.edge_list()
168
+ weights_dict = {}
169
+ edge_pos = set()
170
+
171
+ # Create a mapping between edge positions as defined in rustworkx and their weights
172
+ for e, w in zip(edge_list, weights):
173
+ pos_tuple = (tuple(pos[e[0]]), tuple(pos[e[1]]))
174
+ weights_dict[pos_tuple] = w
175
+ edge_pos.add(pos_tuple)
176
+
177
+ # Get corresponding weights in the same order
178
+ weights_ordered = np.array([weights_dict[edge] for edge in list(edge_pos)])
179
+
180
+ plt.subplots(figsize=(6, 6))
181
+
182
+ # Draw the graph
183
+ visualization.mpl_draw(
184
+ graph,
185
+ with_labels=True,
186
+ node_color=node_colors,
187
+ pos=pos,
188
+ labels=lambda node: node,
189
+ width=7 * weights_ordered / np.max(weights_ordered),
190
+ ) # type: ignore[call-arg]
191
+
192
+ # Add edge labels using matplotlib's annotate
193
+ for edge in edges_graph:
194
+ x1, y1 = pos[edge[0]]
195
+ x2, y2 = pos[edge[1]]
196
+ x = (x1 + x2) / 2
197
+ y = (y1 + y2) / 2
198
+ plt.annotate(
199
+ f"{edge[2]:.1e}",
200
+ xy=(x, y),
201
+ xytext=(0, 0),
202
+ textcoords="offset points",
203
+ ha="center",
204
+ va="center",
205
+ bbox={"boxstyle": "round,pad=0.2", "fc": "white", "ec": "none", "alpha": 0.6},
206
+ )
207
+
208
+ plt.gca().invert_yaxis()
209
+ plt.title(
210
+ "Chip layout with selected qubits in orange\n"
211
+ + "and gate errors indicated by edge thickness (thinner is better)"
212
+ )
213
+ plt.show()
214
+
215
+
216
+ def rx_to_nx_graph(backend_coupling_map: CouplingMap) -> nx.Graph:
217
+ """Convert the Rustworkx graph returned by a backend to a Networkx graph.
218
+
219
+ Args:
220
+ backend_coupling_map (CouplingMap): The coupling map of the backend.
221
+
222
+ Returns:
223
+ networkx.Graph: The Networkx Graph corresponding to the backend graph.
224
+
225
+ """
226
+ # Generate a Networkx graph
227
+ graph_backend = backend_coupling_map.graph.to_undirected(multigraph=False)
228
+ backend_egdes, backend_nodes = (list(graph_backend.edge_list()), list(graph_backend.node_indices()))
229
+ backend_nx_graph = nx.Graph()
230
+ backend_nx_graph.add_nodes_from(backend_nodes)
231
+ backend_nx_graph.add_edges_from(backend_egdes)
232
+
233
+ return backend_nx_graph
@@ -0,0 +1,228 @@
1
+ # Copyright 2025 IQM Benchmarks developers
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ Shadow Tomography utility functions
17
+ """
18
+
19
+ import random
20
+ from typing import Dict, List, Literal, Optional, Sequence, Tuple, cast
21
+
22
+ import numpy as np
23
+ from numpy.random import RandomState
24
+ from qiskit import ClassicalRegister, QuantumCircuit, quantum_info
25
+ from qiskit.circuit.library import UnitaryGate
26
+ import scipy.linalg as spl
27
+
28
+ from iqm.benchmarks.utils import timeit
29
+
30
+
31
+ def CUE(random_gen: RandomState, n: int) -> np.ndarray:
32
+ """Prepares single qubit Haar-random unitary (drawn from Circuilar Unitary Ensemble - CUE).
33
+
34
+ Args:
35
+ random_gen (RandomState): a random generator.
36
+ n (int): the size of the matrix.
37
+ Returns:
38
+ np.ndarray: an n x n CUE matrix
39
+ """
40
+ # Generate an N × N complex matrix Z with standard normal entries
41
+ Z = (random_gen.randn(n, n) + 1j * random_gen.randn(n, n)) / np.sqrt(2.0)
42
+
43
+ # Perform QR decomposition, Z = QR
44
+ Q, R = spl.qr(Z)
45
+
46
+ # Create the diagonal matrix Lambda
47
+ Lambda = np.diag(R.diagonal() / np.abs(R.diagonal()))
48
+
49
+ # Compute U = Q * Lambda, which is Haar-distributed
50
+ U = Q @ Lambda
51
+
52
+ return U
53
+
54
+
55
+ @timeit
56
+ def local_shadow_tomography(
57
+ qc: QuantumCircuit,
58
+ Nu: int,
59
+ active_qubits: Sequence[int],
60
+ measure_other: Optional[Sequence[int]] = None,
61
+ measure_other_name: Optional[str] = None,
62
+ clifford_or_haar: Literal["clifford", "haar"] = "clifford",
63
+ cliffords_1q: Optional[Dict[str, QuantumCircuit]] = None,
64
+ ) -> Tuple[np.ndarray | Dict[str, List[str]], List[QuantumCircuit]]:
65
+ """
66
+ Prepares the circuits to perform local Haar or Clifford shadow tomography.
67
+
68
+ Args:
69
+ qc (QuantumCircuit): The quantum circuit to which random unitaries are appended.
70
+ Nu (int): Number of local random unitaries used.
71
+ active_qubits (Sequence[int]): The Sequence of active qubits.
72
+ measure_other (Optional[Sequence[int]]): Whether to measure other qubits in the qc QuantumCircuit.
73
+ * Default is None.
74
+ measure_other_name (Optional[str]): Name of the classical register to assign measure_other.
75
+ clifford_or_haar (Literal["clifford", "haar"]): Whether to use Clifford or Haar random 1Q gates.
76
+ * Default is "clifford".
77
+ cliffords_1q (Optional[Dict[str, QuantumCircuit]]): Dictionary of 1-qubit Cliffords in terms of IQM-native r and CZ gates.
78
+ * Default is None.
79
+
80
+ Raises:
81
+ ValueError: If clifford_or_haar is not "clifford" or "haar".
82
+ ValueError: If cliffords_1q is None and clifford_or_haar is "clifford".
83
+
84
+ Returns:
85
+ Tuple[np.ndarray | Dict[str, List[str]], List[QuantumCircuit]]:
86
+ - ndarray | Dict[str, List[str]]: Either:
87
+ * Unitary gate (numpy ndarray), composed of local unitaries for each random initialisation and qubit, if clifford_or_haar == 'haar'.
88
+ * Dictionary of lists of Clifford labels corresponding to each RM, keys being str(qubit), if clifford_or_haar == 'clifford'.
89
+ - List[QuantumCircuit]: List of tomography circuits.
90
+ """
91
+ if clifford_or_haar not in ["clifford", "haar"]:
92
+ raise ValueError("clifford_or_haar must be either 'clifford' or 'haar'.")
93
+ if clifford_or_haar == "clifford" and cliffords_1q is None:
94
+ raise ValueError("cliffords_1q dictionary must be provided if clifford_or_haar is 'clifford'.")
95
+ if clifford_or_haar == "clifford":
96
+ # Get the keys of the Clifford dictionaries
97
+ clifford_1q_keys = list(cast(Dict, cliffords_1q).keys())
98
+
99
+ qclist = []
100
+ seed = random.SystemRandom().randrange(2**32 - 1) # Init Random Generator
101
+ random_gen: RandomState = np.random.RandomState(seed) # pylint: disable=no-member
102
+
103
+ unitaries: Dict[str, List[str]] | np.ndarray
104
+ if clifford_or_haar == "haar":
105
+ unitaries = np.zeros((Nu, len(active_qubits), 2, 2), dtype=np.complex_)
106
+ else:
107
+ unitaries = {str(q): [] for q in active_qubits}
108
+
109
+ for u in range(Nu):
110
+ qc_copy = qc.copy()
111
+ for q_idx, qubit in enumerate(active_qubits):
112
+ if clifford_or_haar == "haar":
113
+ temp_U = CUE(random_gen, 2)
114
+ qc_copy.append(UnitaryGate(temp_U), [qubit])
115
+ cast(np.ndarray, unitaries)[u, q_idx, :, :] = np.array(temp_U)
116
+ elif clifford_or_haar == "clifford":
117
+ rand_key = random.choice(clifford_1q_keys)
118
+ c_1q = cast(dict, cliffords_1q)[rand_key]
119
+ qc_copy.compose(c_1q, qubits=[qubit], inplace=True)
120
+ cast(dict, unitaries)[str(qubit)].append(rand_key)
121
+
122
+ qc_copy.barrier()
123
+
124
+ register_rm = ClassicalRegister(len(active_qubits), "RMs")
125
+ qc_copy.add_register(register_rm)
126
+ qc_copy.measure(active_qubits, register_rm)
127
+
128
+ if measure_other is not None:
129
+ if measure_other_name is None:
130
+ measure_other_name = "non_RMs"
131
+ register_neighbors = ClassicalRegister(len(measure_other), measure_other_name)
132
+ qc_copy.add_register(register_neighbors)
133
+ qc_copy.measure(measure_other, register_neighbors)
134
+
135
+ qclist.append(qc_copy)
136
+
137
+ return unitaries, qclist
138
+
139
+
140
+ def get_local_shadow(
141
+ counts: Dict[str, int],
142
+ unitary_arg: np.ndarray | Sequence[str],
143
+ subsystem_bit_indices: Sequence[int],
144
+ clifford_or_haar: Literal["clifford", "haar"] = "clifford",
145
+ cliffords_1q: Optional[Dict[str, QuantumCircuit]] = None,
146
+ ) -> np.ndarray:
147
+ """Constructs shadows for each individual initialisation.
148
+
149
+ Args:
150
+ counts (Dict[str, int]): a dictionary of bit-string counts.
151
+ unitary_arg (np.ndarray | Sequence[str]): local random unitaries used for a given initialisation, either specified as
152
+ - a numpy array, or
153
+ - a Sequence of Clifford labels.
154
+ subsystem_bit_indices (Sequence[int]): Bit indices in the counts of the subsystem to construct the shadow of.
155
+ clifford_or_haar (Literal["clifford", "haar"]): Whether to use Clifford or Haar random 1Q gates.
156
+ * Default is "clifford".
157
+ cliffords_1q (Optional[Dict[str, QuantumCircuit]]): dictionary of 1-qubit Cliffords in terms of IQM-native r and CZ gates
158
+ * Default is None.
159
+
160
+ Returns:
161
+ np.ndarray: shadow of considered subsystem.
162
+ """
163
+ if clifford_or_haar not in ["clifford", "haar"]:
164
+ raise ValueError("clifford_or_haar must be either 'clifford' or 'haar'.")
165
+ if clifford_or_haar == "clifford" and cliffords_1q is None:
166
+ raise ValueError("cliffords_1q dictionary must be provided if clifford_or_haar is 'clifford'.")
167
+ if clifford_or_haar == "haar" and isinstance(unitary_arg, Sequence):
168
+ raise ValueError("If clifford_or_haar is 'haar', the unitary operator must be a numpy array.")
169
+ if clifford_or_haar == "clifford" and not isinstance(unitary_arg, Sequence):
170
+ raise ValueError(
171
+ "If clifford_or_haar is 'clifford', the unitary operator must be specified as a Sequence of strings."
172
+ )
173
+
174
+ nqubits = len(subsystem_bit_indices)
175
+ rhoshadows = np.zeros([2**nqubits, 2**nqubits], dtype=complex)
176
+ proj = np.zeros((2, 2, 2), dtype=complex)
177
+ proj[0, :, :] = np.array([[1, 0], [0, 0]])
178
+ proj[1, :, :] = np.array([[0, 0], [0, 1]])
179
+ shots = sum(list(counts.values()))
180
+
181
+ unitary_op: np.ndarray
182
+ if clifford_or_haar == "haar":
183
+ unitary_op = cast(np.ndarray, unitary_arg)
184
+ else:
185
+ unitary_op = np.zeros((nqubits, 2, 2), dtype=complex)
186
+ for qubit_idx, clif_label in enumerate(unitary_arg):
187
+ unitary_op[qubit_idx, :, :] = quantum_info.Operator(cast(dict, cliffords_1q)[clif_label]).to_matrix()
188
+
189
+ for bit_strings in counts.keys():
190
+ rho_j: int | np.ndarray = 1
191
+ for j in subsystem_bit_indices:
192
+ s_j = int(bit_strings[::-1][j])
193
+ rho_j = np.kron(
194
+ rho_j,
195
+ 3
196
+ * np.einsum(
197
+ "ab,bc,cd", np.transpose(np.conjugate(unitary_op[j, :, :])), proj[s_j, :, :], unitary_op[j, :, :]
198
+ )
199
+ - np.array([[1, 0], [0, 1]]),
200
+ )
201
+
202
+ rhoshadows += rho_j * counts[bit_strings] / shots
203
+
204
+ return rhoshadows
205
+
206
+
207
+ def get_negativity(rho: np.ndarray, NA: int, NB: int) -> float:
208
+ """Computes the negativity of a given density matrix.
209
+ Note that a negativity >0 is only a necessary and sufficient condition for entanglement if NA = NB = 1. For more qubits per subsystems it is merely a necessary condition.
210
+ Args:
211
+ rho (np.ndarray): Density matrix.
212
+ NA (int): Number of qubits for subsystem A.
213
+ NB (int): Number of qubits for subsystem B.
214
+ Returns:
215
+ float: the negativity of the input density matrix.
216
+ """
217
+ da = 2**NA
218
+ db = 2**NB
219
+ rho = rho.reshape(da, db, da, db)
220
+ # TODO: # pylint: disable=fixme
221
+ # This is a one-liner here, but generally it would be nicer to have
222
+ # a partial transpose function w.r.t. any subsystem in the utils file!
223
+ rho_t = np.einsum("ijkl -> kjil", rho)
224
+ rho_t = rho_t.reshape(2 ** (NA + NB), 2 ** (NA + NB))
225
+ evals, _ = np.linalg.eig(rho_t)
226
+ neg = np.sum([np.abs(i) - i for i in np.real(evals)]) / 2
227
+
228
+ return neg
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iqm-benchmarks
3
- Version: 2.26
3
+ Version: 2.28
4
4
  Summary: A package for implementation of Quantum Characterization, Verification and Validation (QCVV) techniques on IQM's hardware at gate level abstraction
5
5
  Author-email: IQM Finland Oy <developers@meetiqm.com>, Adrian Auer <adrian.auer@meetiqm.com>, Raphael Brieger <raphael.brieger@meetiqm.com>, Alessio Calzona <alessio.calzona@meetiqm.com>, Pedro Figueroa Romero <pedro.romero@meetiqm.com>, Amin Hosseinkhani <amin.hosseinkhani@meetiqm.com>, Miikka Koistinen <miikka@meetiqm.com>, Nadia Milazzo <nadia.milazzo@meetiqm.com>, Vicente Pina Canelles <vicente.pina@meetiqm.com>, Aniket Rath <aniket.rath@meetiqm.com>, Jami Rönkkö <jami@meetiqm.com>, Stefan Seegerer <stefan.seegerer@meetiqm.com>
6
6
  Project-URL: Homepage, https://github.com/iqm-finland/iqm-benchmarks
@@ -16,10 +16,11 @@ Requires-Dist: matplotlib<4,>=3.6.3
16
16
  Requires-Dist: more-itertools<11.0.0,>=10.1.0
17
17
  Requires-Dist: mthree<2.7,>=2.6
18
18
  Requires-Dist: networkx<4.0,>=3.3
19
- Requires-Dist: rustworkx>=0.15.1
19
+ Requires-Dist: rustworkx>=0.16.0
20
20
  Requires-Dist: numpy<2.0,>=1.25.2
21
- Requires-Dist: qiskit<2.0,>=1.0
22
- Requires-Dist: qiskit-iqm<16.0,>=15.1
21
+ Requires-Dist: qiskit<2.0,>=1.2.4
22
+ Requires-Dist: qiskit-iqm<18.0,>=17.8
23
+ Requires-Dist: iqm-client>=22.7
23
24
  Requires-Dist: scikit-optimize<0.11.0,>=0.10.2
24
25
  Requires-Dist: tabulate<1.0.0,>=0.9.0
25
26
  Requires-Dist: uncertainties<3.3.0,>=3.2.2
@@ -68,6 +69,7 @@ Below is a list of the benchmarks currently available in the suite:
68
69
  - CLOPS [[arXiv:2110.14108 [quant-ph]](https://arxiv.org/abs/2110.14108) (2021)]
69
70
  * Entanglement:
70
71
  - GHZ State Fidelity [[arXiv:0712.0921 [quant-ph]](https://arxiv.org/abs/0712.0921) (2007)]
72
+ - Graph State Bipartite Entanglement [[Adv. Quantum Technol., 2100061](https://doi.org/10.1002/qute.202100061) (2021)]
71
73
  * Optimization:
72
74
  - Q-Score [[IEEE Trans. Quantum Eng., 2](https://doi.org/10.1109/TQE.2021.3090207) (2021)]
73
75
 
@@ -1,43 +1,46 @@
1
- iqm/benchmarks/__init__.py,sha256=8SRHlADqZjlP8PtbKTMvu-ejpcEZkW8cPmgW8GVKJg8,2638
1
+ iqm/benchmarks/__init__.py,sha256=74NuBycITM-CV7nx0l1T2wbnQDdVmF8jTZVE0KpG7pc,2773
2
2
  iqm/benchmarks/benchmark.py,sha256=3E7g7RQjCIGIpSI1gOSrI3V9SAVs-XEOMrPgToK_7vw,4972
3
3
  iqm/benchmarks/benchmark_definition.py,sha256=e4xe0wlWKZqj48_6-zTglMaMeoiA9aGkHrrSgoCfPkM,11271
4
4
  iqm/benchmarks/circuit_containers.py,sha256=anEtZEsodYqOX-34oZRmuKGeEpp_VfgG5045Mz4-4hI,7562
5
5
  iqm/benchmarks/logging_config.py,sha256=U7olP5Kr75AcLJqNODf9VBhJLVqIvA4AYR6J39D5rww,1052
6
6
  iqm/benchmarks/readout_mitigation.py,sha256=Q2SOGWTNgmklOYkNxepAaSaXlxSj0QQyymYY1bOkT8A,11756
7
- iqm/benchmarks/utils.py,sha256=_1iLsc-azCE4ucHlD1LLRPdTryUKaMs8r75q3njRugE,33451
7
+ iqm/benchmarks/utils.py,sha256=2aEwFhZAHBmqLjSMtnqjuWcXCyMX3vpUfF-vqoeBIHw,38517
8
+ iqm/benchmarks/utils_plots.py,sha256=Y2AQdY92hopDEWmM5KUvF79OqEBTNAUgahwomjhEKZE,8036
9
+ iqm/benchmarks/utils_shadows.py,sha256=e77PV_uaAO5m_woox9lAzompKAvFeDJ-0AKJrNJ7NFg,9728
8
10
  iqm/benchmarks/compressive_gst/__init__.py,sha256=LneifgYXtcwo2jcXo7GdUEHL6_peipukShhkrdaTRCA,929
9
11
  iqm/benchmarks/compressive_gst/compressive_gst.py,sha256=2kiRttog4jR-vtMHu847GTFe5qL_i_uYr_4WMGqt9Ww,25653
10
- iqm/benchmarks/compressive_gst/gst_analysis.py,sha256=SZ4IbRYDTDTc_5DK7wXOeP_QIY48vA63I7JkPdwVbgs,36374
11
- iqm/benchmarks/entanglement/__init__.py,sha256=9T7prOwqMmFWdb4t6ETAHZXKK5o6FvU2DvVb6WhNi-U,682
12
- iqm/benchmarks/entanglement/ghz.py,sha256=jSPcdFf1Xsq09EJXKCVHzNXjQIdAoDg859279wKGjaQ,41075
12
+ iqm/benchmarks/compressive_gst/gst_analysis.py,sha256=jA1MaXIyPBwxbN36mTjn_jKaRO5-NdoG0YV-RaujU3s,36450
13
+ iqm/benchmarks/entanglement/__init__.py,sha256=sHVVToRWRCz0LSntk1rQaoSNNeyZLPoiTjUKWZWrk1E,778
14
+ iqm/benchmarks/entanglement/ghz.py,sha256=RGA6ynJFsfaCJv0nKccsiIzPk2G-iHHvIeW8LVu30HY,41249
15
+ iqm/benchmarks/entanglement/graph_states.py,sha256=okWdpASQewZ62UaHks2N-tvCgCsUtIkz8dBoX1xh6Jk,62512
13
16
  iqm/benchmarks/optimization/__init__.py,sha256=_ajW_OibYLCtzU5AUv5c2zuuVYn8ZNeZUcUUSIGt51M,747
14
- iqm/benchmarks/optimization/qscore.py,sha256=ufkIKuh0XtiSVn-3Deca-7Ky1cXZ1CxCXMN-j-Lhevw,38132
17
+ iqm/benchmarks/optimization/qscore.py,sha256=KOw8fjXeMwCjYvKukpX7IiAqRQrVTkrnIgKjNCPVWdw,38130
15
18
  iqm/benchmarks/quantum_volume/__init__.py,sha256=i-Q4SpDWELBw7frXnxm1j4wJRcxbIyrS5uEK_v06YHo,951
16
- iqm/benchmarks/quantum_volume/clops.py,sha256=xlziaxjhJUNyHjBCMzMLeJ9PcFNBtDO7urKvCTBb4sI,31471
17
- iqm/benchmarks/quantum_volume/quantum_volume.py,sha256=4ll3R8AX-BA599TEaMBzE2rJtAzHLtCkq8CaSkJfA0Y,36626
19
+ iqm/benchmarks/quantum_volume/clops.py,sha256=fD_eh10qHv_W-_mCA-PjPDIxNJ5sqD7yDkK1UjRsAAo,31474
20
+ iqm/benchmarks/quantum_volume/quantum_volume.py,sha256=pro7Lz-A5pPpT9UZ8wtXKTyhdWmTjQjRHt4BylDR-3U,36553
18
21
  iqm/benchmarks/randomized_benchmarking/__init__.py,sha256=IkKo-7zUChxZZd3my_csQCJfJfZNsV3-JTvdG8uqys4,734
19
- iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl,sha256=vvSd0pRWxtzyirohO9yf_58mjevkc2-pbuWIEb-4gaw,46928
20
- iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl,sha256=ZipqU3crPhz2T35qGFgB4GvMyoi_7pnu8NqW5ZP8NXg,90707258
22
+ iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl,sha256=yrmSJqhv7Lb1yqiqU9-2baqTljJPNmTUPQR-AH6GGfc,7800
23
+ iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl,sha256=mJQLubWPOb-DbmFi4oKYJqAMW_Yyo3eJjRjLGl9Sqmo,10282247
21
24
  iqm/benchmarks/randomized_benchmarking/multi_lmfit.py,sha256=Se1ygR4mXn_2_P82Ch31KBnCmY-g_A9NKzE9Ir8nEvw,3247
22
- iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py,sha256=pe9wSFvQ6Vh7rWZNZalIKOeaHoXc8iT4pkvrcLmY75g,42352
25
+ iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py,sha256=MryufwrOCBcZZHDeX9WGHVtYhFz2XtS3xLm6YQYEAM4,43160
23
26
  iqm/benchmarks/randomized_benchmarking/clifford_rb/__init__.py,sha256=bTDA156LAl7OLGcMec--1nzDrV1XpPRVq3CquTmucgE,677
24
27
  iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py,sha256=IGBrq_a9eaVPknkBLKHKS4BOcumHn6TZdasUNKTZjGI,18685
25
28
  iqm/benchmarks/randomized_benchmarking/interleaved_rb/__init__.py,sha256=sq6MgN_hwlpkOj10vyCU4e6eKSX-oLcF2L9na6W2Gt4,681
26
29
  iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py,sha256=TaR1YFWBhOgm1hmEQzuwLYpp0yl0Xpuo3jAT6YhiXpc,28471
27
30
  iqm/benchmarks/randomized_benchmarking/mirror_rb/__init__.py,sha256=ZekEqI_89nXzGO1vjM-b5Uwwicy59M4fYHXfA-f0MIg,674
28
- iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py,sha256=QAivrFMV98JELa28tTV4DkW7XKuSU2I5sL6lkg6syUs,34994
29
- iqm_benchmarks-2.26.dist-info/licenses/LICENSE,sha256=2Ncb40-hqkTil78RPv3-YiJfKaJ8te9USJgliKqIdSY,11558
31
+ iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py,sha256=_xdp8XLPcZyuqy7Xz8-K8H7zjgRo9ZxFiDgCXE72gaE,34997
32
+ iqm_benchmarks-2.28.dist-info/licenses/LICENSE,sha256=2Ncb40-hqkTil78RPv3-YiJfKaJ8te9USJgliKqIdSY,11558
30
33
  mGST/LICENSE,sha256=TtHNq55cUcbglb7uhVudeBLUh_qPdUoAEvU0BBwFz-k,1098
31
34
  mGST/README.md,sha256=v_5kw253csHF4-RfE-44KqFmBXIsSMRmOtN0AUPrRxE,5050
32
35
  mGST/additional_fns.py,sha256=_SEJ10FRNM7_CroysT8hCLZTfpm6ZhEIDCY5zPTnhjo,31390
33
- mGST/algorithm.py,sha256=SRwC1sVFShRVxQDfH1bhUvnquvgwJFLSiZ70qo5SwxE,26314
36
+ mGST/algorithm.py,sha256=QnxLJtxZysggLUtbZE-c2MWaFclZB2XUVJhvrmUvjVs,26315
34
37
  mGST/compatibility.py,sha256=00DsPnNfOtrQcDTvxBDs-0aMhmuXmOIIxl_Ohy-Emkg,8920
35
38
  mGST/low_level_jit.py,sha256=uE1D3v01FbPpsbP92C4220OQalzOfxgL1Ku89BNkxLY,27377
36
39
  mGST/optimization.py,sha256=YHwkzIkYvsZOPjclR-BCQWh24jeqjuXp0BB0WX5Lwow,10559
37
40
  mGST/qiskit_interface.py,sha256=ajx6Zn5FnrX_T7tMP8xnBLyG4c2ddFRm0Fu2_3r1t30,10118
38
41
  mGST/reporting/figure_gen.py,sha256=6Xd8vwfy09hLY1YbJY6TRevuMsQSU4MsWqemly3ZO0I,12970
39
42
  mGST/reporting/reporting.py,sha256=B8NWfpZrrSmyH7lwZxd0EbZMYLsAGK1YsHRB4D5qXH4,26002
40
- iqm_benchmarks-2.26.dist-info/METADATA,sha256=yrczoXmgJh34bMhbo-XTomCKT9XowiP6hw61tpxacUQ,10555
41
- iqm_benchmarks-2.26.dist-info/WHEEL,sha256=tTnHoFhvKQHCh4jz3yCn0WPTYIy7wXx3CJtJ7SJGV7c,91
42
- iqm_benchmarks-2.26.dist-info/top_level.txt,sha256=3G23Z-1LGf-IOzTCUl6QwWqiQ3USz25Zt90Ihq192to,9
43
- iqm_benchmarks-2.26.dist-info/RECORD,,
43
+ iqm_benchmarks-2.28.dist-info/METADATA,sha256=sRwA84uA95W9hBB-hy5KYVZFvOg6eSwhQVC9nTjMFLw,10710
44
+ iqm_benchmarks-2.28.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
45
+ iqm_benchmarks-2.28.dist-info/top_level.txt,sha256=3G23Z-1LGf-IOzTCUl6QwWqiQ3USz25Zt90Ihq192to,9
46
+ iqm_benchmarks-2.28.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.1)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
mGST/algorithm.py CHANGED
@@ -727,7 +727,7 @@ def run_mGST(
727
727
  qcvv_logger.info(f"Convergence criterion satisfied")
728
728
  else:
729
729
  qcvv_logger.info(
730
- f"Convergence criterion not satisfied,inspect results and consider increasing max_iter or using new initializations.",
730
+ f"Convergence criterion not satisfied, inspect results and consider increasing max_iter or using new initializations.",
731
731
  )
732
732
  qcvv_logger.info(
733
733
  f"Final objective {Decimal(res_list[-1]):.2e} in time {(time.time() - t0):.2f}s",