Context
Workstream B3 in OVERVIEW.md lists an open-system extension: Gilbert damping as a Lindblad operator. pyproject.toml already declares the [open] extra with qutip>=5.0. gates.py Issue #11 ships a damping_channel_spec() stub; this issue implements the actual dissipative reservoir dynamics.
Notebook 06 is planned in docs/notebooks.md:
- File: notebooks/06_open_system_qrc.ipynb
- Output: figures/open_system_qrc.png
- Install: pip install -e "./spintronic-qrc[open]" or [all]
PennyLane can represent some channels, but the canonical approach for Lindblad master-equation validation is QuTiP. Compare open-system features against the closed-system pipeline from Issue #1 on a short NARMA-10 or impulse run.
Goal
- Add src/spintronic_qrc/open_system.py — QuTiP Lindblad evolution for the XXZ chain + damping
- Bridge open-system states to Pauli expectation readout features compatible with trainer.py
- Create notebooks/06_open_system_qrc.ipynb with committed figure
- Optional: benchmarks/run_open_system.py for reproducibility
Requirements
1. Lindblad model
Open XXZ chain with Gilbert-type amplitude/phase damping on each site (document chosen model):
d rho / dt = -i [H, rho] + sum_i D_i[rho]
Start with independent amplitude damping per site (one Lindblad operator per site) or collective dephasing — pick one, cite Breuer & Petruccione (REFERENCES.md O1) and Manzano (O2) in docstring.
Build H as QuTiP operator from the same parameters as xxz_chain_hamiltonian (J_xy, J_z, disorder field).
@dataclass
class OpenSystemConfig:
n_sites: int
J_xy: float = 1.0
J_z: float = 1.0
disorder: float = 0.5
gamma: float = 0.01 # damping rate
evolution_time: float = 0.8
seed: int | None = 42
2. Evolution API
def evolve_density_matrix(
rho0,
config: OpenSystemConfig,
) -> object: # qutip.Qobj
"""Mesolve one step or full interval; document time grid."""
def collect_open_features(
inputs: np.ndarray,
config: OpenSystemConfig,
*,
washout: int = 100,
) -> np.ndarray:
"""
Open-system analogue of pipeline.collect_features:
encode input -> Lindblad step -> Pauli expectations from rho.
"""
Encoding: map scalar u(t) to local field Hamiltonian perturbation for that timestep (consistent with encoder.py local-field picture).
Readout: Tr(rho sigma_i^alpha) for configured Pauli set.
3. Comparison helper
def compare_closed_vs_open_narma10(
qrc_config,
open_config: OpenSystemConfig,
length: int = 500,
seed: int = 42,
) -> dict[str, float]:
"""Return test_rmse closed vs open on short NARMA-10."""
Expect open error >= closed at moderate gamma — validates damping hurts performance (or document noise-assisted regime if not).
4. Tests — tests/test_open_system.py
Mark tests requiring QuTiP:
pytest.importorskip("qutip")
| Test |
Verifies |
| test_density_matrix_trace_one |
Tr(rho) = 1 after evolution |
| test_collect_open_features_shape |
Correct feature matrix shape |
| test_zero_gamma_matches_closed_limit |
gamma=0 close to closed features (tolerance) |
| test_open_features_no_nan |
Finite features |
Skip entire module if qutip not installed (default dev install may not include [open]).
5. Notebook 06 structure
- Title: Open-system QRC with Gilbert damping
- Setup with [open] install note
- Plot: closed vs open NARMA-10 test_rmse vs gamma sweep (e.g. gamma in [0, 0.001, 0.01, 0.05])
- Panel: example rho dynamics (one-site expectation vs time)
- Save figures/open_system_qrc.png
- Optional CSV: data/open_system_results.csv
6. Documentation
- docs/api.md — open_system section
- README.md — note Notebook 06 requires [open]
- REFERENCES.md O1–O4 already present
Scope limits
- No full pipeline.py rewrite — open path is parallel module
- No mtj-quantum-noise integration (future repo)
- gamma sweep in notebook only; Optuna not required
Acceptance criteria
Files likely touched
- src/spintronic_qrc/open_system.py (new)
- tests/test_open_system.py (new)
- notebooks/06_open_system_qrc.ipynb (new)
- figures/open_system_qrc.png (new)
- docs/api.md
- README.md (minor)
Depends on
Blocks
- Full [all] extra validation
- Paper discussion section on dissipation
Context
Workstream B3 in OVERVIEW.md lists an open-system extension: Gilbert damping as a Lindblad operator. pyproject.toml already declares the [open] extra with qutip>=5.0. gates.py Issue #11 ships a damping_channel_spec() stub; this issue implements the actual dissipative reservoir dynamics.
Notebook 06 is planned in docs/notebooks.md:
PennyLane can represent some channels, but the canonical approach for Lindblad master-equation validation is QuTiP. Compare open-system features against the closed-system pipeline from Issue #1 on a short NARMA-10 or impulse run.
Goal
Requirements
1. Lindblad model
Open XXZ chain with Gilbert-type amplitude/phase damping on each site (document chosen model):
Start with independent amplitude damping per site (one Lindblad operator per site) or collective dephasing — pick one, cite Breuer & Petruccione (REFERENCES.md O1) and Manzano (O2) in docstring.
Build H as QuTiP operator from the same parameters as xxz_chain_hamiltonian (J_xy, J_z, disorder field).
2. Evolution API
Encoding: map scalar u(t) to local field Hamiltonian perturbation for that timestep (consistent with encoder.py local-field picture).
Readout: Tr(rho sigma_i^alpha) for configured Pauli set.
3. Comparison helper
Expect open error >= closed at moderate gamma — validates damping hurts performance (or document noise-assisted regime if not).
4. Tests — tests/test_open_system.py
Mark tests requiring QuTiP:
Skip entire module if qutip not installed (default dev install may not include [open]).
5. Notebook 06 structure
6. Documentation
Scope limits
Acceptance criteria
Files likely touched
Depends on
Blocks