quchip.chip.baths

Chip-level baths — shared / collective Lindblad dissipation.

A Bath is not a device: it owns no Hilbert-space factor and no Hamiltonian term. It owns only collapse operators that couple a set of devices to a common environment. This is the layer for physics that lives around devices: a single chip temperature (every device thermalizes at it) or correlated/collective dissipation (collective decay, correlated dephasing) that per-device noise — independent by construction — cannot express.

Rates are in 1/ns (the Lindblad convention; no 2π scaling — that boundary is Hamiltonian-only). The thermal Bose factor uses k_B in GHz/mK, so = 1 / expm1(freq / (k_B * T)) with freq in GHz and T in mK.

Classes

Bath(recipe[, targets, temperature, rate, ...])

A shared environment coupling a set of devices to a common bath.

class quchip.chip.baths.Bath(recipe, targets=None, *, temperature=None, rate=None, correlated=False, label=None)[source]

Bases: object

A shared environment coupling a set of devices to a common bath.

Attach at construction (Chip(..., baths=[...])) or at any time after via add_bath() — the next simulate/solve collects the bath’s collapse operators automatically.

Parameters:
  • recipe (str) – One of "thermal", "collective_decay", "correlated_dephasing".

  • targets (list[BaseDevice | str] | None) – Devices the bath couples to (objects or labels). None (default) means every device in the chip — natural for a global thermal bath.

  • temperature (float | None) – Bath temperature in mK (required for "thermal"). May be a JAX tracer for sweeps / gradients.

  • rate (float | None) – Bath–device coupling rate γ in 1/ns. For "thermal" it is the environmental coupling rate (explicit — never silently borrowed from a device T1, so it cannot double-count device-level noise). For the collective recipes it is the overall jump rate. None defaults to 1.0 (user controls the absolute scale elsewhere).

  • correlated (bool) – "thermal" only: False (default) emits independent per-device channels sharing one temperature. True is reserved for a genuinely collective thermal jump operator and currently raises NotImplementedError — it is a documented future refinement, not a silent no-op. The collective recipes always emit a single correlated operator regardless of this flag.

  • label (str | None) – Auto-generated "bath_{n}" when omitted.

Examples

>>> from quchip import DuffingTransmon, Chip, Bath
>>> q = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="q")
>>> chip = Chip([q])
>>> _ = chip.add_bath(Bath("thermal", temperature=20.0))  # global 20 mK bath
>>> _ = chip.add_bath(Bath("collective_decay", targets=[q], rate=0.01))
resolve_targets(chip)[source]

Return the ordered target device labels (defaults to all devices).

Parameters:

chip (Chip)

Return type:

list[str]

property separable: bool

Whether this bath factorizes into independent per-target channels.

True for recipes that emit one collapse operator per target ("thermal" with independent channels); False for recipes that emit a single jump operator summed over targets ("collective_decay", "correlated_dephasing"). Partitioning treats a non-separable bath’s target set as one inseparable block.

to_dict()[source]

Serialize the bath; targets are stored as label strings.

Return type:

dict[str, Any]

classmethod from_dict(d)[source]

Reconstruct a bath from serialized state (targets as label strings).

Parameters:

d (dict[str, Any])

Return type:

Bath

physics_notes()[source]

Return human-readable declarations of this bath’s recipe and scope.

Mirrors physics_notes(): one entry naming the recipe and its targets, plus a recipe-specific assumption a user of this bath should be aware of.

Return type:

list[str]

copy()[source]

Independent copy of this bath (targets normalize to label strings).

Used by Chip.clone and eliminate so a transformed chip never shares live Bath objects with its source — mutating one chip’s bath must not silently change another chip’s physics. Parameter values (temperature, rate) are carried by reference, so traced values stay traced.

Return type:

Bath

collapse_operators(chip)[source]

Fully-embedded collapse operators for this bath.

"thermal" emits independent per-target relaxation/absorption pairs sharing one bath temperature (_bose()). The two collective recipes instead each emit a single jump operator summed over the resolved targets:

  • "collective_decay": L = sqrt(gamma) * sum_i a_i — an equal-phase, equal-weight rank-one collective channel, not general collective (super/subradiant) decay, which requires per-pair phase and weight factors set by the target geometry (Lehmberg, Phys. Rev. A 2, 883 (1970), for the general collective-radiative-decay construction).

  • "correlated_dephasing": L = sqrt(gamma) * sum_i n_i — maximally correlated common-mode dephasing (every target shares the identical dephasing fluctuation), not general correlated dephasing with a target-dependent correlation structure (Breuer & Petruccione, The Theory of Open Quantum Systems, Oxford, 2002, Ch. 3, for the general Lindblad construction).

Always called from inside with _backend_context(chip.backend): (see quchip.engine.stage4_problem._collect_c_ops()), so this method must not open its own backend context.

Parameters:

chip (Chip)

Return type:

list[Operator]