Skip to content

Kossakowski-form dissipator + dissipative pc_step_orbit_rep validation - #179

Closed
AlexSchuckert wants to merge 50 commits into
split/3-symmetric-evolutionfrom
kossakowski-dissipator
Closed

Kossakowski-form dissipator + dissipative pc_step_orbit_rep validation#179
AlexSchuckert wants to merge 50 commits into
split/3-symmetric-evolutionfrom
kossakowski-dissipator

Conversation

@AlexSchuckert

Copy link
Copy Markdown
Collaborator

Stacked on #178 (base: continuous-time-pauli-propagation).

What this adds

Kossakowski-form dissipators: D*(O) = Σ_nm K_nm (A_n† O A_m − ½{A_n†A_m, O}) specified directly by an operator list + Hermitian PSD pair matrix — the natural form for collective decay (every emitter pair shares a channel via Γ_nm from the free-space Green's function). Mathematically identical to eigendecomposing K into N dense collective jumps, but the per-string action costs one term-pair product per nonzero K_nm instead of carrying an extra factor of N: O(N²) instead of O(N³).

  • Rust: one JumpKind::KossakowskiPair per nonzero K_nm (precompiled sandwich table + A_n†A_m lincomb, per-pair support masks), plugged into compute_action_terms — so action/leakage/generator/pc_step/pc_step_orbit_rep all inherit it. Includes a one-sided fast path: strings touching only one of a pair's two sites collapse to ±½[K·A_n†A_m, p] (4 Pauli products instead of 12; the dominant case for local strings under dense K).
  • Python: Lindbladian(..., kossakowski=(ops, K)), validating Hermiticity and positive semidefiniteness (raises — no silent clipping). Coexists with jump_terms.

Dissipative pc_step_orbit_rep validation: the orbit path applies jump/Kossakowski terms correctly with no code change. Under the 1/|G| projection convention of canonicalize_basis_arr_complex (c_rep = coeff_word/|Stab|), the phase-aware action is exact for any translation-equivariant generator, including transitions between orbits of different sizes (the non-unital Z→I flow). Corollary (documented + tested): a translation-invariant {I,Z} observable reads out as |G|·Σ c_rep.

Numbers

Measured per-pc_step wall (criterion, B=4096, superradiance chain d=0.1λ₀), eigenmode jumps vs Kossakowski:

NeigenmodeKossakowskiwin
10274 ms81 ms3.4×
201.43 s161 ms8.9×
304.35 s250 ms17.4×

(pre-optimization Kossakowski walls; two further kept optimizations take another ~40% off — full history in docs/autotune/2026-07-16-kossakowski/).

Validation

  • Representation equivalence: random models (mixed σ⁻ + generic lincomb ops, real and complex Hermitian PSD K) ≤ 1e-12; N=6 superradiance chain vs eigenmode ≤ 1e-11.
  • Physics: N=6 chain R(t) vs exact excitation-cascade ED < 1e-4 (vs the stored fig11 exact reference: 1.1e-05).
  • Orbit path: N=6 ring orbit-vs-projected-full equivalence ~2e-15 (both representations); R(t) vs ring ED < 1e-4; N=10 truncated-regime sanity (finite, admission-bounded, monotone in rep budget); identity bookkeeping vs closed form ≤ 1e-9.
  • Leakage coverage test guarantees admission sees Kossakowski terms.
  • 250 Python tests + Rust suites green; coherent regression gates bit-identical; zero clippy warnings.

🤖 Generated with Claude Code

@github-actions

github-actionsBot commented Jul 16, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-02 07:20 UTC

AlexSchuckertand others added 5 commits July 16, 2026 13:14
…daptive Lindbladian evolution
Direct Heisenberg-picture evolution O ← exp(dt·L*)O on an adaptively
truncated Pauli-string basis: exact in dt within the working basis, no
Trotter splitting. LindbladSpec precompiles Hermitian-Pauli (fast
diagonal) and general complex Pauli-sum jumps (σ±, amplitude damping,
precomputed L†L); pc_step does two-hop leakage enrichment + predictor/
corrector matrix-free exponential via quspin-expm (MIT), with the
truncation policy in one PcStepConfig (max_basis rank cap, admit_basis
displacement bound, drop_tol prune, tau_add admission filter).
Python: ppvm.Lindbladian with numpy hot path + string convenience API,
mimalloc global allocator (~50% peak-RSS cut on adaptive paths), two
jupytext demos, tests against dense-Liouvillian / closed-form / eig
references.
Split 2/4 of the CTPP work; the momentum-sector (orbit-rep) evolution
follows in split 3. Full history: branch continuous-time-pauli-propagation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two consumers of the translation-symmetry primitive:
Trotter path: PauliSum.symmetry_merge (k=0) and PauliSum.momentum_merge
(k≠0 carried as a real pair, character-weighted fold, |G|-rescaled to
the summing projector so merging after every step is idempotent), with
TranslationGroup and canonicalize_basis_arr{,_complex} /
check_momentum_sector_arr exposed to Python. Inputs validated at the
boundary (ValueError, not panics).
CTPP path: pc_step_orbit_rep — per-step evolution entirely in
orbit-representative form (complex coefficients, phase-aware action,
cached-CSC expm; basis ~|G|× smaller than full-basis evolution,
persisting through every step), with the same PcStepConfig truncation
policy incl. displacement admission.
Split 3/4 of the CTPP work; full history on branch
continuous-time-pauli-propagation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The complete experiment ledgers behind the CTPP design decisions:
truncation-scheme comparisons (cap/valve vs displacement vs
thresholds), the momentum-vs-real-space study, exact-reference
methodology, the L=21/L=41 application exhibits, and every kept or
discarded attempt with its measured numbers. Scan drivers and ED
reference generators included as text; plots and .npz exact-reference
data (~2.5 MB) live on the archive branch
continuous-time-pauli-propagation.
Split 4/4 of the CTPP work.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rep validation
D*(O) = Σ_nm K_nm (A_n†OA_m − ½{A_n†A_m,O}) from an operator list +
Hermitian PSD pair matrix — exactly equivalent to the eigenmode-jump
representation but O(N²) instead of O(N³) per string (measured
3.4×/8.9×/17.4× per pc_step at N=10/20/30 on the superradiance chain;
criterion bench included). One JumpKind::KossakowskiPair per nonzero
K_nm with a precompiled sandwich table and a one-sided ±½[K·A_n†A_m, p]
commutator fast path; all step/leakage/generator paths inherit it via
compute_action_terms. Python: Lindbladian(..., kossakowski=(ops, K))
with Hermiticity/PSD validation (raises, no silent clipping).
Dissipative pc_step_orbit_rep validated correct out of the box (the
1/|G| projection convention makes the phase-aware action exact for any
equivariant generator, incl. the non-unital Z→I flow): orbit vs
projected-full ≤1e-12, R(t) vs excitation-cascade ED <1e-4, identity
bookkeeping vs closed form, truncated-regime sanity. Physics regression:
N=6 superradiance chain vs exact cascade <1e-4 (vs the fig11 stored
reference: 1.1e-05).
Squashed from archive/kossakowski-dissipator (full history there).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@AlexSchuckert
AlexSchuckertforce-pushed the kossakowski-dissipator branch from a3ba18f to d3a8ffaCompareJuly 16, 2026 12:24
@AlexSchuckert
AlexSchuckert changed the base branch from continuous-time-pauli-propagation to split/3-symmetric-evolutionJuly 16, 2026 12:24
AlexSchuckertand others added 21 commits July 16, 2026 13:31
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	crates/ppvm-python-native/src/lindblad.rs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ord) — cargo machete
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AlexSchuckertand others added 19 commits July 16, 2026 13:57
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The split/3 merge conflicted on the Lindbladian __init__ signature and
the markers were committed; resolved by combining the kossakowski kwarg
with the tightened jump_terms typing. Full gauntlet green (ty, ruff
check+format, 250 tests).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bitvec implements BitStore for u64 only on 64-bit targets, so the
[u64; 2] word storage broke the wasm32 workspace build. The chunk type
is now target-gated: two u64 chunks on 64-bit targets (bit-identical to
before), four u32 chunks elsewhere — 128 qubits either way. The
chunk loops (anti_commutes / pauli_mul) were already width-agnostic.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	crates/ppvm-lindblad/src/lib.rs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@AlexSchuckert
AlexSchuckertforce-pushed the kossakowski-dissipator branch from ce6e79d to 4992d1eCompareJuly 16, 2026 15:24
AlexSchuckertand others added 5 commits July 17, 2026 10:05
Adds the molecular ZULF-NMR dipolar workload (2-local rank-2 tensor ops,
block-diagonal K over 5 spatial harmonics, dense high-weight basis strings)
as a criterion bench and a fast pc_step_timed profiling example — the A/B
harness for the drug-kossakowski autotune campaign. This path stresses the
both-sided sandwich, unlike the single-term sigma-minus superradiance bench.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Group the precompiled sandwich table by the left word P_a so P_a.p is
computed once per distinct P_a and reused across its P_b partners, instead
of one pauli_mul pair per (P_a,P_b) term-pair. No-op for single-term ops
(the superradiance sigma-minus case, why it2 in the 07-16 ledger found it
noise-level), but for the multi-term 2-local tensors of dipolar relaxation
(~4 terms/op) it cuts the both-sided sandwich from 32 to 20 pauli_mul.
Same-session A/B on the drug_profile harness (n=10, B=1500, 5 steps):
7039 -> 5765 ms/step = 18% (1.22x). Equivalence tests unchanged
(kossakowski_pair_matches_eigenmode_jumps green; 3-spin ZULF dense-vs-koss
action 3.3e-15, trajectory 3.2e-14).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The action keeps only the real part, and P_i.p.Q_j / Q_j.p.P_i produce the
same Pauli word with conjugate phase, so a Hermitian-conjugate pair collapses
to one upper-triangle (n<=m) entry using only the (n,m) products:
- both-sided sandwich: double and take the real part;
- both-sided anticommutator: dd = 2*Re(K_nm A_n#A_m) (Hermitian sum);
- one-sided: +-1/2 [F, p] with F = -2i*Im(K_nm A_n#A_m) (anti-Hermitian
difference of the folded conjugate one-sided contributions).
Diagonal pairs keep the original single-pair handling. Halves the pair count
(P^2 -> P(P+1)/2), and the off-diagonal real-part accumulation drops the
complex arithmetic and per-pair imaginary-cancellation bookkeeping.
General for any Hermitian PSD K (not just real). Same-session A/B on
drug_profile (n=10, B=1500): 5765 -> 2281 ms/step = 2.53x (cumulative from
baseline 7039 -> 2281 = 3.08x). kossakowski_pair_matches_eigenmode_jumps and
the full lindblad suite green; 3-spin ZULF action 3.3e-15, gemcitabine
(N=10) action 1.5e-15 vs dense jumps.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Records the drug-workload Kossakowski campaign (baseline 7039 -> it1 5765 ->
it2 2281 ms/step = 3.08x cumulative; 6.0x / 1.3x-RAM representation win over
dense jumps on gemcitabine N=10). Introduces a SandwichGroups type alias and
type-complexity allows on the bench/example geometry helpers to keep clippy
at zero warnings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
cargo fmt --all on the bench, profiler example, and the it2 dissipator
construction (the pre-commit cargo-fmt hook was red). No logic change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@david-pl
david-plforce-pushed the split/3-symmetric-evolution branch from 36cb95d to 070bc75CompareSeptember 2, 2026 07:16
@david-pl

Copy link
Copy Markdown
Collaborator

Superseded by the split starting with #180

@david-pldavid-pl closed this Sep 2, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AlexSchuckert@david-pl