quchip.chip.states

State factories for Chip.

These helpers build bare tensor-product kets, dressed eigenstates, and normalized superpositions, plus the chip.set_state_order(...) + string-shorthand machinery where "eg1"-style specs name one level per device. The chip forwards its public state surface (Chip.state(), Chip.bare_state(), Chip.superposition(), Chip.set_state_order()) here; users normally call the chip methods, not these functions directly.

Module-level functions (taking chip as the first argument) mirror quchip.chip.serialization. The only per-chip state involved — the declared device order and level symbols — lives on the chip itself (chip._state_order / chip._level_symbols), set by set_state_order().

All spec inputs route through normalize_device_state_mapping(), which is the single place the str shorthand is parsed into a {label: value} dict, so the public factories never repeat the isinstance(..., str) guard.

The dressed state() path stays JAX-traceable: it forwards to ChipAnalysis.state(), which selects the assigned eigenvector column through the label_eigensystem() array kernel.

Functions

bare_state(chip[, device_states])

Bare tensor-product state from per-device Fock indices or kets.

normalize_device_state_mapping(chip, ...)

Merge a mapping (or string shorthand) and kwargs into {label: value}.

parse_state_string(chip, s)

Parse chip.bare_state("eg1") style strings into {label: index}.

set_state_order(chip, *devices[, levels])

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

state(chip[, device_states])

Dressed eigenstate for the given Fock-indexed bare-state labels.

superposition(chip, *components)

Normalized bare-basis superposition of tensor-product states.

quchip.chip.states.set_state_order(chip, *devices, levels=None)[source]

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

After this is called, Chip.bare_state(), Chip.state(), and Chip.superposition() accept single-string specifications where each character is one level per device in devices order. Level symbols default to g=0, e=1, f=2, h=3; digits 0..9 are always accepted as raw Fock indices.

Every chip device must be named exactly once.

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}
Parameters:
Return type:

None

quchip.chip.states.parse_state_string(chip, s)[source]

Parse chip.bare_state("eg1") style strings into {label: index}.

Parameters:
Return type:

dict[str, int]

quchip.chip.states.normalize_device_state_mapping(chip, device_states, keyword_states)[source]

Merge a mapping (or string shorthand) and kwargs into {label: value}.

A str device_states is the single place the "eg1" shorthand is parsed (via parse_state_string()), so every public state factory routes through here instead of repeating the guard. After the string shorthand and the mapping type-check, the resolve-and-dedup step is delegated to merge_labeled_values() — the same primitive the bare-tuple builder uses, so a duplicate device specification means the same thing here and in spectroscopy sweeps.

Parameters:
  • chip (Chip)

  • device_states (Mapping[str | 'BaseDevice', Any] | str | None)

  • keyword_states (dict[str, Any])

Return type:

dict[str, Any]

quchip.chip.states.superposition(chip, *components)[source]

Normalized bare-basis superposition of tensor-product states.

Each component is either a bare-state spec (dict keyed by device or label, or a string when set_state_order() has been called) or an (amplitude, spec) tuple for weighted mixing. Uniform weights by default; results are normalized to unit norm.

Unlike state(), this stays in the bare product basis — no dressed diagonalization — so the probe basis is explicit.

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}),
... )
Parameters:
Return type:

State

quchip.chip.states.state(chip, device_states=None, /, **device_state_kwargs)[source]

Dressed eigenstate for the given Fock-indexed bare-state labels.

Accepts a string shorthand (e.g. "eg1") when set_state_order() has been called.

Safe inside jax.jit/grad/vmap: under tracing the assigned eigenvector column is selected through the label_eigensystem() array kernel, so dressed initial states are differentiable end-to-end. The global phase is gauge-dependent (eigh column convention) — populations and |overlap| figures of merit are unaffected.

Parameters:
  • chip (Chip)

  • device_states (Mapping[str | 'BaseDevice', int] | str | None)

  • device_state_kwargs (int)

Return type:

State

quchip.chip.states.bare_state(chip, device_states=None, /, **device_state_kwargs)[source]

Bare tensor-product state from per-device Fock indices or kets.

Each device may be specified as either a Fock index (int) or a ket vector in that device’s local space. Devices not mentioned default to the ground state (Fock index 0). Unlike state() this does not diagonalize the coupled system.

Accepts a string shorthand (e.g. "eg1") when set_state_order() has been called.

Parameters:
Return type:

State