lichen-q 0.1.0__tar.gz

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,6 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Initial standalone release of `lichen-q` with import package `lichen`.
6
+ - Added blockwise hidden-memory simulation, smoke tests, and validation notebook.
lichen_q-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Wenzheng Dong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,83 @@
1
+ Metadata-Version: 2.1
2
+ Name: lichen-q
3
+ Version: 0.1.0
4
+ Summary: Blockwise hidden-memory simulator for correlated environment noise
5
+ Description-Content-Type: text/markdown
6
+ Requires-Python: >=3.10
7
+ Requires-Dist: numpy>=1.20
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Scientific/Engineering :: Physics
19
+
20
+ # lichen-q
21
+
22
+ `lichen-q` is the standalone PyPI distribution for the `lichen` import
23
+ package. It provides blockwise hidden-memory correlated environment-noise
24
+ simulation.
25
+
26
+ It provides the blockwise hidden-memory correlated environment-noise simulator
27
+ used for DD-aware noisy-circuit sampling.
28
+
29
+ ## Install
30
+
31
+ From this repo root:
32
+
33
+ ```bash
34
+ python -m pip install -e .[dev]
35
+ ```
36
+
37
+ ## Test
38
+
39
+ From this repo root:
40
+
41
+ ```bash
42
+ python -m pytest -q
43
+ ```
44
+
45
+ or:
46
+
47
+ ```bash
48
+ python -m unittest discover -s tests -t . -q
49
+ ```
50
+
51
+ ## Build
52
+
53
+ From this repo root:
54
+
55
+ ```bash
56
+ python -m build
57
+ ```
58
+
59
+ ## Wheel Check
60
+
61
+ From this repo root:
62
+
63
+ ```bash
64
+ python -m pip install dist/*.whl
65
+ ```
66
+
67
+ For users installing from PyPI:
68
+
69
+ ```bash
70
+ python -m pip install lichen-q
71
+ ```
72
+
73
+ ## Contents
74
+
75
+ - block partitioning
76
+ - Clifford-frame tracking
77
+ - exact short-block Pauli-amplitude convolution
78
+ - sparse block-fault export
79
+ - blockwise hidden-memory sampling
80
+
81
+ ## Validation
82
+
83
+ The package ships with a validation notebook under `examples/lichen_validation.ipynb`.
@@ -0,0 +1,64 @@
1
+ # lichen-q
2
+
3
+ `lichen-q` is the standalone PyPI distribution for the `lichen` import
4
+ package. It provides blockwise hidden-memory correlated environment-noise
5
+ simulation.
6
+
7
+ It provides the blockwise hidden-memory correlated environment-noise simulator
8
+ used for DD-aware noisy-circuit sampling.
9
+
10
+ ## Install
11
+
12
+ From this repo root:
13
+
14
+ ```bash
15
+ python -m pip install -e .[dev]
16
+ ```
17
+
18
+ ## Test
19
+
20
+ From this repo root:
21
+
22
+ ```bash
23
+ python -m pytest -q
24
+ ```
25
+
26
+ or:
27
+
28
+ ```bash
29
+ python -m unittest discover -s tests -t . -q
30
+ ```
31
+
32
+ ## Build
33
+
34
+ From this repo root:
35
+
36
+ ```bash
37
+ python -m build
38
+ ```
39
+
40
+ ## Wheel Check
41
+
42
+ From this repo root:
43
+
44
+ ```bash
45
+ python -m pip install dist/*.whl
46
+ ```
47
+
48
+ For users installing from PyPI:
49
+
50
+ ```bash
51
+ python -m pip install lichen-q
52
+ ```
53
+
54
+ ## Contents
55
+
56
+ - block partitioning
57
+ - Clifford-frame tracking
58
+ - exact short-block Pauli-amplitude convolution
59
+ - sparse block-fault export
60
+ - blockwise hidden-memory sampling
61
+
62
+ ## Validation
63
+
64
+ The package ships with a validation notebook under `examples/lichen_validation.ipynb`.
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from pathlib import Path
5
+
6
+ import build_backend
7
+
8
+
9
+ def _build_dist(outdir: Path, *, wheel: bool, sdist: bool) -> list[str]:
10
+ outdir.mkdir(parents=True, exist_ok=True)
11
+ built: list[str] = []
12
+
13
+ if wheel:
14
+ built.append(build_backend.build_wheel(str(outdir)))
15
+ if sdist:
16
+ built.append(build_backend.build_sdist(str(outdir)))
17
+
18
+ return built
19
+
20
+
21
+ def main(argv: list[str] | None = None) -> int:
22
+ parser = argparse.ArgumentParser(prog="build", description="Build lichen distributions.")
23
+ parser.add_argument("--wheel", action="store_true", help="Build a wheel only.")
24
+ parser.add_argument("--sdist", action="store_true", help="Build an sdist only.")
25
+ parser.add_argument("--outdir", default="dist", help="Output directory for artifacts.")
26
+ args = parser.parse_args(argv)
27
+
28
+ build_wheel = args.wheel or not args.sdist
29
+ build_sdist = args.sdist or not args.wheel
30
+
31
+ built = _build_dist(Path(args.outdir), wheel=build_wheel, sdist=build_sdist)
32
+ for artifact in built:
33
+ print(artifact)
34
+ return 0
35
+
36
+
37
+ if __name__ == "__main__":
38
+ raise SystemExit(main())
@@ -0,0 +1,205 @@
1
+ from __future__ import annotations
2
+
3
+ import base64
4
+ import csv
5
+ import hashlib
6
+ import io
7
+ from pathlib import Path
8
+ import tarfile
9
+ import zipfile
10
+
11
+
12
+ DIST_NAME = "lichen-q"
13
+ NORMALIZED_DIST_NAME = "lichen_q"
14
+ VERSION = "0.1.0"
15
+ SUMMARY = "Blockwise hidden-memory simulator for correlated environment noise"
16
+ REQUIRES_PYTHON = ">=3.10"
17
+ REQUIRES_DIST = "numpy>=1.20"
18
+ TOP_LEVEL_PACKAGE = "lichen"
19
+
20
+ ROOT = Path(__file__).resolve().parent
21
+ SRC = ROOT / "src"
22
+
23
+
24
+ def _dist_info_dir() -> str:
25
+ return f"{NORMALIZED_DIST_NAME}-{VERSION}.dist-info"
26
+
27
+
28
+ def _wheel_name() -> str:
29
+ return f"{NORMALIZED_DIST_NAME}-{VERSION}-py3-none-any.whl"
30
+
31
+
32
+ def _sdist_name() -> str:
33
+ return f"{NORMALIZED_DIST_NAME}-{VERSION}.tar.gz"
34
+
35
+
36
+ def _metadata_text() -> str:
37
+ return "\n".join(
38
+ [
39
+ "Metadata-Version: 2.1",
40
+ f"Name: {DIST_NAME}",
41
+ f"Version: {VERSION}",
42
+ f"Summary: {SUMMARY}",
43
+ "Description-Content-Type: text/markdown",
44
+ f"Requires-Python: {REQUIRES_PYTHON}",
45
+ f"Requires-Dist: {REQUIRES_DIST}",
46
+ "License-File: LICENSE",
47
+ "Classifier: Development Status :: 3 - Alpha",
48
+ "Classifier: License :: OSI Approved :: MIT License",
49
+ "Classifier: Operating System :: OS Independent",
50
+ "Classifier: Programming Language :: Python :: 3",
51
+ "Classifier: Programming Language :: Python :: 3.10",
52
+ "Classifier: Programming Language :: Python :: 3.11",
53
+ "Classifier: Programming Language :: Python :: 3.12",
54
+ "Classifier: Programming Language :: Python :: 3.13",
55
+ "Classifier: Programming Language :: Python :: 3.14",
56
+ "Classifier: Topic :: Scientific/Engineering :: Physics",
57
+ "",
58
+ _readme_text(),
59
+ ]
60
+ )
61
+
62
+
63
+ def _readme_text() -> str:
64
+ return (ROOT / "README.md").read_text(encoding="utf-8").strip()
65
+
66
+
67
+ def _wheel_text() -> str:
68
+ return "\n".join(
69
+ [
70
+ "Wheel-Version: 1.0",
71
+ "Generator: build_backend",
72
+ "Root-Is-Purelib: true",
73
+ "Tag: py3-none-any",
74
+ "",
75
+ ]
76
+ )
77
+
78
+
79
+ def _record_row(path: str, data: bytes) -> list[str]:
80
+ digest = base64.urlsafe_b64encode(hashlib.sha256(data).digest()).rstrip(b"=").decode("ascii")
81
+ return [path, f"sha256={digest}", str(len(data))]
82
+
83
+
84
+ def _read_bytes(path: Path) -> bytes:
85
+ return path.read_bytes()
86
+
87
+
88
+ def _iter_package_files() -> list[Path]:
89
+ return sorted((SRC / TOP_LEVEL_PACKAGE).rglob("*.py"))
90
+
91
+
92
+ def _iter_sdist_files() -> list[Path]:
93
+ files = [
94
+ ROOT / "README.md",
95
+ ROOT / "LICENSE",
96
+ ROOT / "CHANGELOG.md",
97
+ ROOT / "pyproject.toml",
98
+ ROOT / "build_backend.py",
99
+ ROOT / "build.py",
100
+ ]
101
+ files.extend(sorted((ROOT / "examples").rglob("*.ipynb")))
102
+ files.extend(sorted((ROOT / "tests").rglob("*.py")))
103
+ files.extend(sorted((ROOT / "tests").rglob("*.md")))
104
+ files.extend(_iter_package_files())
105
+ return [path for path in files if path.exists()]
106
+
107
+
108
+ def _write_wheel_file(wheel_directory: str, *, editable: bool) -> str:
109
+ wheel_path = Path(wheel_directory) / _wheel_name()
110
+ dist_info = _dist_info_dir()
111
+ record_rows: list[list[str]] = []
112
+
113
+ with zipfile.ZipFile(wheel_path, "w", compression=zipfile.ZIP_DEFLATED) as zf:
114
+ if editable:
115
+ pth_name = f"{NORMALIZED_DIST_NAME}.pth"
116
+ pth_data = f"{SRC.as_posix()}\n".encode("utf-8")
117
+ zf.writestr(pth_name, pth_data)
118
+ record_rows.append(_record_row(pth_name, pth_data))
119
+ else:
120
+ for file_path in _iter_package_files():
121
+ archive_name = file_path.relative_to(SRC).as_posix()
122
+ data = _read_bytes(file_path)
123
+ zf.writestr(archive_name, data)
124
+ record_rows.append(_record_row(archive_name, data))
125
+
126
+ metadata_name = f"{dist_info}/METADATA"
127
+ metadata_data = _metadata_text().encode("utf-8")
128
+ zf.writestr(metadata_name, metadata_data)
129
+ record_rows.append(_record_row(metadata_name, metadata_data))
130
+
131
+ wheel_name = f"{dist_info}/WHEEL"
132
+ wheel_data = _wheel_text().encode("utf-8")
133
+ zf.writestr(wheel_name, wheel_data)
134
+ record_rows.append(_record_row(wheel_name, wheel_data))
135
+
136
+ top_level_name = f"{dist_info}/top_level.txt"
137
+ top_level_data = f"{TOP_LEVEL_PACKAGE}\n".encode("utf-8")
138
+ zf.writestr(top_level_name, top_level_data)
139
+ record_rows.append(_record_row(top_level_name, top_level_data))
140
+
141
+ record_name = f"{dist_info}/RECORD"
142
+ record_buffer = io.StringIO()
143
+ writer = csv.writer(record_buffer, lineterminator="\n")
144
+ for row in record_rows:
145
+ writer.writerow(row)
146
+ writer.writerow([record_name, "", ""])
147
+ record_data = record_buffer.getvalue().encode("utf-8")
148
+ zf.writestr(record_name, record_data)
149
+
150
+ return wheel_path.name
151
+
152
+
153
+ def _write_sdist_file(sdist_directory: str) -> str:
154
+ sdist_path = Path(sdist_directory) / _sdist_name()
155
+ base_dir = f"{NORMALIZED_DIST_NAME}-{VERSION}"
156
+ with tarfile.open(sdist_path, "w:gz") as tf:
157
+ pkg_info_data = _metadata_text().encode("utf-8")
158
+ pkg_info = tarfile.TarInfo(name=f"{base_dir}/PKG-INFO")
159
+ pkg_info.size = len(pkg_info_data)
160
+ tf.addfile(pkg_info, io.BytesIO(pkg_info_data))
161
+ for file_path in _iter_sdist_files():
162
+ arcname = f"{base_dir}/{file_path.relative_to(ROOT).as_posix()}"
163
+ tf.add(file_path, arcname=arcname)
164
+ return sdist_path.name
165
+
166
+
167
+ def _prepare_metadata_directory(metadata_directory: str) -> str:
168
+ dist_info = Path(metadata_directory) / _dist_info_dir()
169
+ dist_info.mkdir(parents=True, exist_ok=True)
170
+ (dist_info / "METADATA").write_text(_metadata_text(), encoding="utf-8")
171
+ (dist_info / "WHEEL").write_text(_wheel_text(), encoding="utf-8")
172
+ (dist_info / "top_level.txt").write_text(f"{TOP_LEVEL_PACKAGE}\n", encoding="utf-8")
173
+ return dist_info.name
174
+
175
+
176
+ def get_requires_for_build_wheel(config_settings=None):
177
+ return []
178
+
179
+
180
+ def get_requires_for_build_editable(config_settings=None):
181
+ return []
182
+
183
+
184
+ def get_requires_for_build_sdist(config_settings=None):
185
+ return []
186
+
187
+
188
+ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
189
+ return _prepare_metadata_directory(metadata_directory)
190
+
191
+
192
+ def prepare_metadata_for_build_editable(metadata_directory, config_settings=None):
193
+ return _prepare_metadata_directory(metadata_directory)
194
+
195
+
196
+ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
197
+ return _write_wheel_file(wheel_directory, editable=False)
198
+
199
+
200
+ def build_editable(wheel_directory, config_settings=None, metadata_directory=None):
201
+ return _write_wheel_file(wheel_directory, editable=True)
202
+
203
+
204
+ def build_sdist(sdist_directory, config_settings=None):
205
+ return _write_sdist_file(sdist_directory)