qec 0.3.2__py3-none-any.whl → 0.3.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.
- qec/__init__.py +2 -0
- qec/code_constructions/__init__.py +17 -0
- qec/code_constructions/css_code.py +959 -0
- qec/code_constructions/hgp_code.py +344 -0
- qec/code_constructions/periodic_surface_xzzx.py +100 -0
- qec/code_constructions/rotated_xzzx.py +122 -0
- qec/code_constructions/stabilizer_code.py +654 -0
- qec/code_constructions/surface_code.py +66 -0
- qec/code_constructions/toric_code.py +56 -0
- qec/code_instances/__init__.py +5 -0
- qec/code_instances/five_qubit_code.py +67 -0
- qec/codetables_de/__init__.py +3 -0
- qec/codetables_de/codetables_de.py +97 -0
- qec/utils/__init__.py +6 -0
- qec/utils/binary_pauli_utils.py +404 -0
- qec/utils/codetables_de_utils.py +272 -0
- qec/utils/load_code_util.py +142 -0
- qec/utils/sparse_binary_utils.py +80 -0
- {qec-0.3.2.dist-info → qec-0.3.3.dist-info}/METADATA +1 -1
- qec-0.3.3.dist-info/RECORD +27 -0
- qec-0.3.2.dist-info/RECORD +0 -10
- {qec-0.3.2.dist-info → qec-0.3.3.dist-info}/WHEEL +0 -0
- {qec-0.3.2.dist-info → qec-0.3.3.dist-info}/licenses/LICENSE +0 -0
- {qec-0.3.2.dist-info → qec-0.3.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
import json
|
2
|
+
from typing import Union
|
3
|
+
import inspect
|
4
|
+
from pathlib import Path
|
5
|
+
from qec.utils.sparse_binary_utils import dict_to_binary_csr_matrix
|
6
|
+
import qec.code_constructions
|
7
|
+
|
8
|
+
|
9
|
+
def load_code(filepath: Union[str, Path]):
|
10
|
+
"""
|
11
|
+
Loads a quantum error correction code from a JSON file.
|
12
|
+
|
13
|
+
Parameters
|
14
|
+
----------
|
15
|
+
filepath : Union[str, Path]
|
16
|
+
Path to JSON file containing code data
|
17
|
+
|
18
|
+
Returns
|
19
|
+
-------
|
20
|
+
object
|
21
|
+
An instance of the quantum error correction code class.
|
22
|
+
|
23
|
+
Raises
|
24
|
+
------
|
25
|
+
FileNotFoundError
|
26
|
+
If the specified file does not exist.
|
27
|
+
ValueError
|
28
|
+
If the input file is missing the 'class_name' key.
|
29
|
+
AttributeError
|
30
|
+
If the specified class does not exist in qec.code_constructions.
|
31
|
+
"""
|
32
|
+
|
33
|
+
file_path = Path(filepath)
|
34
|
+
if not file_path.exists():
|
35
|
+
raise FileNotFoundError(
|
36
|
+
f"Error: No file found at the specified path: {file_path}"
|
37
|
+
)
|
38
|
+
|
39
|
+
with open(file_path, "r") as file:
|
40
|
+
code_data = json.load(file)
|
41
|
+
|
42
|
+
if "class_name" not in code_data:
|
43
|
+
raise ValueError(
|
44
|
+
"Error: The input JSON file must contain a 'class_name' key specifying the class to instantiate."
|
45
|
+
)
|
46
|
+
|
47
|
+
try:
|
48
|
+
class_reference = eval(
|
49
|
+
f"qec.code_constructions.{code_data['class_name']}", {"qec": qec}
|
50
|
+
)
|
51
|
+
except AttributeError:
|
52
|
+
raise AttributeError(
|
53
|
+
f"Error: The specified class '{code_data['class_name']}' does not exist in qec.code_constructions."
|
54
|
+
)
|
55
|
+
|
56
|
+
constructor_parameters = inspect.signature(
|
57
|
+
class_reference.__init__
|
58
|
+
).parameters.keys()
|
59
|
+
filtered_input_parameters = {}
|
60
|
+
|
61
|
+
for key, value in code_data.items():
|
62
|
+
if key in constructor_parameters:
|
63
|
+
if isinstance(value, dict) and all(
|
64
|
+
k in value for k in ["indices", "indptr", "shape"]
|
65
|
+
):
|
66
|
+
filtered_input_parameters[key] = dict_to_binary_csr_matrix(
|
67
|
+
value
|
68
|
+
) # Convert sparse matrix
|
69
|
+
else:
|
70
|
+
filtered_input_parameters[key] = value # Keep as-is if not a matrix
|
71
|
+
|
72
|
+
# Instantiate the class
|
73
|
+
code_instance = class_reference(**filtered_input_parameters)
|
74
|
+
|
75
|
+
# Add extra attributes from JSON that are valid class attributes but not constructor parameters
|
76
|
+
class_attributes = dir(code_instance)
|
77
|
+
for key, value in code_data.items():
|
78
|
+
if key not in constructor_parameters and key in class_attributes:
|
79
|
+
if isinstance(value, dict) and all(
|
80
|
+
k in value for k in ["indices", "indptr", "shape"]
|
81
|
+
):
|
82
|
+
value = dict_to_binary_csr_matrix(value) # Convert sparse matrix
|
83
|
+
else:
|
84
|
+
pass
|
85
|
+
|
86
|
+
if (not isinstance(value, str) or value != "?") and value is not None:
|
87
|
+
setattr(code_instance, key, value)
|
88
|
+
|
89
|
+
return code_instance
|
90
|
+
|
91
|
+
|
92
|
+
def load_code_from_id(code_id: int):
|
93
|
+
"""
|
94
|
+
Load a quantum error correction code from a JSON file based on its ID from the package data.
|
95
|
+
|
96
|
+
The code files are packaged as data in the directory:
|
97
|
+
qec/code_instances/saved_codes
|
98
|
+
and are named as f"{code_id}.json".
|
99
|
+
|
100
|
+
Parameters
|
101
|
+
----------
|
102
|
+
code_id : int
|
103
|
+
The identifier of the saved code.
|
104
|
+
|
105
|
+
Returns
|
106
|
+
-------
|
107
|
+
object
|
108
|
+
An instance of the quantum error correction code class loaded from the JSON data.
|
109
|
+
|
110
|
+
Raises
|
111
|
+
------
|
112
|
+
FileNotFoundError
|
113
|
+
If the JSON file corresponding to code_id is not found.
|
114
|
+
"""
|
115
|
+
from importlib.resources import files, as_file
|
116
|
+
from importlib import import_module
|
117
|
+
from pathlib import Path
|
118
|
+
|
119
|
+
filename = f"{code_id}.json"
|
120
|
+
package = "qec.code_instances.saved_codes"
|
121
|
+
try:
|
122
|
+
pkg = import_module(package)
|
123
|
+
# If the package spec lacks an origin, fall back.
|
124
|
+
if pkg.__spec__ is None or pkg.__spec__.origin is None:
|
125
|
+
raise ImportError("Package spec origin not found; fallback to filesystem.")
|
126
|
+
resource = files(pkg).joinpath(filename)
|
127
|
+
except Exception:
|
128
|
+
# Fallback: construct the path relative to this file.
|
129
|
+
resource = (
|
130
|
+
Path(__file__).parent.parent / "code_instances" / "saved_codes" / filename
|
131
|
+
)
|
132
|
+
|
133
|
+
if not resource.is_file():
|
134
|
+
raise FileNotFoundError(
|
135
|
+
f"File '{filename}' does not exist in package data at '{package}' "
|
136
|
+
f"or via fallback path '{resource}'."
|
137
|
+
)
|
138
|
+
|
139
|
+
with as_file(resource) as resource_path:
|
140
|
+
if not resource_path.exists():
|
141
|
+
raise FileNotFoundError(f"File '{resource_path}' does not exist on disk.")
|
142
|
+
return load_code(resource_path)
|
@@ -0,0 +1,80 @@
|
|
1
|
+
import numpy.typing
|
2
|
+
import numpy as np
|
3
|
+
import scipy.sparse
|
4
|
+
|
5
|
+
|
6
|
+
def convert_to_binary_scipy_sparse(
|
7
|
+
matrix: numpy.typing.ArrayLike,
|
8
|
+
) -> scipy.sparse.csr_matrix:
|
9
|
+
"""
|
10
|
+
Convert and validate a matrix as a sparse binary matrix in CSR format.
|
11
|
+
|
12
|
+
This function checks whether all elements of the input matrix are binary (0 or 1).
|
13
|
+
If the input is not already a sparse matrix, it converts it to a CSR (Compressed Sparse Row) matrix.
|
14
|
+
|
15
|
+
Parameters
|
16
|
+
----------
|
17
|
+
matrix : array-like
|
18
|
+
Input matrix of shape (M, N). Can be a dense array-like or any SciPy sparse matrix format.
|
19
|
+
|
20
|
+
Returns
|
21
|
+
-------
|
22
|
+
scipy.sparse.csr_matrix
|
23
|
+
Binary sparse matrix in CSR format, of shape (M, N).
|
24
|
+
|
25
|
+
Raises
|
26
|
+
------
|
27
|
+
ValueError
|
28
|
+
If the input matrix has elements outside {0, 1}.
|
29
|
+
TypeError
|
30
|
+
If the input is not array-like.
|
31
|
+
|
32
|
+
Examples
|
33
|
+
--------
|
34
|
+
>>> import numpy as np
|
35
|
+
>>> from scipy.sparse import csr_matrix
|
36
|
+
>>> from qec.utils.sparse_binary_utils import convert_to_binary_scipy_sparse
|
37
|
+
>>> mat = np.array([[0, 1], [1, 0]])
|
38
|
+
>>> convert_to_binary_scipy_sparse(mat).toarray()
|
39
|
+
array([[0, 1],
|
40
|
+
[1, 0]])
|
41
|
+
|
42
|
+
>>> mat = csr_matrix([[0, 1], [1, 0]])
|
43
|
+
>>> convert_to_binary_scipy_sparse(mat).toarray()
|
44
|
+
array([[0, 1],
|
45
|
+
[1, 0]])
|
46
|
+
|
47
|
+
>>> mat = np.array([[0, 2], [1, 0]])
|
48
|
+
>>> convert_to_binary_scipy_sparse(mat)
|
49
|
+
Traceback (most recent call last):
|
50
|
+
...
|
51
|
+
ValueError: All elements of the input matrix must be binary.
|
52
|
+
"""
|
53
|
+
if not isinstance(matrix, (np.ndarray, list, scipy.sparse.spmatrix)):
|
54
|
+
raise TypeError("Input must be array-like.")
|
55
|
+
|
56
|
+
if not isinstance(matrix, scipy.sparse.csr_matrix):
|
57
|
+
matrix = scipy.sparse.csr_matrix(matrix, dtype=np.uint8)
|
58
|
+
|
59
|
+
if not matrix.dtype == np.uint8:
|
60
|
+
matrix = matrix.astype(np.uint8)
|
61
|
+
|
62
|
+
if not np.all(np.isin(matrix.data, [0, 1])):
|
63
|
+
raise ValueError("All elements of the input matrix must be binary.")
|
64
|
+
|
65
|
+
return matrix
|
66
|
+
|
67
|
+
|
68
|
+
def binary_csr_matrix_to_dict(matrix: scipy.sparse.spmatrix):
|
69
|
+
return {
|
70
|
+
"indices": matrix.indices.tolist(),
|
71
|
+
"indptr": matrix.indptr.tolist(),
|
72
|
+
"shape": matrix.shape,
|
73
|
+
}
|
74
|
+
|
75
|
+
|
76
|
+
def dict_to_binary_csr_matrix(csr_dict: dict):
|
77
|
+
return scipy.sparse.csr_matrix(
|
78
|
+
([1] * len(csr_dict["indices"]), csr_dict["indices"], csr_dict["indptr"]),
|
79
|
+
shape=csr_dict["shape"],
|
80
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qec
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.3
|
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
|
@@ -0,0 +1,27 @@
|
|
1
|
+
qec/__init__.py,sha256=daEdpEyAJIa8b2VkCqSKcw8PaExcB6Qro80XNes_sHA,2
|
2
|
+
qec/code_constructions/__init__.py,sha256=Jg7aUTYaTuFnLGcpqPmc7iSQeM6Kwi_p9eUQBLNvePQ,600
|
3
|
+
qec/code_constructions/css_code.py,sha256=e4X6QMnZ_xHdZENsaqrfFe-tl0XgEHvm7Fw2yBM3low,38614
|
4
|
+
qec/code_constructions/hgp_code.py,sha256=FqghbZ6mQIBlQIJwhaPU_Zb1LjnmHBS_PGtQVNPl_mA,12310
|
5
|
+
qec/code_constructions/periodic_surface_xzzx.py,sha256=iF95s-py85ivELlCiL5oEWe87OUVaKI3r4mJjaKy_-o,3551
|
6
|
+
qec/code_constructions/rotated_xzzx.py,sha256=wSWH9H1AaNn_Yyhnr_NSvZdlo_sV9HW5JHFcBrjAnQY,4400
|
7
|
+
qec/code_constructions/stabilizer_code.py,sha256=InPbSrqzMxueMQaFbUt-ytDHCWIzgIddnlAwYegpRFg,24258
|
8
|
+
qec/code_constructions/surface_code.py,sha256=s49uyMZPRjOwBqpfLeB5Dl38O8w7BP8Y1tBemFhyDr0,2561
|
9
|
+
qec/code_constructions/toric_code.py,sha256=Q8f3jU80gwsjqRVtp2tBuO6yRltQI5KeD49xQm8vuAw,1952
|
10
|
+
qec/code_instances/__init__.py,sha256=5T_Qw26-cQc5BC6RM23_oDAYRdB3UPU5MeCGPxsoSRs,79
|
11
|
+
qec/code_instances/five_qubit_code.py,sha256=ZHyusTEnnnmUv4QxPLXQSKbEQv2QOoBqn2V9N4SgrQE,2177
|
12
|
+
qec/code_instances/saved_codes/1.json,sha256=PEErxvbeDupmZ4woHxC6EGAaRxfZ34fb4cOpBkfHvrs,850
|
13
|
+
qec/code_instances/saved_codes/2.json,sha256=Dwp5XT65s9Wu51WFJjzNzkP5WYLcVPkVoIpfLb92PMM,2920
|
14
|
+
qec/code_instances/saved_codes/3.json,sha256=3FeCj54tl708TeEsaChb_qqr92kw4_9S1wf4VASN-5U,4687
|
15
|
+
qec/code_instances/saved_codes/4.json,sha256=H4ktJy02VGPxqSAZkjam1HMlPex2KjmbcG9CBdP4NhI,5452
|
16
|
+
qec/codetables_de/__init__.py,sha256=_BQq4cIgZHbGPsA6qsJnMJ-B5eHqiYvUKbSubmJP8jA,68
|
17
|
+
qec/codetables_de/codetables_de.py,sha256=4tkoHtr4VXHm0qY9r397EUhxFXR1Mp6DqqtfblGyzbw,3725
|
18
|
+
qec/utils/__init__.py,sha256=lSkUeUQhk2KU8EgH63jSehwAMHQAJ3XBDmmRIKXRuN8,123
|
19
|
+
qec/utils/binary_pauli_utils.py,sha256=Vtqw-wWlOmrj2CDDhjjNmgUZHe5TJ2bU5-c_pV_Q4ks,13280
|
20
|
+
qec/utils/codetables_de_utils.py,sha256=Qbk2y-4sMufSrgQyuC6pDBOteeC3By_BiykVz4mIL7o,9467
|
21
|
+
qec/utils/load_code_util.py,sha256=w4icqtSKvEiA9JuFAc1AdkCt31dDC-SYK4-d4G4YfAY,4642
|
22
|
+
qec/utils/sparse_binary_utils.py,sha256=02qxK1iC_8jFIeuH1vjSd_3OwuKT5wWsVBshklc2IIA,2397
|
23
|
+
qec-0.3.3.dist-info/licenses/LICENSE,sha256=1b_xwNz1znYBfEaCL6pN2gNBAn8pQIjDRs_UhDp1EJI,1066
|
24
|
+
qec-0.3.3.dist-info/METADATA,sha256=r6ZBxOp3OYOhSOvjah90naZqy93BQcnHUpqIgfJpLoU,6392
|
25
|
+
qec-0.3.3.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
26
|
+
qec-0.3.3.dist-info/top_level.txt,sha256=d8l_7pJ5u9uWdviNp0FUK-j8VPZqywkDek7qa4NDank,4
|
27
|
+
qec-0.3.3.dist-info/RECORD,,
|
qec-0.3.2.dist-info/RECORD
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
qec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
qec/code_instances/saved_codes/1.json,sha256=PEErxvbeDupmZ4woHxC6EGAaRxfZ34fb4cOpBkfHvrs,850
|
3
|
-
qec/code_instances/saved_codes/2.json,sha256=Dwp5XT65s9Wu51WFJjzNzkP5WYLcVPkVoIpfLb92PMM,2920
|
4
|
-
qec/code_instances/saved_codes/3.json,sha256=3FeCj54tl708TeEsaChb_qqr92kw4_9S1wf4VASN-5U,4687
|
5
|
-
qec/code_instances/saved_codes/4.json,sha256=H4ktJy02VGPxqSAZkjam1HMlPex2KjmbcG9CBdP4NhI,5452
|
6
|
-
qec-0.3.2.dist-info/licenses/LICENSE,sha256=1b_xwNz1znYBfEaCL6pN2gNBAn8pQIjDRs_UhDp1EJI,1066
|
7
|
-
qec-0.3.2.dist-info/METADATA,sha256=dXPczwlUgmEfniM9ImiaDIRhIKgGtUH65ycJcMrg_Ek,6392
|
8
|
-
qec-0.3.2.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
9
|
-
qec-0.3.2.dist-info/top_level.txt,sha256=d8l_7pJ5u9uWdviNp0FUK-j8VPZqywkDek7qa4NDank,4
|
10
|
-
qec-0.3.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|