epgx 0.1.dev0__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.
- epgx/__init__.py +19 -0
- epgx/axes.py +285 -0
- epgx/common.py +63 -0
- epgx/compiler.py +347 -0
- epgx/diff.py +242 -0
- epgx/examples.py +146 -0
- epgx/functions.py +602 -0
- epgx/kernels/__init__.py +9 -0
- epgx/kernels/affine.py +187 -0
- epgx/kernels/evolution.py +40 -0
- epgx/kernels/operator.py +32 -0
- epgx/kernels/probe.py +107 -0
- epgx/kernels/shift.py +106 -0
- epgx/kernels/state.py +447 -0
- epgx/kernels/transition.py +48 -0
- epgx/library/__init__.py +3 -0
- epgx/library/sequences.py +210 -0
- epgx/lowering.py +95 -0
- epgx/merging.py +137 -0
- epgx/methods.py +329 -0
- epgx/ops/__init__.py +30 -0
- epgx/ops/dephasing.py +71 -0
- epgx/ops/evolution.py +135 -0
- epgx/ops/functions.py +158 -0
- epgx/ops/operator.py +224 -0
- epgx/ops/probe.py +116 -0
- epgx/ops/shift.py +118 -0
- epgx/ops/transition.py +58 -0
- epgx/plotting.py +226 -0
- epgx/progress.py +81 -0
- epgx/sample.py +142 -0
- epgx/sequences.py +850 -0
- epgx/stats.py +117 -0
- epgx-0.1.dev0.dist-info/METADATA +64 -0
- epgx-0.1.dev0.dist-info/RECORD +38 -0
- epgx-0.1.dev0.dist-info/WHEEL +5 -0
- epgx-0.1.dev0.dist-info/licenses/LICENSE +28 -0
- epgx-0.1.dev0.dist-info/top_level.txt +1 -0
epgx/examples.py
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""Utilities for the example scripts (examples/)
|
|
2
|
+
|
|
3
|
+
quick(): reduced sizes for fast runs (EPGX_QUICK=1 or `--quick`)
|
|
4
|
+
show(name): save the open figures if requested (EPGX_SAVEFIG=<folder> or
|
|
5
|
+
`--savefig [folder]`), then `plt.show()`
|
|
6
|
+
device_name(): readable name of the computing device (e.g. for timings)
|
|
7
|
+
|
|
8
|
+
Example headers (module docstring):
|
|
9
|
+
|
|
10
|
+
Title
|
|
11
|
+
|
|
12
|
+
Description (free text)
|
|
13
|
+
|
|
14
|
+
Shows: what the example demonstrates
|
|
15
|
+
Reference: Author et al. Journal Year;vol:pages. doi:... (optional)
|
|
16
|
+
Reproduces: figure(s) of the reference (optional)
|
|
17
|
+
Differences: w.r.t. the reference (optional)
|
|
18
|
+
|
|
19
|
+
Field values may continue on indented lines. The index of the examples
|
|
20
|
+
(examples/README.md) is generated from the headers (tools/make_examples_index.py).
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import ast
|
|
24
|
+
import os
|
|
25
|
+
import pathlib
|
|
26
|
+
import platform
|
|
27
|
+
import re
|
|
28
|
+
import subprocess
|
|
29
|
+
import sys
|
|
30
|
+
|
|
31
|
+
QUICK_VAR = "EPGX_QUICK"
|
|
32
|
+
SAVEFIG_VAR = "EPGX_SAVEFIG"
|
|
33
|
+
DEFAULT_FOLDER = "figures"
|
|
34
|
+
HEADER_FIELDS = ("Shows", "Reference", "Reproduces", "Differences")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def parse_header(docstring):
|
|
38
|
+
"""parse an example header (cf. module docstring)
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
dict with "title", "description" and the header fields found
|
|
42
|
+
"""
|
|
43
|
+
lines = (docstring or "").strip().splitlines()
|
|
44
|
+
if not lines:
|
|
45
|
+
raise ValueError("Empty example header")
|
|
46
|
+
header = {"title": lines[0].strip()}
|
|
47
|
+
pattern = re.compile(rf"^({'|'.join(HEADER_FIELDS)}):\s*(.*)$")
|
|
48
|
+
description, field = [], None
|
|
49
|
+
for line in lines[1:]:
|
|
50
|
+
match = pattern.match(line)
|
|
51
|
+
if match:
|
|
52
|
+
field = match.group(1)
|
|
53
|
+
header[field] = match.group(2).strip()
|
|
54
|
+
elif field and line.startswith((" ", "\t")) and line.strip():
|
|
55
|
+
header[field] += " " + line.strip()
|
|
56
|
+
else:
|
|
57
|
+
field = None
|
|
58
|
+
description.append(line)
|
|
59
|
+
header["description"] = "\n".join(description).strip()
|
|
60
|
+
return header
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def read_header(path):
|
|
64
|
+
"""parse the header of an example file"""
|
|
65
|
+
tree = ast.parse(pathlib.Path(path).read_text(encoding="utf-8"))
|
|
66
|
+
return parse_header(ast.get_docstring(tree))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def quick():
|
|
70
|
+
"""True in quick mode (EPGX_QUICK=1 or `--quick` on the command line)"""
|
|
71
|
+
value = os.environ.get(QUICK_VAR, "").strip().lower()
|
|
72
|
+
return value in ("1", "true", "yes") or "--quick" in sys.argv
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def savefig_folder():
|
|
76
|
+
"""folder where to save figures (EPGX_SAVEFIG or `--savefig [folder]`), or None"""
|
|
77
|
+
if "--savefig" in sys.argv:
|
|
78
|
+
index = sys.argv.index("--savefig")
|
|
79
|
+
value = sys.argv[index + 1] if index + 1 < len(sys.argv) else ""
|
|
80
|
+
return pathlib.Path(
|
|
81
|
+
value if value and not value.startswith("-") else DEFAULT_FOLDER
|
|
82
|
+
)
|
|
83
|
+
value = os.environ.get(SAVEFIG_VAR)
|
|
84
|
+
return pathlib.Path(value) if value else None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def show(name):
|
|
88
|
+
"""save the open figures if requested, then show them
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
name: name of the example (e.g. `__file__`), used for the file names:
|
|
92
|
+
<folder>/<example>_<figure label or number>.png
|
|
93
|
+
"""
|
|
94
|
+
from matplotlib import pyplot as plt
|
|
95
|
+
|
|
96
|
+
folder = savefig_folder()
|
|
97
|
+
if folder is not None:
|
|
98
|
+
folder.mkdir(parents=True, exist_ok=True)
|
|
99
|
+
stem = pathlib.Path(name).stem
|
|
100
|
+
for number in plt.get_fignums():
|
|
101
|
+
figure = plt.figure(number)
|
|
102
|
+
label = figure.get_label() or str(number)
|
|
103
|
+
figure.savefig(folder / f"{stem}_{label}.png", dpi=100)
|
|
104
|
+
plt.show()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def device_name():
|
|
108
|
+
"""readable name of the computing device and precision, e.g. for timings
|
|
109
|
+
|
|
110
|
+
GPU: model reported by JAX; CPU: processor name (registry on Windows,
|
|
111
|
+
/proc/cpuinfo on Linux, sysctl on macOS) and number of threads.
|
|
112
|
+
"""
|
|
113
|
+
import jax
|
|
114
|
+
|
|
115
|
+
device = jax.devices()[0]
|
|
116
|
+
precision = "x64" if jax.config.jax_enable_x64 else "float32"
|
|
117
|
+
if device.platform != "cpu":
|
|
118
|
+
return f"{device.device_kind} ({device.platform}), {precision}"
|
|
119
|
+
return f"{_cpu_name()} ({os.cpu_count()} threads), {precision}"
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _cpu_name():
|
|
123
|
+
"""processor name, or the generic platform description"""
|
|
124
|
+
try:
|
|
125
|
+
system = platform.system()
|
|
126
|
+
if system == "Windows":
|
|
127
|
+
import winreg
|
|
128
|
+
|
|
129
|
+
key = r"HARDWARE\DESCRIPTION\System\CentralProcessor\0"
|
|
130
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key) as handle:
|
|
131
|
+
name = winreg.QueryValueEx(handle, "ProcessorNameString")[0]
|
|
132
|
+
elif system == "Linux":
|
|
133
|
+
text = pathlib.Path("/proc/cpuinfo").read_text()
|
|
134
|
+
name = re.search(r"model name\s*:\s*(.*)", text).group(1)
|
|
135
|
+
elif system == "Darwin":
|
|
136
|
+
name = subprocess.run(
|
|
137
|
+
["sysctl", "-n", "machdep.cpu.brand_string"],
|
|
138
|
+
capture_output=True,
|
|
139
|
+
text=True,
|
|
140
|
+
check=True,
|
|
141
|
+
).stdout
|
|
142
|
+
else:
|
|
143
|
+
name = ""
|
|
144
|
+
except Exception:
|
|
145
|
+
name = ""
|
|
146
|
+
return " ".join(name.split()) or platform.processor() or "CPU"
|