quchip.chip.transformations.active_patch

Spectator elimination: reduce a chip to kept devices, or a schedule to its active patch.

eliminate_spectators() removes the spectators of a set of kept devices one at a time, in an order that the patch structure and the transition energies set (PHYSICS.md §10.8). active_patch() keeps the devices that a schedule touches, plus hops coupling-graph steps, and eliminates the other spectators in the same way. The activity analysis does not rank devices by amplitude, detuning, or an error bound. The results record per-step Schrieffer-Wolff validity, and a poor fold emits a UserWarning.

quchip.chip.transformations.active_patch.coupling_adjacency(chip)[source]

Device-label adjacency of the chip’s coupling graph.

quchip.chip.transformations.active_patch.active_labels(sequence, *, hops=1)[source]

Devices that the schedule touches, expanded hops coupling-graph steps.

A pulse touches its target and the device whose frame its carrier follows, such as the target qubit of a cross-resonance tone.

class quchip.chip.transformations.active_patch.SpectatorEliminationResult(chip, kept_labels, eliminated_labels, steps, notes, omitted_shifts=<factory>)[source]

Bases: _EliminationChain

A chip reduced to kept devices, and the record of each elimination.

Variables:
  • chip (Any) – The reduced chip: the kept devices plus the spectators that eliminate_spectators() did not eliminate (see notes).

  • kept_labels (tuple[str, ...]) – Kept device labels, in chip order.

  • eliminated_labels (tuple[str, ...]) – Device labels that were folded away, in elimination order.

  • steps (tuple) – The EliminationResult of each eliminate() call, verbatim and in eliminated_labels order. Read .validity and .effective_params of all steps through the properties below.

  • notes (tuple[str, ...]) – Every explicitly dropped or deferred piece of physics, including spectators left in place, each step that breaks the precedence of the default order, and every step’s notes. If elimination cannot continue past a spectator, it also includes why the reduction stopped early.

  • omitted_shifts (dict[str, float | None] | None) – For each kept device that a Schrieffer-Wolff step reaches through a device that stays on the chip, the estimated shift of its transition that the chain omits, in GHz: the sum over steps of |J|^2 / (E_k - E_v) (PHYSICS.md §10.8). The reduced transition is off by about minus this value. A value is None when the estimate does not apply, and notes says why. The attribute is None when traced device parameters prevent the estimate. An empty dict means that no step found such a path, not that the chain omits nothing: the estimate reads number-conserving exchange elements only.

chip: Any
kept_labels: tuple[str, ...]
eliminated_labels: tuple[str, ...]
steps: tuple
notes: tuple[str, ...]
omitted_shifts: dict[str, float | None] | None
class quchip.chip.transformations.active_patch.ActivePatchResult(chip, sequence, active_labels, eliminated_labels, steps, notes, omitted_shifts=<factory>)[source]

Bases: _EliminationChain

A reduced patch chip, the re-bound sequence, and the record of reduction validity.

Variables:
  • chip (Any) – The patch chip: schedule-active devices plus the spectators that active_patch() did not eliminate. They are unreachable or declined by elimination itself (see notes).

  • sequence (Any) – A QuantumSequence bound to chip, which replays the source sequence’s entries verbatim. Delays, barriers and virtual-Z entries on removed devices and stripped lines keep the source timing and have no other effect.

  • active_labels (tuple[str, ...]) – Sorted schedule-active device labels (never eliminated).

  • eliminated_labels (tuple[str, ...]) – Device labels that were folded away, in elimination order.

  • steps (tuple) – The EliminationResult from each successful eliminate() call, verbatim and in eliminated_labels order. Do not reshape them here. Read .validity/.effective_params from the step objects through the convenience properties below.

  • notes (tuple[str, ...]) – Every explicitly dropped or deferred piece of physics, including unreachable spectators left in place, control lines stripped as unused, each step that breaks the precedence of the default order, and every step’s notes. If elimination cannot continue past a spectator, it also includes why the reduction stopped early.

  • omitted_shifts (dict[str, float | None] | None) – For each active device that a Schrieffer-Wolff step reaches through a device that stays on the chip, the estimated shift of its transition that the chain omits, in GHz: the sum over steps of |J|^2 / (E_k - E_v) (PHYSICS.md §10.8). The reduced transition is off by about minus this value. A value is None when the estimate does not apply, and notes says why. The attribute is None when traced device parameters prevent the estimate. An empty dict means that no step found such a path, not that the chain omits nothing: the estimate reads number-conserving exchange elements only.

chip: Any
sequence: Any
active_labels: tuple[str, ...]
eliminated_labels: tuple[str, ...]
steps: tuple
notes: tuple[str, ...]
omitted_shifts: dict[str, float | None] | None
simulate(**kwargs)[source]

Solve the patch sequence.

Parameters:

**kwargs (Any) – Arguments forwarded to QuantumSequence.simulate().

quchip.chip.transformations.active_patch.eliminate_spectators(chip, keep, *, order=None, method='sw', local=False)[source]

Reduce a chip to the kept devices by eliminating the other devices one at a time.

Each step is one eliminate() call, so each keeps second-order terms in its own couplings. The order of the steps sets which fourth-order terms the chain keeps and, with local=True, how far the operators of the kept devices spread along the captured maps (PHYSICS.md §10.8). By default, a spectator waits while a spectator neighbour links it to a kept device that is at least two times closer to it in transition frequency than that neighbour. Among the others, a device whose neighbours are all kept goes last, and the step that keeps the widest operator of a kept device smallest goes first. A step that must break the wait is recorded in notes. The order is a heuristic for dispersive chips and does not bound the error. Each Schrieffer-Wolff step also estimates the shift that it omits from a kept device, in omitted_shifts.

Spectators that share no coupling, effective Hamiltonian or port path with the kept devices stay on the reduced chip, for the exact partitioner to split off at solve time. If eliminate declines a step with its typed NotImplementedError, the chain stops there, and everything eliminated until then stays folded.

Parameters:
  • chip (Chip) – Source chip (never mutated).

  • keep (Any) – The devices to keep, as labels or objects.

  • order (Iterable[Any] | None) – Devices to eliminate, in this order, as labels or objects. The other spectators stay on the reduced chip. The default order compares transition frequencies, so it needs concrete values. Under jax.jit or jax.grad with traced device parameters, pass the eliminated_labels of a call without tracing.

  • method (str) – Forwarded to every eliminate() call.

  • local (bool) – Forwarded to every eliminate() call. Each step then computes its generator on the patch around the eliminated device.

Return type:

SpectatorEliminationResult

Examples

>>> from quchip import Capacitive, Chip, DuffingTransmon, Resonator, eliminate_spectators
>>> q = [DuffingTransmon(freq=5.0 + 0.1 * i, anharmonicity=-0.25, levels=3, label=f"q{i}") for i in range(3)]
>>> c = [Resonator(freq=6.5 + 0.02 * i, levels=3, label=f"c{i}") for i in range(2)]
>>> chip = Chip(q + c, [Capacitive(q[i + j], c[i], g=0.03) for i in range(2) for j in range(2)])
>>> result = eliminate_spectators(chip, ["q0", "q2"], local=True)
>>> [d.label for d in result.chip.devices]
['q0', 'q2']
quchip.chip.transformations.active_patch.active_patch(sequence, *, hops=1, method='sw', local=False, order=None)[source]

Reduce a chip to its schedule-active patch by eliminating spectators.

The spectators are eliminated one at a time through eliminate(), in the default order of eliminate_spectators() with the active devices kept. The result keeps every step’s validity metrics unchanged. A kept device next to an active device, such as a coupler with hops=1, can link a removed spectator to the active device. The step then omits their exchange shift, and omitted_shifts estimates it. The reduction is an explicit opt-in, because it approximates (Schrieffer-Wolff, or the exact dressed-spectrum route under method="exact"), unlike the exact automatic partitioning that simulate() does internally at solve time.

Bridging edges from earlier folds can be Capacitive edges that carry g or TunableCapacitive edges that carry g_0. Both fold onward, so cycles among spectators reduce completely. eliminate can still decline an unsupported step, such as an unsupported accessible-field boundary, with its typed NotImplementedError. The reduction then stops there, and everything eliminated until then stays folded. The remaining spectators, including the one that failed, stay unchanged on the patch chip, and notes records the reason.

Parameters:
  • sequence (QuantumSequence) – The schedule to reduce around.

  • hops (int) – Coupling-graph hops by which the active set expands beyond the scheduled targets (see active_labels()).

  • method (str) – Forwarded to eliminate() for every device elimination.

  • local (bool) – Forwarded to eliminate(). Each step then computes its generator on the patch around the eliminated device.

  • order (Iterable[Any] | None) – Spectators to eliminate, in this order, as for eliminate_spectators(). The other spectators stay on the patch chip.

Return type:

ActivePatchResult