quchip.chip.sw

Schrieffer-Wolff reduction kernels (2nd order) on bare chip blocks.

All functions are pure, jax.numpy-only on the value path, and traced-safe: no float(), no Python branch on a traced value. H is the chip’s bare Hamiltonian in the C-order product basis, ordinary GHz; block masks are static NumPy booleans (dims are static). The caller (the elimination handlers in quchip.chip.transformations) owns cloning, folding, and control-plane concerns.

The partition eliminates one mode: P = the mode in its ground state, Q = everything else. The generator solves the Sylvester condition [S, H₀] = -V_offdiag on the P↔Q blocks, giving the standard 2nd-order effective Hamiltonian H_eff = P (H + ½[S, V]) P.

References: Bravyi, DiVincenzo & Loss, Ann. Phys. 326, 2793 (2011) (Schrieffer-Wolff); F. Yan et al., Phys. Rev. Applied 10, 054062 (2018) (tunable-coupler exchange J); Koch et al., PRA 76, 042319 (2007), §IV (dispersive shift); Krantz et al., Appl. Phys. Rev. 6, 021318 (2019), §V (Purcell decay, dispersive readout).

Functions

bare_hamiltonian(chip, backend)

Full bare Hamiltonian as a dense jnp array in GHz, with labels and dims.

bare_index(labels, dims[, excited_label])

Full bare product-basis index for the ground state, or one label's n=1 occupation.

basis_row(p_index, labels, dims[, excited_label])

Row within the P-block ordering for the ground state, or one label's n=1 occupation.

exact_reduction(chip, mode_label, ...)

Exact-from-dressing reduction: labeled dressed energies instead of perturbation theory.

exact_transform_collapse(c_full, evecs, ...)

c_eff = P U† c U P with U the labeled eigenvector matrix (dense).

extract_pair_parameters(h_eff, p_index, ...)

Read survivor parameters from the P-block matrix.

h_effective_second_order(h, s, p_mask)

H_eff = P (H + ½[S, V]) P restricted to the P block (dense, GHz).

mode_blocks(dims, labels, mode_label)

(p_mask, q_mask) boolean arrays over the product basis.

pathway_attribution(h, s, p_mask, i_idx, j_idx)

Virtual-state attribution for one H_eff matrix element.

purcell_rate_from(...)

rate = |amplitude|² · κ — the mediated decay a survivor inherits.

sylvester_generator(h, p_mask)

Generator S solving the P↔Q Sylvester condition, plus the block-gap diagnostic.

transform_collapse(c_full, s, p_mask)

c_eff = P (c + [S, c]) P — the 2nd-order jump-operator transform (dense).

quchip.chip.sw.bare_hamiltonian(chip, backend)[source]

Full bare Hamiltonian as a dense jnp array in GHz, with labels and dims.

Delegates assembly to Chip.hamiltonian() — devices plus couplings at the chip’s RWA policy, pre-2π — and converts dense once via backend.to_array. This is an analysis kernel, not a solver path; the dense conversion is the point, not a cost to avoid.

Parameters:
  • chip (Chip)

  • backend (Any)

Return type:

tuple[Any, list[str], tuple[int, …]]

quchip.chip.sw.mode_blocks(dims, labels, mode_label)[source]

(p_mask, q_mask) boolean arrays over the product basis.

P is the eliminated mode in its ground state, Q everything else. The masks are static NumPy arrays (dims are static), so they can index and slice without touching the trace.

Parameters:
Return type:

tuple[Any, Any]

quchip.chip.sw.sylvester_generator(h, p_mask)[source]

Generator S solving the P↔Q Sylvester condition, plus the block-gap diagnostic.

E = diag(H) are the bare energies and V = H diag(E); S_ij = V_ij / (E_i E_j) on the cross blocks only. The division is double-where guarded so an exactly degenerate cross pair with no matrix element between it contributes zero — with a finite gradient, not a NaN propagated backward through the unselected branch.

Returns:

(s, min_gap): the (anti-Hermitian) generator, and the smallest |E_i E_j| over cross entries carrying a nonzero V at working precision — a traced scalar, diagnostics only (jnp.inf when no cross entry couples).

Return type:

tuple

Parameters:
quchip.chip.sw.h_effective_second_order(h, s, p_mask)[source]

H_eff = P (H + ½[S, V]) P restricted to the P block (dense, GHz).

Parameters:
Return type:

Any

quchip.chip.sw.basis_row(p_index, labels, dims, excited_label=None)[source]

Row within the P-block ordering for the ground state, or one label’s n=1 occupation.

Shared basis bookkeeping between extract_pair_parameters() and any caller reading out a matching row of a separately transformed P-block operator (e.g. a collapse operator carried through transform_collapse()).

Parameters:
Return type:

int

quchip.chip.sw.bare_index(labels, dims, excited_label=None)[source]

Full bare product-basis index for the ground state, or one label’s n=1 occupation.

Parameters:
Return type:

int

quchip.chip.sw.extract_pair_parameters(h_eff, p_index, labels, dims, mode_label)[source]

Read survivor parameters from the P-block matrix. Pure indexing, no physics choices.

Returns {survivor: {"freq_after": E(1_s) E(0)}} for every survivor, plus ("J", a, b): h_eff[<1_a|, |1_b>] for every survivor pair — the effective exchange between the two single-excitation states.

Parameters:
Return type:

dict

quchip.chip.sw.transform_collapse(c_full, s, p_mask)[source]

c_eff = P (c + [S, c]) P — the 2nd-order jump-operator transform (dense).

The same rotation that block-diagonalizes H carries the jump operators into the reduced frame; truncating at first order in S matches the Hamiltonian’s 2nd-order accuracy. The projection is exact for the spectrum but approximate for dissipation — the caller records that honesty note (spec §6.2). Pass the unit jump operator and fold the rate back in via purcell_rate_from().

Parameters:
Return type:

Any

quchip.chip.sw.purcell_rate_from(c_eff_survivor_lowering_amplitude, kappa)[source]

rate = |amplitude|² · κ — the mediated decay a survivor inherits.

amplitude is the survivor-lowering matrix element of the transformed unit jump operator (dimensionless, g/Δ in the dispersive case); κ is the eliminated mode’s own rate in 1/ns, so the result is Lindblad-ready without any further unit conversion.

Parameters:
  • c_eff_survivor_lowering_amplitude (Any)

  • kappa (Any)

Return type:

Any

quchip.chip.sw.exact_reduction(chip, mode_label, survivor_labels)[source]

Exact-from-dressing reduction: labeled dressed energies instead of perturbation theory.

Diagonalizes once through the chip’s traced-safe array path and reads the reduced parameters off the labeled spectrum, so kept-block energies are exact to all orders — which is what ZZ needs. This is the des-Cloizeaux caveat in reverse: energies are exact, but the effective basis is the overlap-projected one, not the canonical SW rotation, so off-diagonal reads (J) agree with the perturbative route only through 2nd order.

Returns the same parameter shape as the perturbative extraction — {survivor: {"freq_after": E(1_s) E(0)}} and ("J", a, b) — plus ("zz", a, b) = E₁₁ E₁₀ E₀₁ + E₀₀ per survivor pair (identical convention to Chip.dispersive_shift()).

Raises:

ValueError – When two kept computational labels are assigned the same dressed state (concrete path only; under tracing the guard is skipped — labeling indices are best-effort diagnostics there, never a traced branch).

Parameters:
Return type:

dict

quchip.chip.sw.exact_transform_collapse(c_full, evecs, kept_dressed_indices)[source]

c_eff = P U† c U P with U the labeled eigenvector matrix (dense).

Rotates the jump operator into the dressed basis and keeps the rows and columns of the kept block’s assigned dressed states. Exact counterpart of transform_collapse(); the spectrum-vs-dissipation honesty note is the caller’s to record either way.

Parameters:
  • c_full (Any)

  • evecs (Any)

  • kept_dressed_indices (Any)

Return type:

Any

quchip.chip.sw.pathway_attribution(h, s, p_mask, i_idx, j_idx)[source]

Virtual-state attribution for one H_eff matrix element.

The contribution of intermediate |k⟩ to (½[S, V])_ij is ½ V_ik V_kj (1/(E_i E_k) + 1/(E_j E_k)), with the same double-where guard as the generator. Returns (k, amount) pairs for the Q-block states carrying a nonzero path at working precision; under tracing the nonzero filter cannot run, so every Q state is returned (diagnostics remain complete either way — extra entries are exact zeros).

Parameters:
Return type:

list[tuple[int, Any]]