qec 0.2.6__py3-none-any.whl → 0.2.7__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.
- qec/code_constructions/__init__.py +0 -1
- qec/code_constructions/hgp_code.py +100 -56
- {qec-0.2.6.dist-info → qec-0.2.7.dist-info}/METADATA +1 -1
- {qec-0.2.6.dist-info → qec-0.2.7.dist-info}/RECORD +7 -7
- {qec-0.2.6.dist-info → qec-0.2.7.dist-info}/LICENSE +0 -0
- {qec-0.2.6.dist-info → qec-0.2.7.dist-info}/WHEEL +0 -0
- {qec-0.2.6.dist-info → qec-0.2.7.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,13 @@
|
|
1
1
|
import numpy as np
|
2
|
-
import scipy
|
2
|
+
import scipy
|
3
3
|
from typing import Union, Tuple
|
4
|
-
import ldpc.mod2
|
4
|
+
import ldpc.mod2
|
5
5
|
import time
|
6
6
|
|
7
7
|
from qec.code_constructions import CSSCode
|
8
8
|
from qec.utils.sparse_binary_utils import convert_to_binary_scipy_sparse
|
9
9
|
|
10
|
+
|
10
11
|
class HypergraphProductCode(CSSCode):
|
11
12
|
"""
|
12
13
|
Implements a Hypergraph Product (HGP) code - derived from two classical linear binary codes.
|
@@ -59,15 +60,19 @@ class HypergraphProductCode(CSSCode):
|
|
59
60
|
|
60
61
|
def __init__(
|
61
62
|
self,
|
62
|
-
seed_matrix_1
|
63
|
-
seed_matrix_2
|
64
|
-
name
|
63
|
+
seed_matrix_1: Union[np.ndarray, scipy.sparse.spmatrix],
|
64
|
+
seed_matrix_2: Union[np.ndarray, scipy.sparse.spmatrix],
|
65
|
+
name: str = None,
|
65
66
|
):
|
66
|
-
|
67
67
|
self.name = name if name else "Hypergraph product code"
|
68
68
|
|
69
|
-
if not all(
|
70
|
-
|
69
|
+
if not all(
|
70
|
+
isinstance(seed_m, (np.ndarray, scipy.sparse.spmatrix))
|
71
|
+
for seed_m in (seed_matrix_1, seed_matrix_2)
|
72
|
+
):
|
73
|
+
raise TypeError(
|
74
|
+
"The seed matrices must be either numpy arrays or scipy sparse matrices."
|
75
|
+
)
|
71
76
|
|
72
77
|
self.seed_matrix_1 = convert_to_binary_scipy_sparse(seed_matrix_1)
|
73
78
|
self.seed_matrix_2 = convert_to_binary_scipy_sparse(seed_matrix_2)
|
@@ -90,31 +95,30 @@ class HypergraphProductCode(CSSCode):
|
|
90
95
|
# --------------------------------------------------------------------------
|
91
96
|
|
92
97
|
super().__init__(self.x_stabilizer_matrix, self.z_stabilizer_matrix, self.name)
|
93
|
-
|
94
98
|
|
95
99
|
def compute_exact_code_distance(self) -> int:
|
96
100
|
"""
|
97
101
|
Computes the exact code distance of the HGP code.
|
98
|
-
|
102
|
+
|
99
103
|
Returns
|
100
104
|
-------
|
101
|
-
int
|
102
|
-
The distance of the code.
|
105
|
+
int
|
106
|
+
The distance of the code.
|
103
107
|
|
104
108
|
Notes
|
105
109
|
-----
|
106
|
-
The distance of a HGP code is given as:
|
107
|
-
|
110
|
+
The distance of a HGP code is given as:
|
111
|
+
|
108
112
|
.. math::
|
109
113
|
|
110
114
|
\min(d_1, d_2, d_1^T, d_2^T)
|
111
115
|
|
112
116
|
corresponding to the distance of the seed codes and the distance of their transposes.
|
113
117
|
"""
|
114
|
-
|
118
|
+
|
115
119
|
rank_seed_m1 = ldpc.mod2.rank(self.seed_matrix_1)
|
116
120
|
rank_seed_m2 = ldpc.mod2.rank(self.seed_matrix_2)
|
117
|
-
|
121
|
+
|
118
122
|
if self.seed_matrix_1.shape[1] != rank_seed_m1:
|
119
123
|
self.d1 = ldpc.mod2.compute_exact_code_distance(self.seed_matrix_1)
|
120
124
|
else:
|
@@ -124,7 +128,7 @@ class HypergraphProductCode(CSSCode):
|
|
124
128
|
self.d2 = ldpc.mod2.compute_exact_code_distance(self.seed_matrix_2)
|
125
129
|
else:
|
126
130
|
self.d2 = np.inf
|
127
|
-
|
131
|
+
|
128
132
|
# note: rank(A) = rank(A^T):
|
129
133
|
if self.seed_matrix_1.shape[0] != rank_seed_m1:
|
130
134
|
self.d1T = ldpc.mod2.compute_exact_code_distance(self.seed_matrix_1.T)
|
@@ -141,70 +145,86 @@ class HypergraphProductCode(CSSCode):
|
|
141
145
|
self.code_distance = min(self.x_code_distance, self.z_code_distance)
|
142
146
|
|
143
147
|
return self.code_distance
|
144
|
-
|
145
148
|
|
146
149
|
def estimate_min_distance(self, timeout_seconds: float = 0.025) -> int:
|
147
150
|
"""
|
148
151
|
Estimate the minimum X and Z distance of the HGP code. Parameters
|
149
152
|
----------
|
150
|
-
timeout_seconds : float, optional
|
151
|
-
Time limit in seconds for the full search. Default: 0.25
|
152
|
-
|
153
|
+
timeout_seconds : float, optional
|
154
|
+
Time limit in seconds for the full search. Default: 0.25
|
155
|
+
|
153
156
|
Returns
|
154
157
|
-------
|
155
158
|
int
|
156
|
-
Best estimate of the (overall) code distance found within time limit.
|
159
|
+
Best estimate of the (overall) code distance found within time limit.
|
157
160
|
|
158
161
|
"""
|
159
|
-
|
162
|
+
|
160
163
|
rank_seed_m1 = ldpc.mod2.rank(self.seed_matrix_1)
|
161
164
|
rank_seed_m2 = ldpc.mod2.rank(self.seed_matrix_2)
|
162
165
|
|
163
|
-
|
164
|
-
|
165
|
-
if self.seed_matrix_1.shape[1] != rank_seed_m1:
|
166
|
+
d1_timeout_seconds = timeout_seconds / 4
|
167
|
+
if self.seed_matrix_1.shape[1] != rank_seed_m1:
|
166
168
|
d1_start_time = time.time()
|
167
|
-
d1_min_estimate, _, _ = ldpc.mod2.estimate_code_distance(
|
169
|
+
d1_min_estimate, _, _ = ldpc.mod2.estimate_code_distance(
|
170
|
+
self.seed_matrix_1, d1_timeout_seconds, 0
|
171
|
+
)
|
168
172
|
d1_run_time = time.time() - d1_start_time
|
169
173
|
else:
|
170
174
|
d1_min_estimate = np.inf
|
171
175
|
d1_run_time = 0
|
172
176
|
|
173
|
-
d1T_timeout_seconds = (
|
177
|
+
d1T_timeout_seconds = (
|
178
|
+
(d1_timeout_seconds * 4 - d1_run_time) / 3
|
179
|
+
if d1_run_time <= d1_timeout_seconds
|
180
|
+
else timeout_seconds / 4
|
181
|
+
)
|
174
182
|
if self.seed_matrix_1.shape[0] != rank_seed_m1:
|
175
183
|
d1T_start_time = time.time()
|
176
|
-
d1T_min_estimate, _, _ = ldpc.mod2.estimate_code_distance(
|
184
|
+
d1T_min_estimate, _, _ = ldpc.mod2.estimate_code_distance(
|
185
|
+
self.seed_matrix_1.T, d1T_timeout_seconds, 0
|
186
|
+
)
|
177
187
|
d1T_run_time = time.time() - d1T_start_time
|
178
188
|
else:
|
179
189
|
d1T_min_estimate = np.inf
|
180
190
|
d1T_run_time = 0
|
181
191
|
|
182
|
-
d2_timeout_seconds = (
|
192
|
+
d2_timeout_seconds = (
|
193
|
+
(d1T_timeout_seconds * 3 - d1T_run_time) / 2
|
194
|
+
if d1T_run_time <= d1T_timeout_seconds
|
195
|
+
else timeout_seconds / 4
|
196
|
+
)
|
183
197
|
if self.seed_matrix_2.shape[1] != rank_seed_m2:
|
184
198
|
d2_start_time = time.time()
|
185
|
-
d2_min_estimate, _, _ = ldpc.mod2.estimate_code_distance(
|
199
|
+
d2_min_estimate, _, _ = ldpc.mod2.estimate_code_distance(
|
200
|
+
self.seed_matrix_2, d2_timeout_seconds, 0
|
201
|
+
)
|
186
202
|
d2_run_time = time.time() - d2_start_time
|
187
203
|
else:
|
188
204
|
d2_min_estimate = np.inf
|
189
205
|
d2_run_time = 0
|
190
206
|
|
191
|
-
|
192
|
-
|
207
|
+
d2T_timeout_seconds = (
|
208
|
+
(d2_timeout_seconds * 2 - d2_run_time)
|
209
|
+
if d2_run_time <= d2_timeout_seconds
|
210
|
+
else timeout_seconds / 4
|
211
|
+
)
|
193
212
|
if self.seed_matrix_2.shape[0] != rank_seed_m2:
|
194
|
-
d2T_min_estimate, _, _ = ldpc.mod2.estimate_code_distance(
|
213
|
+
d2T_min_estimate, _, _ = ldpc.mod2.estimate_code_distance(
|
214
|
+
self.seed_matrix_2.T, d2T_timeout_seconds, 0
|
215
|
+
)
|
195
216
|
else:
|
196
217
|
d2T_min_estimate = np.inf
|
197
|
-
|
218
|
+
|
198
219
|
self.x_code_distance = min(d1T_min_estimate, d2_min_estimate)
|
199
220
|
self.z_code_distance = min(d1_min_estimate, d2T_min_estimate)
|
200
221
|
self.code_distance = min(self.x_code_distance, self.z_code_distance)
|
201
222
|
|
202
|
-
|
203
223
|
return self.code_distance
|
204
224
|
|
205
|
-
|
206
|
-
|
207
|
-
|
225
|
+
def compute_logical_basis(
|
226
|
+
self,
|
227
|
+
) -> Tuple[scipy.sparse.spmatrix, scipy.sparse.spmatrix]:
|
208
228
|
"""
|
209
229
|
Compute the logical operator basis for the given HGP code.
|
210
230
|
|
@@ -225,40 +245,64 @@ class HypergraphProductCode(CSSCode):
|
|
225
245
|
row_comp_h2T = ldpc.mod2.row_complement_basis(self.seed_matrix_2.T)
|
226
246
|
|
227
247
|
temp = scipy.sparse.kron(ker_h1, row_comp_h2)
|
228
|
-
lz1 = scipy.sparse.hstack(
|
248
|
+
lz1 = scipy.sparse.hstack(
|
249
|
+
[
|
250
|
+
temp,
|
251
|
+
scipy.sparse.csr_matrix(
|
252
|
+
(temp.shape[0], self._m1 * self._m2), dtype=np.uint8
|
253
|
+
),
|
254
|
+
]
|
255
|
+
)
|
229
256
|
|
230
257
|
temp = scipy.sparse.kron(row_comp_h1T, ker_h2T)
|
231
|
-
lz2 = scipy.sparse.hstack(
|
258
|
+
lz2 = scipy.sparse.hstack(
|
259
|
+
[
|
260
|
+
scipy.sparse.csr_matrix(
|
261
|
+
(temp.shape[0], self._n1 * self._n2), dtype=np.uint8
|
262
|
+
),
|
263
|
+
temp,
|
264
|
+
]
|
265
|
+
)
|
232
266
|
|
233
267
|
self.z_logical_operator_basis = scipy.sparse.vstack([lz1, lz2], dtype=np.uint8)
|
234
268
|
|
235
|
-
|
236
269
|
temp = scipy.sparse.kron(row_comp_h1, ker_h2)
|
237
|
-
lx1 = scipy.sparse.hstack(
|
270
|
+
lx1 = scipy.sparse.hstack(
|
271
|
+
[
|
272
|
+
temp,
|
273
|
+
scipy.sparse.csr_matrix(
|
274
|
+
(temp.shape[0], self._m1 * self._m2), dtype=np.uint8
|
275
|
+
),
|
276
|
+
]
|
277
|
+
)
|
238
278
|
|
239
279
|
temp = scipy.sparse.kron(ker_h1T, row_comp_h2T)
|
240
|
-
lx2 = scipy.sparse.hstack(
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
280
|
+
lx2 = scipy.sparse.hstack(
|
281
|
+
[
|
282
|
+
scipy.sparse.csr_matrix(
|
283
|
+
(temp.shape[0], self._n1 * self._n2), dtype=np.uint8
|
284
|
+
),
|
285
|
+
temp,
|
286
|
+
]
|
287
|
+
)
|
288
|
+
|
289
|
+
self.x_logical_operator_basis = scipy.sparse.vstack([lx1, lx2], dtype=np.uint8)
|
290
|
+
|
291
|
+
# Follows the way it is done in CSSCode -> move it into __init__?
|
292
|
+
# ----------------------------------------------------------------
|
246
293
|
self.logical_qubit_count = self.x_logical_operator_basis.shape[0]
|
247
|
-
|
294
|
+
# ----------------------------------------------------------------
|
248
295
|
|
249
296
|
return (self.x_logical_operator_basis, self.z_logical_operator_basis)
|
250
297
|
|
251
|
-
|
252
298
|
def __str__(self):
|
253
299
|
"""
|
254
300
|
String representation of the HGP code. Includes the name and [[n, k, d]] properties of the code.
|
255
301
|
|
256
302
|
Returns
|
257
303
|
-------
|
258
|
-
str
|
259
|
-
String representation of the HGP code.
|
304
|
+
str
|
305
|
+
String representation of the HGP code.
|
260
306
|
"""
|
261
|
-
|
262
|
-
return f"{self.name} Hypergraphproduct Code: [[N={self.physical_qubit_count}, K={self.logical_qubit_count}, dx={self.x_code_distance}, dz={self.z_code_distance}]]"
|
263
|
-
|
264
307
|
|
308
|
+
return f"{self.name} Hypergraphproduct Code: [[N={self.physical_qubit_count}, K={self.logical_qubit_count}, dx={self.x_code_distance}, dz={self.z_code_distance}]]"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: qec
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.7
|
4
4
|
Summary: Python Tools for Quantum Error Correction
|
5
5
|
Author-email: Joschka Roffe <joschka@roffe.eu>, Tamas Noszko <T.K.Noszko@sms.ed.ac.uk>, Liam Veeder-Sweeney <L.D.Veeder-Sweeney@sms.ed.ac.uk>
|
6
6
|
License: MIT License
|
@@ -1,7 +1,7 @@
|
|
1
1
|
qec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
qec/code_constructions/__init__.py,sha256=
|
2
|
+
qec/code_constructions/__init__.py,sha256=AyEYcahGs_4C8nqSUhoYmZNBt1TzuzVPZjNN1FErRyQ,118
|
3
3
|
qec/code_constructions/css_code.py,sha256=nIaC24QhQwrmWQNhmX-X4TzlkmNAYoxN0feTdWjhswo,32376
|
4
|
-
qec/code_constructions/hgp_code.py,sha256=
|
4
|
+
qec/code_constructions/hgp_code.py,sha256=r5E_tEilRRJWDXrMbNAbplf-N5Y0XS7VUoWWTEjh9BY,11098
|
5
5
|
qec/code_constructions/stabilizer_code.py,sha256=I5u8JKZu88ioC4E2nBJ-00xCmnL8nU6kdAvwYOfmNRk,22138
|
6
6
|
qec/code_instances/__init__.py,sha256=z6jOPjekDIx0jgbRFThI95zUzLzjl9Dh89RBzxsT_BE,43
|
7
7
|
qec/code_instances/five_qubit_code.py,sha256=ZHyusTEnnnmUv4QxPLXQSKbEQv2QOoBqn2V9N4SgrQE,2177
|
@@ -11,8 +11,8 @@ qec/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
qec/utils/binary_pauli_utils.py,sha256=BSlngYDdRICu0aVu4u_m0bvLicohORyGxfk5eRER7TQ,13245
|
12
12
|
qec/utils/codetables_de_utils.py,sha256=S1wcVGJkkASQQ5s71QAsYBmpyE-3xTb6UsvgMfQtuiw,9469
|
13
13
|
qec/utils/sparse_binary_utils.py,sha256=Y9xfGKzOGFiVTyhb6iF6N7-5oMY6Ah9oLrnv8HhSBHA,1965
|
14
|
-
qec-0.2.
|
15
|
-
qec-0.2.
|
16
|
-
qec-0.2.
|
17
|
-
qec-0.2.
|
18
|
-
qec-0.2.
|
14
|
+
qec-0.2.7.dist-info/LICENSE,sha256=1b_xwNz1znYBfEaCL6pN2gNBAn8pQIjDRs_UhDp1EJI,1066
|
15
|
+
qec-0.2.7.dist-info/METADATA,sha256=KJk3mjCfJkluDMXt7-jh3lhPMpd_bvX3e3KPmKurRbo,4611
|
16
|
+
qec-0.2.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
17
|
+
qec-0.2.7.dist-info/top_level.txt,sha256=d8l_7pJ5u9uWdviNp0FUK-j8VPZqywkDek7qa4NDank,4
|
18
|
+
qec-0.2.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|