quchip.chip.analysis

Dressed-state analysis owned by quchip.chip.chip.Chip.

ChipAnalysis diagonalizes the lab-frame static Hamiltonian, assigns bare-state labels to dressed eigenvectors by overlap maximization, and exposes derived quantities (dressed eigenenergies, transition frequencies, dispersive shifts, effective subspace Hamiltonians). All results cache against a structural signature and refresh automatically when any device or coupling parameter mutates.

Dressing is always computed in the lab frame — frame selection never alters dressed data.

References

Gambetta, J., Blais, A., Schuster, D. I., Wallraff, A., Frunzio, L.,

Majer, J., Devoret, M. H., Girvin, S. M., & Schoelkopf, R. J. Qubit-photon interactions in a cavity: Measurement-induced dephasing and number splitting. PRA 74, 042318 (2006).

Koch, J., Yu, T. M., Gambetta, J., Houck, A. A., Schuster, D. I., Majer,

J., Blais, A., Devoret, M. H., Girvin, S. M., & Schoelkopf, R. J. Charge-insensitive qubit design derived from the Cooper pair box. PRA 76, 042319 (2007).

Blais, A., Grimsmo, A. L., Girvin, S. M., & Wallraff, A. Circuit quantum

electrodynamics. Rev. Mod. Phys. 93, 025005 (2021), §IV on dispersive regime and dressed-state labeling.

Classes

ChipAnalysis(chip)

Dressed-state analysis, caching, and dressed-basis helpers.

DressedResult(eigenvalues, state_map, ...[, ...])

Store a frozen snapshot of a dressed-state diagonalization.

class quchip.chip.analysis.DressedResult(eigenvalues, state_map, dressed_eigenvalues, assignment_overlaps, hybridized_labels, bare_labels, bare_labels_by_dressed_index, eigenvector_matrix=None, overlap_threshold=0.5, labeling='DE', _eigensystem=None)[source]

Bases: object

Store a frozen snapshot of a dressed-state diagonalization.

Parameters:
eigenvalues

Sorted dressed eigenvalues in GHz.

Type:

array-like

eigenstates

Backend eigenstate objects in the same order as eigenvalues. Materialized lazily on first access from the underlying EigensystemData — the dressing / sweep hot path never touches them, so the per-column backend kets are only built when a caller actually asks for states.

Type:

array-like

state_map

Assignment from bare product-basis label (one int per device) to the dressed eigenstate index it overlaps most with.

Type:

dict[tuple[int, …], int]

dressed_eigenvalues

Dressed eigenvalue for each assigned bare label — direct lookup path for Chip.energy().

Type:

dict[tuple[int, …], Any]

assignment_overlaps

|⟨bare|dressed⟩|² of each assignment; values below overlap_threshold flag hybridization.

Type:

dict[tuple[int, …], float]

hybridized_labels

Bare labels whose assignment quality is below overlap_threshold. A non-empty tuple triggers a user warning at dress time.

Type:

tuple[tuple[int, …], …]

bare_labels

Full canonical product-basis label set (all combinations of range(device.levels) for every device, in chip order).

Type:

tuple[tuple[int, …], …]

bare_labels_by_dressed_index

Inverse of state_map — dressed index → assigned bare label.

Type:

dict[int, tuple[int, …]]

eigenvector_matrix

Columns = dressed eigenvectors in the bare product basis. Used for ChipAnalysis.operator_in_dressed_basis() and ChipAnalysis.state_components().

Type:

array-like or None

overlap_threshold

Minimum overlap for a confident assignment.

Type:

float

labeling

Algorithm id (currently only "DE"), resolved to the confidence-ordered row-greedy overlap-matching policy actually run by ChipAnalysis.dress() (assign_rowwise_greedy()).

Type:

str

eigenvalues: Any
state_map: dict[tuple[int, ...], int]
dressed_eigenvalues: dict[tuple[int, ...], Any]
assignment_overlaps: dict[tuple[int, ...], float]
hybridized_labels: tuple[tuple[int, ...], ...]
bare_labels: tuple[tuple[int, ...], ...]
bare_labels_by_dressed_index: dict[int, tuple[int, ...]]
eigenvector_matrix: Any = None
overlap_threshold: float = 0.5
labeling: str = 'DE'
property eigenstates: Any

Backend eigenstate kets, materialized lazily from the eigensystem.

class quchip.chip.analysis.ChipAnalysis(chip)[source]

Bases: object

Dressed-state analysis, caching, and dressed-basis helpers.

Every Chip owns one ChipAnalysis as chip._analysis. The chip class forwards its public dressed-state API here; users normally call methods on the chip, not this class directly.

Caching: dress() keys its cache on a structural signature covering backend identity, RWA policy, and the state_version of every device and coupling. Any mutation that bumps a version invalidates the cache on next access.

Parameters:

chip (Chip)

dress(*, overlap_threshold=0.5, force=False, labeling='DE')[source]

Diagonalize the lab-frame Hamiltonian and assign bare-state labels.

Assignment goes through the label_eigensystem kernel (quchip.chip.dressing) with assign_rowwise_greedy — confidence-ordered row-greedy matching as a pure lax.scan, O(D**2) in the Hilbert dimension versus the O(D**3) global variant. It is identical to assign_global_greedy in the dispersive / weak-hybridization regime and can differ only on strongly-hybridized chips, where the assignment is already approximate (those labels are flagged below). Bare labels whose best match is below overlap_threshold are flagged DressedResult.hybridized_labels and trigger a user warning.

DressedResult is the eager, dict-materialized view. Materialization concretizes the assignment indices and is not traceable — call energy(), freq(), dispersive_shift(), or state() from inside jax.jit/grad/vmap; those route through the array kernel directly.

Parameters:
  • overlap_threshold (float) – Confidence cutoff for the greedy assignment.

  • force (bool) – Force recomputation even if the signature matches.

  • labeling (str) – Currently only "DE" is implemented.

Returns:

Cached result — mutate at the caller’s own risk.

Return type:

DressedResult

property is_dressed: bool

True if a cached dressed result is present and consistent.

energy(device_states=None, /, **device_state_kwargs)[source]

Dressed eigenvalue (GHz) for the given bare-state label.

Unspecified devices default to Fock index 0. Routes through the quchip.chip.dressing.label_eigensystem() array kernel, so this is safe inside jax.jit/grad/vmap — gradients flow through eigenvalues[labeling.indices[bare_idx]] to any traced chip parameters.

Parameters:
Return type:

Any

dressed_spectrum()[source]

Raw sorted eigenvalue array of the dressed Hamiltonian (GHz).

Return type:

Any

dressed_index(device_states=None, /, **device_state_kwargs)[source]

Dressed-state index assigned to a bare label, or None if unassigned.

Parameters:
Return type:

int | None

bare_label(dressed_index)[source]

Bare-state label assigned to a dressed-state index.

Parameters:

dressed_index (int)

Return type:

tuple[int, …]

operator_in_dressed_basis(device, op, *, truncate=None)[source]

Transform a local operator into the dressed eigenbasis.

Computes U† O_embedded U where U is the dressed eigenvector matrix (columns are dressed eigenstates in the bare product basis), phase-fixed to the assigned bare-state convention used by drive_matrix_elements(). Optional truncation keeps the lowest truncate dressed levels.

Parameters:
  • device (str or BaseDevice) – Device whose local operator is embedded and transformed.

  • op (str or Operator) – Operator name resolved off the device (e.g. "n", "a") or an already-built local-space operator.

  • truncate (int, optional) – Keep only the lowest truncate dressed levels of the result.

Return type:

Any

drive_matrix_elements(transition, *, drives=None)[source]

Return dressed matrix elements of wired drive operators.

The matrix convention is m_j^{fi} = <f~|D_j|i~>: the final dressed state is the row index and the initial dressed state is the column index. Each dressed eigenvector is phase-fixed so that its overlap with the assigned bare state is real and nonnegative. This makes relative matrix elements between different conditioned transitions independent of the backend’s eigenvector phases. Passing a device selects the dressed ground-to-first-excitation transition of that device with every other device in its ground state. Passing (initial, final) mappings selects an arbitrary transition.

Each drive must expose exactly one local Hamiltonian channel. The signal chain is not applied: this method returns the physical matrix element of each control line’s drive operator, which can then be combined with declared signal-chain phasors. This is the weak-drive projection used for effective driven-Hamiltonian coefficients; see Magesan and Gambetta, Phys. Rev. A 101, 052308 (2020), DOI 10.1103/PhysRevA.101.052308.

Parameters:
  • transition (str, BaseDevice, or tuple[mapping, mapping]) – Device shorthand, or (initial, final) bare-state mappings. Unspecified devices in either mapping default to level zero.

  • drives (sequence[str or BaseDrive], optional) – Wired control lines to evaluate. None evaluates every line. Original or rebound drive objects resolve by label.

Returns:

Drive-label mapping of backend-native scalar matrix elements. Values remain JAX-traceable on a JAX-capable backend; each entry is addressable by the drive object or its label.

Return type:

LabelKeyedDict

Raises:
  • ValueError – If no control equipment is attached, a selected line is not a device-target drive, or a drive exposes zero or multiple channels.

  • KeyError – If a requested drive label is absent from the attached equipment.

  • TypeError – If transition is neither a device reference nor a pair of state mappings.

Examples

>>> from quchip import Chip, ChargeDrive, ControlEquipment, DuffingTransmon
>>> q = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="q")
>>> drive = ChargeDrive(q, label="xy")
>>> chip = Chip([q], control_equipment=ControlEquipment([drive]))
>>> elements = chip.drive_matrix_elements(q, drives=[drive])
>>> abs(elements["xy"]) > 0
True
state_components(state=None, /, *, n_components=5, **device_state_kwargs)[source]

Leading bare-basis probabilities |⟨bare|dressed⟩|² of a dressed eigenstate.

state may be an int (direct dressed index) or a mapping of {device: Fock} (dressed index resolved via label matching).

Parameters:
Return type:

dict[tuple[int, …], float]

dispersive_shift(device_a, device_b)[source]

Dressed cross-Kerr shift (GHz): E(1,1) E(1,0) E(0,1) + E(0,0).

Equivalent to the static ZZ interaction strength between the two devices with all others grounded. See Blais et al., RMP 93, 025005 (2021), §IV.C.

Parameters:
  • device_a (str or BaseDevice) – The two devices whose cross-Kerr shift is evaluated.

  • device_b (str or BaseDevice) – The two devices whose cross-Kerr shift is evaluated.

Return type:

float

Examples

>>> from quchip import DuffingTransmon, Capacitive, Chip
>>> q0 = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="q0")
>>> q1 = DuffingTransmon(freq=5.2, anharmonicity=-0.22, levels=3, label="q1")
>>> chip = Chip([q0, q1], couplings=[Capacitive(q0, q1, g=0.02)])
>>> zz = chip.dispersive_shift(q0, q1)  # residual ZZ in GHz
effective_subspace_hamiltonian(states)[source]

Effective Hamiltonian projected onto a labeled bare subspace.

Returns a Hermitian matrix in the user-chosen bare-state basis whose eigenvalues are exactly the dressed eigenenergies of the listed bare-label states. The truncated overlap block is Löwdin (S^{-1/2}) orthonormalized — the same des-Cloizeaux construction as quchip.analysis.effective_hamiltonian() — so hybridization with states outside the subspace cannot leak absolute dressed energies into the off-diagonal elements. Bridges full-chip dressed physics to the kind of low-dimensional effective model used in dispersive gate design and state-transfer analysis.

Parameters:

states (sequence of mapping or tuple[int, ...]) – The bare-state labels spanning the subspace, each a {device: Fock} mapping or a full chip-ordered index tuple.

Return type:

ndarray

dressed_anharmonicity(device)[source]

Dressed anharmonicity (GHz): E_2 2·E_1 + E_0, others grounded.

Parameters:

device (str | BaseDevice)

Return type:

float

freq(target=None, when=None)[source]

All dressed 0→1 frequencies (GHz), or one conditional transition.

Parameters:
  • target (str or BaseDevice, optional) – Device whose 0→1 transition is returned. None returns the full {device_label: frequency} dict for every device.

  • when (dict[str | BaseDevice, int], optional) – Spectator Fock indices held fixed while the transition is evaluated; unlisted devices stay in their ground state.

Return type:

dict[str, Any] | Any

frame_info()[source]

Per-device frame reference frequency ω_ref,i (GHz).

Resolves the chip’s current frame spec through the same path the engine uses (quchip.engine.stage1_frames.resolve_frame()) and returns a flat {device_label: ω_ref,i} dict. These are the concrete frequencies the assembler will subtract as -Σ_i ω_ref,i n̂_i in stage2_assembly._build_static_h0(), so it exposes what will be solved without running the solver.

Values are returned as produced by the frame resolver: concrete Python floats in "lab", "rotating", or scalar modes, and potentially JAX tracers in dict mode when the user wired a traced reference frequency through. Traced values are passed through unchanged to preserve differentiability.

Return type:

dict[str, Any]

state(device_states=None, /, **device_state_kwargs)[source]

Dressed eigenstate for Fock-indexed bare-state labels.

Validates the mapping (rejects bool, non-int, and out-of-range indices) and returns the assigned dressed eigenvector. A str shorthand (e.g. "eg1") is parsed through normalize_device_state_mapping() when Chip.set_state_order() has been called. Use Chip.bare_state() for arbitrary kets.

Safe inside jax.jit/grad/vmap: under tracing the eigenvector column is selected through the array kernel, so a dressed initial state is differentiable end-to-end.

Parameters:
Return type:

Any