openquantumsim 0.1.0a1__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.
- openquantumsim-0.1.0a1/CHANGELOG.md +29 -0
- openquantumsim-0.1.0a1/CITATION.cff +17 -0
- openquantumsim-0.1.0a1/CONTRIBUTING.md +39 -0
- openquantumsim-0.1.0a1/LICENSE +21 -0
- openquantumsim-0.1.0a1/MANIFEST.in +7 -0
- openquantumsim-0.1.0a1/PKG-INFO +427 -0
- openquantumsim-0.1.0a1/README.md +384 -0
- openquantumsim-0.1.0a1/openquantumsim/__init__.py +202 -0
- openquantumsim-0.1.0a1/openquantumsim/_julia_bridge.py +80 -0
- openquantumsim-0.1.0a1/openquantumsim/_version.py +3 -0
- openquantumsim-0.1.0a1/openquantumsim/correlations.py +144 -0
- openquantumsim-0.1.0a1/openquantumsim/hilbert.py +114 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/Manifest.toml +1644 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/Project.toml +26 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/Correlations.jl +205 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/HilbertSpace.jl +51 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/Lindblad.jl +155 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/Observables.jl +78 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/OpenQuantumSimJL.jl +34 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/Operators.jl +99 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/Parallel.jl +1 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/Propagators.jl +40 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/SteadyState.jl +61 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/TimeDep.jl +191 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/Trajectories.jl +600 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/src/Utils.jl +1 -0
- openquantumsim-0.1.0a1/openquantumsim/julia/OpenQuantumSimJL/test/runtests.jl +497 -0
- openquantumsim-0.1.0a1/openquantumsim/observables.py +661 -0
- openquantumsim-0.1.0a1/openquantumsim/operators.py +462 -0
- openquantumsim-0.1.0a1/openquantumsim/phase_space.py +153 -0
- openquantumsim-0.1.0a1/openquantumsim/plot.py +210 -0
- openquantumsim-0.1.0a1/openquantumsim/py.typed +1 -0
- openquantumsim-0.1.0a1/openquantumsim/result.py +332 -0
- openquantumsim-0.1.0a1/openquantumsim/solvers.py +704 -0
- openquantumsim-0.1.0a1/openquantumsim/sweep.py +562 -0
- openquantumsim-0.1.0a1/openquantumsim/systems.py +136 -0
- openquantumsim-0.1.0a1/openquantumsim/timedep.py +162 -0
- openquantumsim-0.1.0a1/openquantumsim.egg-info/PKG-INFO +427 -0
- openquantumsim-0.1.0a1/openquantumsim.egg-info/SOURCES.txt +57 -0
- openquantumsim-0.1.0a1/openquantumsim.egg-info/dependency_links.txt +1 -0
- openquantumsim-0.1.0a1/openquantumsim.egg-info/requires.txt +24 -0
- openquantumsim-0.1.0a1/openquantumsim.egg-info/top_level.txt +1 -0
- openquantumsim-0.1.0a1/pyproject.toml +90 -0
- openquantumsim-0.1.0a1/setup.cfg +4 -0
- openquantumsim-0.1.0a1/tests/test_analyze_dicke_mi_distribution.py +101 -0
- openquantumsim-0.1.0a1/tests/test_bench_dicke_mi.py +81 -0
- openquantumsim-0.1.0a1/tests/test_docs.py +93 -0
- openquantumsim-0.1.0a1/tests/test_hilbert.py +26 -0
- openquantumsim-0.1.0a1/tests/test_observables.py +120 -0
- openquantumsim-0.1.0a1/tests/test_operators.py +158 -0
- openquantumsim-0.1.0a1/tests/test_packaging.py +42 -0
- openquantumsim-0.1.0a1/tests/test_phase_space.py +64 -0
- openquantumsim-0.1.0a1/tests/test_plot.py +47 -0
- openquantumsim-0.1.0a1/tests/test_result_io.py +150 -0
- openquantumsim-0.1.0a1/tests/test_run_dicke_mi_distribution.py +129 -0
- openquantumsim-0.1.0a1/tests/test_run_sweep.py +65 -0
- openquantumsim-0.1.0a1/tests/test_sweep.py +105 -0
- openquantumsim-0.1.0a1/tests/test_systems.py +62 -0
- openquantumsim-0.1.0a1/tests/test_timedep.py +55 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to OpenQuantumSim will be documented here.
|
|
4
|
+
|
|
5
|
+
The project follows semantic versioning once the public API reaches `0.1.0`.
|
|
6
|
+
Until then, entries are grouped under alpha releases.
|
|
7
|
+
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
## 0.1.0a1 - 2026-05-15
|
|
11
|
+
|
|
12
|
+
- Removed an invalid PyPI trove classifier from the package metadata so the
|
|
13
|
+
alpha can be published through TestPyPI/PyPI.
|
|
14
|
+
- Documented TestPyPI and PyPI trusted-publisher verification commands.
|
|
15
|
+
|
|
16
|
+
## 0.1.0a0 - 2026-05-14
|
|
17
|
+
|
|
18
|
+
- Added a Python frontend and Julia backend package scaffold.
|
|
19
|
+
- Added dense Hilbert-space, state, and operator helpers.
|
|
20
|
+
- Added `mesolve`, `mcsolve`, and `single_trajectory` Python entry points.
|
|
21
|
+
- Added HDF5 result persistence and checkpointed MCWF runs.
|
|
22
|
+
- Added model-agnostic partial trace, entropy, purity, and mutual information
|
|
23
|
+
utilities.
|
|
24
|
+
- Added named scalar `state_observables` for `mesolve` and
|
|
25
|
+
`single_trajectory`.
|
|
26
|
+
- Moved the two-ensemble Dicke workflow into `examples/dicke` so the public
|
|
27
|
+
package remains model agnostic.
|
|
28
|
+
- Added release-hygiene files for citation, contribution, changelog, and
|
|
29
|
+
publish-readiness tracking.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use OpenQuantumSim, please cite the software release."
|
|
3
|
+
title: "OpenQuantumSim"
|
|
4
|
+
version: "0.1.0a1"
|
|
5
|
+
abstract: "Python-accessible, Julia-powered simulation tools for open quantum systems."
|
|
6
|
+
authors:
|
|
7
|
+
- family-names: "Jafari"
|
|
8
|
+
given-names: "Mohammad"
|
|
9
|
+
license: "MIT"
|
|
10
|
+
repository-code: "https://github.com/mohammadjafariph/OpenQuantumSimulation"
|
|
11
|
+
keywords:
|
|
12
|
+
- "open quantum systems"
|
|
13
|
+
- "Lindblad equation"
|
|
14
|
+
- "Monte Carlo wave function"
|
|
15
|
+
- "quantum trajectories"
|
|
16
|
+
- "Julia"
|
|
17
|
+
- "Python"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
OpenQuantumSim is still pre-alpha, so the most useful contributions are small,
|
|
4
|
+
well-tested changes that make the public API clearer, more reliable, or easier
|
|
5
|
+
to install.
|
|
6
|
+
|
|
7
|
+
## Development Setup
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
python -m pip install -e ".[dev]"
|
|
11
|
+
python setup_julia.py
|
|
12
|
+
python -m pytest
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Run the Julia backend tests directly with:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
julia --project=src/OpenQuantumSimJL -e 'using Pkg; Pkg.test()'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Checks Before A Pull Request
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python -m ruff check openquantumsim examples tests scripts benchmarks README.md
|
|
25
|
+
python -m mypy openquantumsim
|
|
26
|
+
python -m pytest
|
|
27
|
+
python scripts/check_publish_ready.py
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Contribution Guidelines
|
|
31
|
+
|
|
32
|
+
- Keep the `openquantumsim` package model agnostic. Specific physics studies
|
|
33
|
+
belong in `examples/` unless they are genuinely reusable library primitives.
|
|
34
|
+
- Add tests for public behavior changes.
|
|
35
|
+
- Keep Python and Julia backend changes synchronized. The packaged Julia
|
|
36
|
+
backend mirror under `openquantumsim/julia/OpenQuantumSimJL` must match the
|
|
37
|
+
development backend under `src/OpenQuantumSimJL`.
|
|
38
|
+
- Document new public API in the README or Sphinx docs.
|
|
39
|
+
- Avoid committing generated simulation outputs.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mohammad Jafari
|
|
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,427 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openquantumsim
|
|
3
|
+
Version: 0.1.0a1
|
|
4
|
+
Summary: Python-accessible, Julia-powered simulation tools for open quantum systems.
|
|
5
|
+
Author: Mohammad Jafari
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/mohammadjafariph/OpenQuantumSimulation
|
|
8
|
+
Project-URL: Issues, https://github.com/mohammadjafariph/OpenQuantumSimulation/issues
|
|
9
|
+
Project-URL: Documentation, https://github.com/mohammadjafariph/OpenQuantumSimulation#readme
|
|
10
|
+
Project-URL: Source, https://github.com/mohammadjafariph/OpenQuantumSimulation
|
|
11
|
+
Keywords: open quantum systems,quantum trajectories,lindblad,julia
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: numpy>=1.24
|
|
23
|
+
Requires-Dist: scipy>=1.10
|
|
24
|
+
Requires-Dist: juliacall>=0.9
|
|
25
|
+
Requires-Dist: h5py>=3.8
|
|
26
|
+
Requires-Dist: xarray>=2023.1
|
|
27
|
+
Requires-Dist: matplotlib>=3.7
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=4.1; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.7; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.1.8; extra == "dev"
|
|
33
|
+
Provides-Extra: docs
|
|
34
|
+
Requires-Dist: sphinx>=7.0; extra == "docs"
|
|
35
|
+
Requires-Dist: myst-parser>=2.0; extra == "docs"
|
|
36
|
+
Requires-Dist: myst-nb>=1.0; extra == "docs"
|
|
37
|
+
Provides-Extra: release
|
|
38
|
+
Requires-Dist: build>=1.2; extra == "release"
|
|
39
|
+
Requires-Dist: twine>=5.0; extra == "release"
|
|
40
|
+
Provides-Extra: validation
|
|
41
|
+
Requires-Dist: qutip>=5.0; extra == "validation"
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
# OpenQuantumSim
|
|
45
|
+
|
|
46
|
+
Python-accessible, Julia-powered tools for simulating open quantum systems.
|
|
47
|
+
|
|
48
|
+
OpenQuantumSim is starting as a research-grade package with a Python frontend
|
|
49
|
+
and a Julia backend. The first development target is a reliable MVP for
|
|
50
|
+
Lindblad master-equation propagation, Monte Carlo wave-function trajectories,
|
|
51
|
+
basic Hilbert-space construction, observables, and validation against canonical
|
|
52
|
+
open-system examples.
|
|
53
|
+
|
|
54
|
+
## Current Status
|
|
55
|
+
|
|
56
|
+
This repository is a public alpha candidate. It is usable for development and
|
|
57
|
+
local research runs; release readiness is tracked in
|
|
58
|
+
`docs/release_checklist.md`. The current package includes:
|
|
59
|
+
|
|
60
|
+
- A Python package namespace: `openquantumsim`
|
|
61
|
+
- A Julia backend package: `OpenQuantumSimJL`
|
|
62
|
+
- Basic Hilbert-space types and dense Python operator primitives
|
|
63
|
+
- Sparse Julia operator and observable primitives
|
|
64
|
+
- Symmetric Dicke manifolds for collective spin ensembles
|
|
65
|
+
- General subsystem utilities such as `partial_trace` and mutual information
|
|
66
|
+
- Solver entry points for `mesolve`, time-dependent `mesolve`, `mcsolve`, and
|
|
67
|
+
`steadystate`
|
|
68
|
+
- Starter tests for Python and Julia
|
|
69
|
+
- Release metadata and package-data wiring for the Julia backend
|
|
70
|
+
|
|
71
|
+
## Roadmap Focus
|
|
72
|
+
|
|
73
|
+
Phase 1 and Phase 2 follow the R&D roadmap:
|
|
74
|
+
|
|
75
|
+
1. Implement `FockSpace`, `SpinSpace`, basic states, and operators.
|
|
76
|
+
2. Build a `juliacall` bridge that loads `OpenQuantumSimJL`.
|
|
77
|
+
3. Implement `mesolve` for time-independent Lindblad dynamics.
|
|
78
|
+
4. Implement `mcsolve` for MCWF trajectories with thread-local RNG.
|
|
79
|
+
5. Add sparse/Krylov propagation and composite-space observables.
|
|
80
|
+
6. Add time-dependent Hamiltonians and parameter-sweep execution.
|
|
81
|
+
7. Validate against qubit decay and Jaynes-Cummings reference results.
|
|
82
|
+
|
|
83
|
+
## Quick Start
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
python -m pip install -e .
|
|
87
|
+
python setup_julia.py
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The first Julia backend setup may spend a few minutes precompiling packages.
|
|
91
|
+
Then run a small spontaneous-emission smoke test:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
python - <<'PY'
|
|
95
|
+
import numpy as np
|
|
96
|
+
import openquantumsim as oqs
|
|
97
|
+
|
|
98
|
+
atom = oqs.SpinSpace(0.5, label="atom")
|
|
99
|
+
H = 0.0 * oqs.sigmaz(atom)
|
|
100
|
+
psi0 = oqs.basis(atom, "up")
|
|
101
|
+
rho0 = oqs.ket2dm(psi0)
|
|
102
|
+
gamma = 0.2
|
|
103
|
+
collapse = np.sqrt(gamma) * oqs.sigmam(atom)
|
|
104
|
+
projector = oqs.Operator(oqs.ket2dm(psi0), atom, "P_excited")
|
|
105
|
+
times = np.linspace(0.0, 0.2, 3)
|
|
106
|
+
|
|
107
|
+
result = oqs.mesolve(H, rho0, times, c_ops=[collapse], e_ops=[projector])
|
|
108
|
+
expected = np.exp(-gamma * times)
|
|
109
|
+
print(result.expect[0].real)
|
|
110
|
+
assert np.allclose(result.expect[0].real, expected, atol=2e-7)
|
|
111
|
+
PY
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For development checks, install the optional test tools and run:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
python -m pip install -e ".[dev]"
|
|
118
|
+
python -m pytest
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For the Julia backend:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
julia --project=src/OpenQuantumSimJL -e 'using Pkg; Pkg.test()'
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Build the local API docs and tutorial notebooks with:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
python -m pip install -e ".[docs]"
|
|
131
|
+
sphinx-build -b html docs docs/_build/html
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Benchmarks
|
|
135
|
+
|
|
136
|
+
The first benchmark harness measures Monte Carlo trajectory scaling for the
|
|
137
|
+
qubit decay validation problem:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
PYTHON_JULIACALL_HANDLE_SIGNALS=yes JULIA_NUM_THREADS=auto \
|
|
141
|
+
python benchmarks/bench_mcsolve.py --n-traj 1000 --repeats 3
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Use `scripts/run_benchmarks.sh` to run the default benchmark entry point. The
|
|
145
|
+
report includes Python elapsed time, Julia backend wall time, worker count, and
|
|
146
|
+
the maximum expectation-value delta from the serial reference.
|
|
147
|
+
|
|
148
|
+
The Dicke mutual-information research example has a separate batch benchmark:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
python examples/dicke/bench_mi.py \
|
|
152
|
+
--N 6 \
|
|
153
|
+
--n-traj 20 \
|
|
154
|
+
--time-points 101 \
|
|
155
|
+
--batch-size 5 \
|
|
156
|
+
--n-jobs 1 4 \
|
|
157
|
+
--target-n-traj 1000
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Production Runner
|
|
161
|
+
|
|
162
|
+
A checkpointed MCWF runner is available for the qubit-decay validation problem:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
python scripts/run_mcsolve_qubit_decay.py \
|
|
166
|
+
--n-traj 2000 \
|
|
167
|
+
--checkpoint-file runs/qubit_decay_checkpoint.h5 \
|
|
168
|
+
--output runs/qubit_decay.h5 \
|
|
169
|
+
--force
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The script resumes from an existing matching checkpoint, prints progress by
|
|
173
|
+
default, and saves the final solver result as HDF5.
|
|
174
|
+
|
|
175
|
+
## Sweep Runner
|
|
176
|
+
|
|
177
|
+
The public `ParameterSweep` API expands parameter grids, skips completed
|
|
178
|
+
points on rerun, writes a restartable manifest, saves returned `Result`
|
|
179
|
+
objects, and produces aggregate `summary.csv` / `summary.h5` files:
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
sweep = oqs.ParameterSweep(
|
|
183
|
+
base_system={"model": "qubit_decay"},
|
|
184
|
+
params={"kappa": [0.02, 0.05, 0.1]},
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
run = sweep.run(run_one_point, output_dir="runs/kappa_sweep")
|
|
188
|
+
print(run.summary)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The CLI wrapper uses the same output layout:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
python scripts/run_sweep.py \
|
|
195
|
+
--kappa-values 0.02,0.05,0.1 \
|
|
196
|
+
--n-traj 2000 \
|
|
197
|
+
--output-dir runs/kappa_sweep
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Re-running the same command skips completed points and resumes unfinished
|
|
201
|
+
checkpointed points.
|
|
202
|
+
|
|
203
|
+
Research examples live on top of the general solver API. The roadmap
|
|
204
|
+
two-ensemble Dicke study has its model builder and analysis scripts in
|
|
205
|
+
`examples/dicke/`.
|
|
206
|
+
|
|
207
|
+
Single trajectories can save kets for trajectory-level diagnostics:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
import numpy as np
|
|
211
|
+
import openquantumsim as oqs
|
|
212
|
+
from examples.dicke.observables import trajectory_dicke_mutual_information
|
|
213
|
+
from examples.dicke.system import two_ensemble_dicke_system
|
|
214
|
+
|
|
215
|
+
system = two_ensemble_dicke_system(N=6, kappa=0.1)
|
|
216
|
+
times = np.linspace(0.0, 1.0, 101)
|
|
217
|
+
|
|
218
|
+
result = oqs.single_trajectory(
|
|
219
|
+
system.H,
|
|
220
|
+
system.psi0,
|
|
221
|
+
times,
|
|
222
|
+
c_ops=system.c_ops,
|
|
223
|
+
e_ops=system.e_ops,
|
|
224
|
+
options=oqs.Options(seed=2026, max_step=0.01, save_states=True),
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
mi_a, mi_b = trajectory_dicke_mutual_information(result.states or [], 6)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
For batched MI distributions, use the restartable trajectory runner:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
python examples/dicke/run_mi_distribution.py \
|
|
234
|
+
--n-values 6,8,12 \
|
|
235
|
+
--kappa-values 0.1 \
|
|
236
|
+
--n-traj 1000 \
|
|
237
|
+
--time-points 2001 \
|
|
238
|
+
--t-final 200 \
|
|
239
|
+
--n-jobs 4 \
|
|
240
|
+
--batch-size 10 \
|
|
241
|
+
--output runs/dicke_mi_distribution.h5
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The HDF5 output stores `MI_time_A`, `MI_time_B`, `MI_steady_A`, and
|
|
245
|
+
`MI_steady_B` under `kappa_<value>/N_<N>` groups and can resume incomplete
|
|
246
|
+
points from the stored trajectory count. Worker processes compute trajectory
|
|
247
|
+
batches; the parent process owns all HDF5 writes.
|
|
248
|
+
|
|
249
|
+
Summarize and plot completed MI distribution runs with:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
python examples/dicke/analyze_mi_distribution.py \
|
|
253
|
+
--input runs/dicke_mi_distribution.h5 \
|
|
254
|
+
--output-dir runs/dicke_mi_analysis
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The analyzer writes `summary.csv`, `summary.h5`, `steady_mi_mean.png`, and
|
|
258
|
+
`steady_mi_boxplot.png`.
|
|
259
|
+
|
|
260
|
+
The first recommended pilot settings are captured in `examples/dicke/README.md`.
|
|
261
|
+
|
|
262
|
+
## Validation
|
|
263
|
+
|
|
264
|
+
Canonical validation cases currently cover analytic qubit decay and a
|
|
265
|
+
Jaynes-Cummings comparison against QuTiP. Install the optional validation extra
|
|
266
|
+
or QuTiP directly, then run:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
python scripts/validate_jaynes_cummings_qutip.py
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The script compares cavity photon number and atomic excited-state population
|
|
273
|
+
between OpenQuantumSim and QuTiP, and exits nonzero if the maximum deviation
|
|
274
|
+
exceeds the requested tolerance.
|
|
275
|
+
|
|
276
|
+
Two-time correlations use the quantum regression theorem for time-independent
|
|
277
|
+
Lindblad systems:
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
taus = np.linspace(0.0, 4.0, 101)
|
|
281
|
+
corr = oqs.correlation_2op_1t(
|
|
282
|
+
H,
|
|
283
|
+
rho0,
|
|
284
|
+
taus,
|
|
285
|
+
oqs.sigmap(qubit),
|
|
286
|
+
oqs.sigmam(qubit),
|
|
287
|
+
c_ops=[collapse],
|
|
288
|
+
)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Finite Fock-space states can also be inspected in phase space:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
x, p = oqs.phase_space_grid(xlim=(-5.0, 5.0), points=201)
|
|
295
|
+
rho = oqs.ket2dm(oqs.coherent(oqs.FockSpace(30), 1.0 + 0.5j))
|
|
296
|
+
|
|
297
|
+
W = oqs.wigner(rho, x, p)
|
|
298
|
+
Q = oqs.q_function(rho, x, p)
|
|
299
|
+
ax = oqs.plot_wigner(rho, x, p)
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Minimal Python Example
|
|
303
|
+
|
|
304
|
+
```python
|
|
305
|
+
import numpy as np
|
|
306
|
+
import openquantumsim as oqs
|
|
307
|
+
|
|
308
|
+
qubit = oqs.SpinSpace(0.5, label="atom")
|
|
309
|
+
sm = oqs.sigmam(qubit)
|
|
310
|
+
H = 0.5 * oqs.sigmaz(qubit)
|
|
311
|
+
rho0 = oqs.ket2dm(oqs.basis(qubit, "up"))
|
|
312
|
+
|
|
313
|
+
print(H.shape)
|
|
314
|
+
print(np.trace(rho0))
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Subsystem observables are model agnostic:
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
bell = np.array([1, 0, 0, 1], dtype=np.complex128) / np.sqrt(2)
|
|
321
|
+
rho_a = oqs.partial_trace(bell, dims=(2, 2), keep=0)
|
|
322
|
+
mi_ab = oqs.mutual_information(bell, dims=(2, 2), subsystem_a=0, subsystem_b=1)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Time-dependent Hamiltonians can be written as `H0 + sum_i f_i(t) H_i`:
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
drive = oqs.InterpolatedCoefficient([0.0, 5.0], [0.0, 0.2])
|
|
329
|
+
H_t = oqs.time_dependent_hamiltonian(
|
|
330
|
+
0.5 * oqs.sigmaz(qubit),
|
|
331
|
+
[(oqs.sigmax(qubit), drive)],
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
result = oqs.mesolve(H_t, rho0, np.linspace(0.0, 5.0, 101))
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Collective open-system models can use a symmetric Dicke manifold instead of
|
|
338
|
+
the full `2**N` spin Hilbert space:
|
|
339
|
+
|
|
340
|
+
```python
|
|
341
|
+
ensemble = oqs.DickeSpace(20, label="atoms")
|
|
342
|
+
Jm = oqs.collective_lowering(ensemble)
|
|
343
|
+
Jx = oqs.collective_x(ensemble)
|
|
344
|
+
Nexc = oqs.collective_excitation(ensemble)
|
|
345
|
+
|
|
346
|
+
H = 0.5 * Jx
|
|
347
|
+
c_ops = [np.sqrt(0.1 / ensemble.n_spins) * Jm]
|
|
348
|
+
psi0 = oqs.dicke_state(ensemble, excitations=ensemble.n_spins)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Arbitrary scalar diagnostics can be evaluated from saved kets or density
|
|
352
|
+
matrices and persisted with the solver result:
|
|
353
|
+
|
|
354
|
+
For `mcsolve`, built-in diagnostics from `state_metrics` that are linear
|
|
355
|
+
expectations or pure-trajectory constants are aggregated in the Julia backend
|
|
356
|
+
with mean, standard deviation, and standard error.
|
|
357
|
+
|
|
358
|
+
```python
|
|
359
|
+
metrics = oqs.state_metrics(
|
|
360
|
+
purity=True,
|
|
361
|
+
fidelity_to=psi0,
|
|
362
|
+
population_indices=[0, 1],
|
|
363
|
+
)
|
|
364
|
+
metrics["left_entropy"] = lambda ket: oqs.von_neumann_entropy(
|
|
365
|
+
oqs.partial_trace(ket, dims=(2, 2), keep=0)
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
result = oqs.single_trajectory(
|
|
369
|
+
H,
|
|
370
|
+
psi0,
|
|
371
|
+
times,
|
|
372
|
+
c_ops=c_ops,
|
|
373
|
+
state_observables=metrics,
|
|
374
|
+
options=oqs.Options(seed=2026, max_step=0.01),
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
left_entropy = result.state_observables["left_entropy"].real
|
|
378
|
+
return_fidelity = result.state_observables["fidelity"].real
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Result Persistence
|
|
382
|
+
|
|
383
|
+
Solver results can be saved in a portable HDF5 format:
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
result.save_hdf5("runs/qubit_decay.h5")
|
|
387
|
+
loaded = oqs.load_result("runs/qubit_decay.h5")
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
The file stores time points, expectation series, optional saved states,
|
|
391
|
+
state-observable series, Monte Carlo uncertainty estimates, entropy, and solver
|
|
392
|
+
statistics. The full schema is documented in
|
|
393
|
+
`docs/result_hdf5_schema.rst`.
|
|
394
|
+
|
|
395
|
+
Long Monte Carlo trajectory runs can also checkpoint partial trajectory sums:
|
|
396
|
+
|
|
397
|
+
```python
|
|
398
|
+
result = oqs.mcsolve(
|
|
399
|
+
H,
|
|
400
|
+
psi0,
|
|
401
|
+
times,
|
|
402
|
+
c_ops=[collapse],
|
|
403
|
+
e_ops=[observable],
|
|
404
|
+
n_traj=20_000,
|
|
405
|
+
options=oqs.Options(
|
|
406
|
+
seed=2026,
|
|
407
|
+
checkpoint_file="runs/mcsolve_checkpoint.h5",
|
|
408
|
+
checkpoint_every=100,
|
|
409
|
+
progress=True,
|
|
410
|
+
),
|
|
411
|
+
)
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Calling `mcsolve` again with the same checkpoint file, seed, operators, time
|
|
415
|
+
grid, and `max_step` resumes from the stored trajectory count. Set
|
|
416
|
+
`progress=False` for silent batch runs.
|
|
417
|
+
|
|
418
|
+
## Repository Layout
|
|
419
|
+
|
|
420
|
+
```text
|
|
421
|
+
openquantumsim/ Python frontend
|
|
422
|
+
src/OpenQuantumSimJL/ Julia backend package
|
|
423
|
+
tests/ Python test suite
|
|
424
|
+
docs/ Sphinx documentation skeleton
|
|
425
|
+
benchmarks/ Benchmark scripts
|
|
426
|
+
scripts/ Development helpers
|
|
427
|
+
```
|