quchip.chip.chip

Composite quantum system: Chip holds devices, couplings, and control.

A chip owns the devices and the couplings between them. Each device owns its local Hamiltonian, and each coupling owns its two-body interaction Hamiltonian. The chip can also own the ControlEquipment that wires the classical control lines. The engine turns a chip into a solver-ready problem.

All public parameters, including device frequencies, coupling strengths, drive amplitudes, and crosstalk coefficients, stay JAX-traceable and sweepable, so a single loss function can span any of them.

Classes

Chip(devices[, couplings, ...])

Composite quantum system: devices + couplings + (optional) control.

class quchip.chip.chip.Chip(devices, couplings=None, control_equipment=None, label=None, frame='lab', approximation=RWA(keep_bands=None), basis='native', backend=None, baths=None, port_network=None, effective_terms=(), space=None)[source]

Bases: object

Composite quantum system: devices + couplings + (optional) control.

Device arguments accept an object or its label. The ordered device list fixes tensor-product positions.

Parameters:
  • devices (list[BaseDevice]) – The tensor-product position equals the list index. Labels must be unique.

  • couplings (list[BaseCoupling], optional) – Two-body couplings. Every device a coupling refers to must be in devices.

  • control_equipment (ControlEquipment, optional) – Holds the drive lines and the signal-chain transforms (crosstalk, delays, gains). You can also attach it later with wire() or connect().

  • label (str, optional) – Human-readable chip label.

  • frame (FrameSpec) –

    Initial frame specification:

    • "lab": all reference frequencies are 0 GHz (default).

    • "rotating": a per-device rotating frame at the dressed drive frequencies.

    • "auto": per-device frequencies that quchip chooses from retained couplings, cascade-generated network couplings, delivered drive tones, and scattering-scaled coherent-input tones.

    • scalar-like: one shared reference frequency for all devices.

    • dict: per-device references keyed by label or device.

  • approximation (Approximation) – Strategy for dressed analysis and solver assembly. The default is RWA. To keep every band, use Exact().

  • basis ({"native", "eigen"}) – Chip-wide policy for the local solver basis. "native" keeps each device’s authored coordinate basis. "eigen" transforms into each device’s retained local energy subspace. A device-level basis overrides this policy.

  • backend (str or Backend, optional) – Chip-specific backend. None uses the process default.

  • baths (list[Bath], optional) – Shared or collective unobserved environments.

  • port_network (PortNetwork, optional) – Complete accessible field boundary. Attach at most one network.

  • effective_terms (sequence[EffectiveTerms]) – Captured contributions that a reduction made. The engine keeps their retained operator bands when it applies the selected frame.

  • space (ExcitationCutoff or None, default=None) – Retained product energy labels. None keeps the full product space, with exact excitation reductions where quchip proves them. ExcitationCutoff keeps the labels with total excitation N <= max_total for dressed analysis and deterministic pulse solves. See with_space().

Examples

>>> from quchip import DuffingTransmon, Resonator, Capacitive, Chip
>>> q = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="q")
>>> r = Resonator(freq=7.0, levels=5, label="r")
>>> chip = Chip([q, r], couplings=[Capacitive(q, r, g=0.05)])
>>> chip.energy({q: 1})  # dressed |1,0⟩ eigenvalue, GHz
unresolved_hamiltonian()[source]

Return the authored lab-frame static Hamiltonian.

This method embeds every device Hamiltonian into the full tensor space and adds each embedded coupling interaction. It does not apply the rotating-frame transform or any drive envelopes.

The result is exact, because only the engine applies the RWA and the frame transformations. At solve time, the engine subtracts 2π Σ_i ω_ref,i n̂_i for each device, where ω_ref,i is the frame reference resolved by quchip.engine.frames.resolve_frame(). To see each device’s reference frequency, use frame_info().

Returns:

Symbolic Hamiltonian on ⨂_d H_d. For a dense numerical view with the current bindings, call .matrix().

Return type:

PhysicsExpr

hamiltonian()[source]

Return the Hamiltonian after the chip’s engine policies.

resolve(*, frame=None, approximation=None)[source]

Return a frozen engine contract without mutating chip intent.

frame=None uses frame. An explicit frame resolves only this snapshot. approximation=None uses the chip default. Neither override mutates chip intent.

Parameters:
  • frame (FrameSpec or None, default=None) – Snapshot frame, or None to use frame.

  • approximation (Approximation or None, default=None) – Snapshot approximation, or None to use approximation.

dynamic_contributions()[source]

Return the time-dependent Hamiltonian contributions that the chip owns, with their support.

Returns (local_op, time_dependence, support, owner, origin, tag) tuples. A device-local operator has one support index, and a coupling’s two-body operator has two. Operators are in the lab frame and in ordinary GHz, and the engine applies the 2π boundary. Drive terms are not included, because the schedule owns them.

collapse_contributions(bases=None)[source]

Return every Lindblad collapse operator on the chip, with its support.

Returns (operator, rate, support, source, channel, parameter_paths) tuples. An operator local to a device or a drive line has one device index, and a coupling’s two-body operator has two. An operator already embedded in the full space (baths) has an empty tuple. Rates are in 1/ns and are ready for the Lindblad equation. Each component owns its rate physics, including any intrinsic 2π (for example, κ = 2π·f/Q for a resonator).

Every returned operator is authored locally, and the engine transforms it into the same fixed local solver bases as the Hamiltonian. This is the standard local-Lindblad approximation (Breuer & Petruccione, The Theory of Open Quantum Systems, Oxford, 2002, Ch. 3). It is not a dressed-basis (polaron-frame) master equation. It applies to the full chip, independent of which components have noise. See the "chip" entry of physics_notes().

Parameters:

bases (mapping or None, default=None) – Captured basis records, or None to resolve them.

property effective_terms: tuple[EffectiveTerms, ...]

Captured Hamiltonian and loss contributions that are retained.

property device_map: dict[str, BaseDevice]

Label → device mapping (the chip’s own dict, do not mutate it).

property coupling_map: dict[str, BaseCoupling]

Couplings by label, in insertion order (do not mutate them).

coupling(coupling)[source]

Return a coupling by label or object.

Parameters:

coupling (str or BaseCoupling) – Coupling label or object.

property backend: Backend

per-call override, then chip-specific backend, then process default.

The per-call override is the backend= argument of simulate() / simulate_batch. The override has priority over a backend that the chip constructor set. So one chip can run, e.g., QuTiP sweeps and dynamiqs gradient solves without changing global state.

Type:

Active backend

property frame: FrameSpec

Current frame specification (see set_frame()).

property approximation: Approximation

Approximation for the dressed analysis and the default solver assembly.

property space: ExcitationCutoff | None

Retained-space policy, or None for the full product space (see with_space()).

with_space(space)[source]

Return an isolated copy that keeps the product labels selected by space.

The policy applies to dressed analysis, resolve(), deterministic pulse solves, steadystate() and the stationary VNA workflows finite_power(), measure(), output_spectrum(), g1() and g2(). Workflows that do not support a cutoff raise, e.g. VNA.sweep(), stochastic trajectories, partitions and eliminations. The copy keeps the policy through cloning, parameter rebinding and serialization. quchip never changes it automatically.

Parameters:

space (ExcitationCutoff or None) – Policy of the copy. None restores the full product space.

Examples

>>> from quchip import Chip, DuffingTransmon, ExcitationCutoff
>>> q = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=4, label="q")
>>> limited = Chip([q]).with_space(ExcitationCutoff(max_total=2))
>>> limited.space
ExcitationCutoff(max_total=2)
>>> limited.with_space(None).space is None
True
property control_equipment: ControlEquipment | None

Attached control equipment, if any.

property devices: tuple[BaseDevice, ...]

Ordered tuple of devices; index matches tensor-product position.

property couplings: tuple[BaseCoupling, ...]

Tuple of couplings in insertion order.

property dims: tuple[int, ...]

Per-device Hilbert-space dimensions (same order as devices).

property authored_dims: tuple[int, ...]

Per-device dimensions of the exact authored local spaces.

property basis: Literal['native', 'eigen']

Chip-wide policy for the local solver basis that devices inherit.

resolve_basis(device)[source]

Resolve a device override against the chip basis policy.

Parameters:

device (str or BaseDevice) – Device label or object.

property total_dim: int

Total Hilbert-space dimension (product of per-device dims).

property baths: tuple[Bath, ...]

Chip-level baths (shared or collective dissipation), in insertion order.

property ports: tuple[Port, ...]

Accessible Markovian input-output channels, in declaration order.

property port_network: PortNetwork | None

Return the attached accessible field boundary, if any.

port(port)[source]

Return one declared port by object or label.

Parameters:

port (str or Port) – Port label or object.

connect_network(network)[source]

Attach the chip’s one complete accessible field boundary.

Parameters:

network (PortNetwork) – Network whose ports target this chip.

disconnect_network()[source]

Detach and return the accessible field boundary.

add_bath(bath)[source]

Attach a bath to this chip and return it (for fluent use).

Parameters:

bath (Bath) – Shared or collective dissipation model that targets this chip.

Notes

You can add baths at any time after construction. The next simulate or solve call collects the bath’s collapse operators without a chip rebuild. The bath is validated immediately, so bad input fails here, not at solve time with an unclear error. Bad input is a non-Bath argument, a target label not on this chip, or a label that collides with an attached bath.

set_noise(config=None, *, baths=None)[source]

Replace this chip’s entire noise description in one call.

Omitted device noise fields reset to None. An omitted baths clears all baths. The complete target state is validated before any write. Declare custom noise rates with parameter(noise=True) and implement them in dissipation(), so they stay sweepable, differentiable, and serializable. It prints the applied changes, and a repeated identical call is a silent no-op.

Parameters:
  • config (mapping, optional) – {device_or_label: {noise_param: value}}. Devices can appear as objects or labels, once each. Non-noise parameters are rejected.

  • baths (list[Bath], optional) – The chip’s complete new bath list (validated like add_bath()).

property crosstalks: list[Crosstalk]

Convenience view of the Crosstalk entries from the signal chain.

device_index(label)[source]

Return a device’s tensor-product index.

Parameters:

label (str or BaseDevice) – Device label or object.

plot_graph(path='chip_topology.html', *, full=True, exclude=None, values='bare', **kwargs)[source]

Render the chip topology through quchip.viz.chip.

Parameters:
  • path (str, default="chip_topology.html") – Output HTML path.

  • full (bool, default=True) – Include the complete topology view.

  • exclude (set[str] or None, default=None) – Labels omitted from the rendering.

  • values (str, default="bare") – Parameter-value view forwarded to the renderer.

  • **kwargs (Any) – Additional renderer options.

plot_energy_levels(*, ax=None, **kwargs)[source]

Render the dressed spectrum through quchip.viz.chip.

Parameters:
  • ax (object or None, default=None) – Matplotlib axes. None creates axes.

  • **kwargs (Any) – Additional renderer options.

set_frame(frame)[source]

Set the frame that the simulation inputs use.

Supported values:

  • "lab": all reference frequencies are 0.0 GHz.

  • "rotating": per-device references use the dressed drive frequencies.

  • "auto": quchip plans per-device frequencies from retained couplings, cascade-generated network couplings, delivered drive tones, and scattering-scaled coherent-input tones.

  • scalar-like: a shared reference frequency for all devices.

  • dict: per-device references keyed by label or device.

Frame changes never change dressed-state data, because quchip always calculates the dressing from the lab-frame static Hamiltonian.

Parameters:

frame ({"lab", "rotating", "auto"}, scalar-like, or mapping) – Frame specification. Frequencies are in GHz.

property analysis: ChipAnalysis

Dressed-state analysis namespace, i.e. the chip’s ChipAnalysis.

Canonical entry point for the full dressed-analysis surface (for advanced users and less common methods). Flat chip.* forwarders to this namespace give the common quantities, e.g. energy(), freq(), dress(), dispersive_shift(), … For all other quantities, use chip.analysis.

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

Diagonalize the static lab-frame Hamiltonian under the chip’s approximation.

The Hamiltonian keeps the declared truncation of each device and the Hamiltonian terms of the port network. Under RWA() it has no counter-rotating terms.

Parameters:
  • overlap_threshold (float, default=0.5) – Minimum bare-state overlap used for labels.

  • force (bool, default=False) – Recalculate even when a valid result is cached.

  • labeling ({"DE"}, default="DE") – Confidence-ordered row-greedy overlap assignment.

property is_dressed: bool

True if a valid dressed-state result is cached. See ChipAnalysis.is_dressed.

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

Return the dressed eigenenergy in GHz for a bare-state label.

Parameters:
  • device_states (mapping, optional) – Device labels or objects mapped to levels.

  • **device_state_kwargs (int) – Device-label keyword levels.

dressed_spectrum()[source]

Return raw dressed eigenvalues without Python scalar coercion. See ChipAnalysis.dressed_spectrum().

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

Return the matching dressed index, or None.

Parameters:
  • device_states (mapping, optional) – Device labels or objects mapped to levels.

  • **device_state_kwargs (int) – Device-label keyword levels.

bare_label(dressed_index)[source]

Return the bare-state label assigned to a dressed index.

Parameters:

dressed_index (int) – Dressed eigenstate index.

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

Return an embedded device operator transformed to the dressed eigenbasis.

See ChipAnalysis.operator_in_dressed_basis() for the owner contract.

Parameters:
  • device (str or BaseDevice) – Device that owns the local operator.

  • op (str or array-like) – Named or explicit local operator.

  • truncate (int, optional) – Keep only the lowest dressed states.

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

Return <final~|D_j|initial~> for wired drive lines.

Rows index the final dressed state and columns the initial dressed state. In the weak-drive projection, these matrix elements set the coefficients of the effective driven Hamiltonian. See E. Magesan and J. M. Gambetta, Phys. Rev. A 101, 052308 (2020), DOI 10.1103/PhysRevA.101.052308, and ChipAnalysis.drive_matrix_elements() for the owner contract.

Parameters:
  • transition (str, BaseDevice, or pair of mappings) – Transition shorthand or explicit lower/upper bare labels.

  • drives (sequence, optional) – Drive labels or objects to include. The default is all wired drives.

rotation_amplitude(transition, line, envelope, angle=3.141592653589793)[source]

Return a first-guess amplitude that rotates a dressed transition by angle.

The amplitude solves θ = 2π |m| |A a| for the dressed matrix element m of the line and the envelope area A a at amplitude A. See ChipAnalysis.rotation_amplitude() for its limits; the value is a starting point for a calibration.

Parameters:
  • transition (str, BaseDevice, or pair of mappings) – Transition shorthand or explicit lower/upper bare labels.

  • line (str or BaseDrive) – Wired device-target line without signal-chain transforms.

  • envelope (Envelope) – Pulse shape with an amplitude field.

  • angle (scalar, default=pi) – Rotation angle in rad.

state_components(state=None, /, *, n_components=5, **device_state_kwargs)[source]

Return leading bare-basis probabilities for a dressed eigenstate.

Parameters:
  • state (int or mapping, optional) – Dressed index or bare-state label.

  • n_components (int, default=5) – Number of largest components to return.

  • **device_state_kwargs (int) – Device-label keyword levels.

dispersive_shift(device_a, device_b)[source]

Return the dressed cross-Kerr shift (GHz): E(1,1) − E(1,0) − E(0,1) + E(0,0).

Parameters:
  • device_a (str or BaseDevice) – Devices whose dressed cross-Kerr shift is requested.

  • device_b (str or BaseDevice) – Devices whose dressed cross-Kerr shift is requested.

static_zz(device_a, device_b)

Return the dressed cross-Kerr shift (GHz): E(1,1) − E(1,0) − E(0,1) + E(0,0).

Parameters:
  • device_a (str or BaseDevice) – Devices whose dressed cross-Kerr shift is requested.

  • device_b (str or BaseDevice) – Devices whose dressed cross-Kerr shift is requested.

zz(device_a, device_b)

Return the dressed cross-Kerr shift (GHz): E(1,1) − E(1,0) − E(0,1) + E(0,0).

Parameters:
  • device_a (str or BaseDevice) – Devices whose dressed cross-Kerr shift is requested.

  • device_b (str or BaseDevice) – Devices whose dressed cross-Kerr shift is requested.

excitation_structure()[source]

Return the excitation-number structure of the static model.

The record shows whether the static model conserves the total excitation number, which terms break it, and the block size that dressed queries diagonalize. See ChipAnalysis.excitation_structure().

kerr_matrix()[source]

Return the labeled dressed self-Kerr and cross-Kerr matrix in GHz.

See ChipAnalysis.kerr_matrix().

dressed_anharmonicity(device)[source]

Return the dressed anharmonicity of one device with the other devices grounded (GHz).

See ChipAnalysis.dressed_anharmonicity().

Parameters:

device (str or BaseDevice) – Device label or object.

transition_frequency(target, lower, upper, when=None)[source]

Return a dressed transition in GHz with optional spectator levels.

Parameters:
  • target (str or BaseDevice) – Device whose transition is requested.

  • lower (int) – Lower and upper local levels.

  • upper (int) – Lower and upper local levels.

  • when (mapping, optional) – Spectator device levels.

  • and (Unspecified spectators are in their ground state. target)

  • labels. (entries in when accept either device objects or)

effective_subspace_hamiltonian(states)[source]

Return the dressed effective Hamiltonian in a labeled bare subspace.

See ChipAnalysis.effective_subspace_hamiltonian().

Parameters:

states (sequence of mappings or level tuples) – Bare labels spanning the requested subspace.

freq(target: None = None, when: dict[str | BaseDevice, int] | None = None) → dict[str, float][source]
freq(target: str | BaseDevice, when: dict[str | BaseDevice, int] | None = None) → float

Return the dressed 0→1 frequencies in GHz, optionally conditioned on spectators.

Parameters:
  • target (str or BaseDevice, optional) – Device label or object. If you omit it, the method returns all frequencies.

  • when (mapping, optional) – Spectator device levels.

  • Overloaded (no target returns the full {label: freq} dict;)

  • 0→1 (a single target (label or device) returns one scalar)

  • the (frequency. Under jax.jit the scalar is a traced 0-d array;)

  • traceability. (overload is type-only and preserves)

frame_info()[source]

Return the per-device frame reference frequency ω_ref,i (GHz). See ChipAnalysis.frame_info().

physics_notes()[source]

Collect physics_notes() from every component.

Returns a dict with the key "chip" for the chip-level entry. Each component has the key "<kind>:<label>", where kind is one of "device", "coupling", "drive", "bath", "port", "network", "effective". Each key maps to that component’s declared approximations: Hilbert truncation, model regime, RWA status, noise-channel selection, and any other non-obvious assumption it explicitly declares.

Keys are kind-qualified, not bare labels, because the label namespaces are not globally disjoint. A device, coupling, drive, and bath can share a label, and on this audit surface one component’s entry must not silently overwrite another’s. Drives are enumerated from the control_equipment wiring, not from per-device connected_drives, so an edge-target ParametricDrive (that pumps a coupling, not a device) is included.

The chip-level "chip" entry states the local-Lindblad approximation, under which this chip builds every collapse operator (see collapse_contributions()). The entry is present even without baths, because it always applies. The dict is for inspection and audit, not for runtime dispatch.

to_dict()[source]

Serialize chip topology into a JSON-safe dictionary.

classmethod from_dict(d)[source]

Reconstruct a chip from to_dict() output.

Parameters:

d (dict[str, Any]) – Serialized chip payload.

clone()[source]

Return an isolated structural clone for sweep evaluation.

property parameters: Mapping[str, Any]

Bindable numerical values keyed by stable component paths.

property settings: Mapping[str, Any]

Read-only structural choices that are not numerical fit parameters.

with_params(bindings)[source]

Return an isolated structural copy with values rebound.

Parameters:

bindings (mapping[str, Any]) – Fully qualified parameter paths and replacement values.

partition()[source]

Split the chip into independent sub-chips along the independence graph.

Connectivity comes from multi-device operator support in the resolved Hamiltonian and Lindblad channels, including Hamiltonian terms generated by SLH composition. Passive field scattering alone does not connect subsystems. Drive-crosstalk pairs stay together, so component solves keep their signal transform. The devices that a captured reduction map acts on also stay together, because the map can mix them. An active excitation cutoff couples every device through its global budget, so this method raises for it.

status()[source]

Print a short diagnostic dashboard for the chip.

from_array(data, device=None)[source]

Build a backend operator from a raw NumPy array.

With device, the array is a local operator on that device’s subspace and is embedded into the full tensor-product space. With device=None the array must already span the full chip Hilbert space.

Parameters:
  • data (array-like) – Local or full-space operator array.

  • device (str, BaseDevice, or None, default=None) – Owner of the local operator. None treats data as full-space.

observable(device, op)[source]

Embed a device operator onto the full chip Hilbert space.

Accepts a prebuilt local-space operator or one of the names "X", "Y", "Z", "n", "a", "a_dag", and "I". Returns the operator embedded on the chip’s tensor-product space.

Use it for manual construction and analysis of full-space operators, not as a solver e_op. For solver expectation values, use e_ops(), which keeps operators local so the demodulation pipeline can band-decompose and embed them correctly.

Parameters:
  • device (str or BaseDevice) – Device whose local space owns the operator.

  • op (str or array-like) – Named or explicit local operator.

e_ops(*, correlators=None, **specs)[source]

Build a dict-form e_ops mapping for the solver pipeline.

Each keyword maps a device label to an operator specification: a name string, a list of names, a raw local-space operator, or a mixed list of strings and operators. Specify two-device correlators (for example ⟨Z₁⊗Z₂⟩) with correlators as device-label pairs → operator pairs. Returns local-space operators (not embedded), which the demodulation pipeline embeds as needed.

Parameters:
  • correlators (dict or None, default=None) – Device-pair keys mapped to pairs of local operator specifications.

  • **specs (str, list, or array-like) – Device labels mapped to local operator specifications.

Examples

>>> from quchip import DuffingTransmon, Capacitive, Chip
>>> q1 = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="q1")
>>> q2 = DuffingTransmon(freq=5.2, anharmonicity=-0.22, levels=3, label="q2")
>>> chip = Chip([q1, q2], couplings=[Capacitive(q1, q2, g=0.02)])
>>> e = chip.e_ops(
...     q1=["X", "Y", "Z"], q2=["X", "Y", "Z"],
...     correlators={("q1", "q2"): ("Z", "Z")},
... )
set_state_order(*devices, levels=None)[source]

Declare the device order used to parse string-state shorthands.

After this call, bare_state(), state(), and superposition() accept single-string specifications. Each character gives one device’s level, in devices order. The default level symbols are g=0, e=1, f=2, h=3. The methods always accept digits 0..9 as energy-level indices.

Name every chip device exactly once.

Parameters:
  • *devices (str or BaseDevice) – All chip devices in shorthand order.

  • levels (mapping[str, int] or None, default=None) – Extra one-character level symbols and their indices.

Examples

>>> from quchip import DuffingTransmon, Resonator, Chip
>>> qb = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="qb")
>>> tc = DuffingTransmon(freq=5.5, anharmonicity=-0.20, levels=3, label="tc")
>>> cr = Resonator(freq=7.0, levels=4, label="cr")
>>> chip = Chip([qb, tc, cr])
>>> chip.set_state_order(qb, tc, cr)
>>> _ = chip.bare_state("eg1")  # {qb: 1, tc: 0, cr: 1}
superposition(*components)[source]

Return a normalized superposition of the dressed states of level labels.

Each component is a level label or an (amplitude, label) tuple for weighted mixing. A label is a dict keyed by device or label, or a string if you called set_state_order() before, and names the dressed state that state() returns. Weights default to uniform, and results are normalized to unit norm. bare_state() takes the same components for a superposition of bare product states.

Parameters:

*components (mapping, str, or tuple) – Level labels, optionally paired with amplitudes.

Examples

>>> import numpy as np
>>> from quchip import DuffingTransmon, Resonator, Chip
>>> qb = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="qb")
>>> cr = Resonator(freq=7.0, levels=4, label="cr")
>>> chip = Chip([qb, cr])
>>> _ = chip.superposition({qb: 0}, {qb: 1})  # equal |00> + |10>
>>> _ = chip.superposition(                   # weighted mix
...     (np.sqrt(0.3), {qb: 1, cr: 0}),
...     (np.sqrt(0.7), {qb: 1, cr: 1}),
... )
state(device_states=None, /, **device_state_kwargs)[source]

Return the dressed eigenstate assigned from the given product-state level labels.

Accepts a string shorthand (for example "eg1") if you called set_state_order() before.

A level label names this state wherever quchip takes one: as the initial_state of a solve, as a target of overlap() and amplitude_array(), and in superposition() and compact_state(). A solve takes the state under its own approximation and excitation cutoff, and places it in its frame at tlist[0]. bare_state() gives the bare product state.

If the requested label’s assignment overlap is low, this method warns and names bare_state() as the product-state alternative.

This method is safe in jax.jit/grad/vmap. Under tracing, the label_eigensystem() array kernel selects the assigned eigenvector column, so dressed initial states are differentiable end-to-end. The state’s amplitude on its assigned product state is real and nonnegative (see gauge_phases()), so a nondegenerate state vector, not only its populations, is the same on each backend. On a chip whose static model conserves the total energy-level index, the method diagonalizes only the sector of the label.

Parameters:
  • device_states (mapping, str, or None, default=None) – Product-state level labels used for dressed assignment.

  • **device_state_kwargs (int) – Per-device energy levels keyed by label.

compact_state(*components, dressed=True)[source]

Prepare a reusable state without a full product-space allocation.

Parameters:
  • *components (mapping, str, or (amplitude, specification) pairs) – Energy-level labels, using the same strings and mappings as superposition. Unmentioned devices have level zero. Components are summed and normalized. No components prepares the vacuum.

  • dressed (bool, default=True) – Use the static dressed eigenstate assigned to each label. This requires proven static excitation conservation or an excitation cutoff. False uses the bare product of each label, and a mapping can then also give a device a local ket, as in bare_state.

Returns:

Captured state accepted as a pulse simulation’s initial_state.

Return type:

CompactState

bare_state(*components, **device_state_kwargs)[source]

Return a product state, or a superposition of product states, from energy levels or local kets.

Specify each device as an energy-level index (int) or as a ket vector in that device’s authored local space. Unspecified devices use the ground state (level 0). Unlike state(), this method does not diagonalize the coupled system.

One mapping or string, keywords, or both give one product state. Several components, or (amplitude, specification) pairs, give the normalized superposition of their products, as superposition() combines dressed states. Accepts a string shorthand (for example "eg1") if you called set_state_order() before.

Inside jax.jit, a state that depends on no traced value stays a constant, so a solve keeps the excitation sectors of its levels. A level of a device that solves in its native basis, such as Fluxonium(basis="native"), depends on that device’s traced parameters, and a solve then uses the full product space. compact_state(..., dressed=False) keeps the sectors in every case.

Parameters:
  • *components (mapping, str, or (amplitude, specification) pairs) – Per-device levels or local kets. Omitted devices use level zero.

  • **device_state_kwargs (int or State) – Per-device levels or local kets keyed by label, for one product state.

wire(*lines, signal_chain=None)[source]

Attach or replace classical control wiring.

Preferred user-facing API to attach control to a chip. If you omit lines, the method reuses the connected lines and replaces only the signal chain.

Parameters:
  • *lines (BaseDrive) – Classical control lines to attach.

  • signal_chain (sequence of SignalTransform or None, default=None) – Ordered classical signal transforms.

Examples

>>> # chip.wire(drive_q, drive_r, signal_chain=[Crosstalk(drive_q, drive_r, c=0.05)])
unwire(line)[source]

Remove one control line and every signal-chain transform that refers to it.

The inverse of wire() for a single line. Accepts the drive object or its label. Returns the removed drive, so you can rewire it later. Removing the last line fully detaches the equipment (control_equipment becomes None).

Parameters:

line (BaseDrive or str) – Drive object or label to remove.

connect(control_equipment)[source]

Attach control equipment to this chip (low-level API).

Validates every drive target, rejects duplicate drive labels, and reconnects each drive to this chip’s canonical device or coupling instance. User-facing code should use wire().

Parameters:

control_equipment (ControlEquipment) – Complete classical control wiring to attach.

disconnect()[source]

Fully detach the control equipment (low-level API).

The inverse of connect()/wire(). Removes all lines and the signal chain at once (control_equipment becomes None). Returns the detached equipment, so you can reconnect it later.

Returns:

The previously attached equipment.

Return type:

ControlEquipment

solve(problem)[source]

Solve a typed SolveProblem through this chip’s backend.

Call quchip.check_truncation() to inspect saved boundary samples.

Parameters:

problem (SolveProblem) – Prepared problem built for this chip.

solve_many(batch_or_problems, *, progress=True, max_workers=None)[source]

Solve a SolveBatch or list of problems.

Chip-level validation checks only what uses self (every input was built for this chip).

Parameters:
  • batch_or_problems (SolveBatch or sequence of SolveProblem) – Batch or prepared problems built for this chip.

  • progress (bool, default=True) – Show backend progress where supported.

  • max_workers (int or None, default=None) – Worker processes for a backend that solves points in parallel, such as QuTiP. None takes the CPU count that loky reports, which honors LOKY_MAX_CPU_COUNT, or fewer when the available memory cannot hold them. 1 solves in this process.

steadystate(*, e_ops=None, options=None, frame=None, approximation=None)[source]

Solve this chip’s unique static Lindblad steady state.

A chip that conserves the total excitation N and has an ExcitationCutoff or more than 64 product states needs no Liouvillian solve when its lowering channels prove the vacuum unique. The result then holds the vacuum on the labels with N <= 1. The vacuum is the same in every frame, so this also holds in a frame where the resolved Hamiltonian is not static. Other chips, and every call with options, solve the backend’s stationary Liouvillian. result.diagnostics["route"] records the route and the reason for it.

Parameters:
  • e_ops (dict or None, default=None) – Static expectation operators.

  • options (dict or None, default=None) – Backend solver options. A dictionary, also an empty one, selects the backend’s stationary Liouvillian.

  • frame (FrameSpec or None, default=None) – Solve frame, or None to use the chip default.

  • approximation (Approximation or None, default=None) – Solve approximation, or None to use the chip default.

steadystate_batch(*axes, e_ops=None, options=None, frame=None, approximation=None, progress=True)[source]

Solve static Lindblad steady states over parameter sweep axes.

Parameters:
  • *axes (Any) – Parameter sweep axes accepted by the batch builder.

  • e_ops (dict or None, default=None) – Static expectation operators.

  • options (dict or None, default=None) – Backend solver options.

  • frame (FrameSpec or None, default=None) – Solve frame, or None to use the chip default.

  • approximation (Approximation or None, default=None) – Solve approximation, or None to use the chip default.

  • progress (bool, default=True) – Show backend progress where supported.

describe()[source]

Return a plain-text report of everything on the chip, in sections.

The report shows devices with their declared parameters (units included), noise settings, couplings, control wiring, and baths: the “what did I just build?” view. Returns a string, so use print(chip.describe()). Traced parameters show as <traced> and are never concretized.