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.
- lichen_q-0.1.0/CHANGELOG.md +6 -0
- lichen_q-0.1.0/LICENSE +21 -0
- lichen_q-0.1.0/PKG-INFO +83 -0
- lichen_q-0.1.0/README.md +64 -0
- lichen_q-0.1.0/build.py +38 -0
- lichen_q-0.1.0/build_backend.py +205 -0
- lichen_q-0.1.0/examples/lichen_validation.ipynb +984 -0
- lichen_q-0.1.0/pyproject.toml +34 -0
- lichen_q-0.1.0/src/lichen/__init__.py +97 -0
- lichen_q-0.1.0/src/lichen/block_fault_export.py +183 -0
- lichen_q-0.1.0/src/lichen/block_partition.py +114 -0
- lichen_q-0.1.0/src/lichen/block_pauli_projector.py +325 -0
- lichen_q-0.1.0/src/lichen/block_probability_search.py +209 -0
- lichen_q-0.1.0/src/lichen/block_propagator.py +114 -0
- lichen_q-0.1.0/src/lichen/block_sampler.py +187 -0
- lichen_q-0.1.0/src/lichen/block_structure_analyzer.py +196 -0
- lichen_q-0.1.0/src/lichen/block_template_cache.py +67 -0
- lichen_q-0.1.0/src/lichen/circuit.py +32 -0
- lichen_q-0.1.0/src/lichen/frame_tracker.py +121 -0
- lichen_q-0.1.0/src/lichen/hidden_memory.py +95 -0
- lichen_q-0.1.0/src/lichen/model.py +49 -0
- lichen_q-0.1.0/src/lichen/pauli.py +354 -0
- lichen_q-0.1.0/src/lichen/segment_generators.py +100 -0
- lichen_q-0.1.0/tests/__init__.py +1 -0
- lichen_q-0.1.0/tests/test_direction.md +5 -0
- lichen_q-0.1.0/tests/test_smoke.py +52 -0
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.
|
lichen_q-0.1.0/PKG-INFO
ADDED
|
@@ -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`.
|
lichen_q-0.1.0/README.md
ADDED
|
@@ -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`.
|
lichen_q-0.1.0/build.py
ADDED
|
@@ -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)
|