quchip.chip.observables

Observable construction for Chip.

These helpers turn an operator specification — a short name string (resolved off the device via BaseDevice.local_operator()), a raw local-space operator, or a raw full-space NumPy array — into a backend-native operator embedded on the chip’s tensor-product space.

The chip forwards its public observable surface (Chip.observable(), Chip.e_ops(), Chip.from_array()) here; users normally call the chip methods, not these functions directly. Module-level functions (taking chip as the first argument) mirror quchip.chip.serialization, since this group carries no per-chip state of its own.

Functions

e_ops(chip, *[, correlators])

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

from_array(chip, data[, device])

Build a backend operator from a raw NumPy array.

observable(chip, device, op)

Embed a device operator onto the full chip Hilbert space.

prepare_local_op(dev, spec)

Resolve a string name to a device operator; pass non-strings through.

quchip.chip.observables.prepare_local_op(dev, spec)[source]

Resolve a string name to a device operator; pass non-strings through.

The operator-name vocabulary is owned by the device (BaseDevice.local_operator()).

Parameters:
Return type:

Any

quchip.chip.observables.from_array(chip, data, device=None)[source]

Build a backend operator from a raw NumPy array.

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

Parameters:
Return type:

Any

quchip.chip.observables.observable(chip, device, op)[source]

Embed a device operator onto the full chip Hilbert space.

Accepts either an operator name ("X", "Y", "Z", "n", "a", "a_dag", "I") or an already-built local-space operator, and returns it embedded on the chip’s tensor-product space.

This is for manual full-space operator construction and analysis — the named-operator counterpart of from_array(), alongside operator_in_dressed_basis(). It is not a solver e_op: e_ops() (Chip.e_ops) is the solver surface, and it keeps operators local so the demodulation pipeline can band-decompose and embed them correctly. Passing this embedded operator into simulate(e_ops=...) would be misread as a local device operator.

Parameters:
Return type:

Any

quchip.chip.observables.e_ops(chip, *, 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. Two-device correlators (e.g. ⟨Z₁⊗Z₂⟩) are specified via correlators as device-label pairs → operator pairs. Returns local-space operators (not embedded) — the demodulation pipeline embeds as needed.

Parameters:
Return type:

dict[str | tuple[str, str], Any]