quchip.devices.resonator

Linear-resonator device model.

Hamiltonian:

\[H = \omega \, \hat{n}\]

where \(\hat{n} = a^\dagger a\) is the Fock-basis number operator and \(\omega\) is the bare cavity frequency.

Approximation

Strictly harmonic / non-interacting: no Kerr, no cross-Kerr, no drive backaction beyond what couplings/drives themselves introduce. This is the ideal cavity / transmission-line-resonator mode — suitable for readout cavities, filter modes, photonic oscillators, and cavity-QED benchmarks where anharmonicity is either absent or modelled separately. For Kerr / anharmonic cavities, use a device that owns an explicit (K/2) n(n-1) term (see examples/kerr_cat_qubit.py).

Optional dissipation

Passing internal_quality_factor = Q adds a single unobserved photon-loss collapse operator sqrt(kappa) a with \(\kappa = 2\pi\,f/Q\) (angular decay rate, rad/ns).

Quality-factor convention (physics, not a unit conversion). internal_quality_factor is defined against the ordinary frequency freq (GHz) carried by this class. The resulting decay rate is \(\kappa = 2\pi\,f/Q\) (angular, rad/ns). The \(2\pi\) here is intrinsic to the physical definition of Q — not an ordinary→angular units conversion bolted on at the engine boundary. Concretely, Q counts cycles of the ordinary oscillation per e-folding of energy, so energy decays as \(e^{-t/\tau} = e^{-\kappa t}\) with \(\kappa = \omega/Q = 2\pi f/Q\). For this reason the \(2\pi\) lives in the resonator’s photon-loss noise channel and must not be moved to the units boundary in assembly.py.

Noise hooks inherited from BaseDevice (T1, T2, thermal_population) produce the Lindblad channels described in that base class. For circuit-QED conventions see Krantz et al., Applied Physics Reviews 6, 021318 (2019), §V.

References

  • Walls & Milburn, Quantum Optics, 2nd ed. (Springer, 2008), Ch. 7.

  • Blais, Grimsmo, Girvin & Wallraff, Circuit quantum electrodynamics, Reviews of Modern Physics 93, 025005 (2021).

Example

>>> from quchip.chip import Chip
>>> from quchip.devices import Resonator
>>> r = Resonator(freq=7.2, levels=6, label="readout")
>>> chip = Chip(devices=[r])
>>> r.freq, r.levels
(7.2, 6)

Classes

Resonator([freq, levels, label, T1, T2, ...])

Linear microwave / photonic resonator — pure harmonic oscillator.

class quchip.devices.resonator.Resonator(freq=unbound, *, levels=10, label=None, T1=None, T2=None, thermal_population=None, internal_quality_factor=None)[source]

Bases: FockDevice

Linear microwave / photonic resonator — pure harmonic oscillator.

Parameters:
  • freq (float) – Bare cavity frequency ω in GHz. Must be positive. May be a JAX tracer for sweeps / gradients.

  • internal_quality_factor (float | None, optional) – Internal Q referenced to the ordinary frequency freq in GHz. When set, adds a photon-loss Lindblad channel sqrt(2*pi*freq/Q) a with angular decay rate kappa = 2*pi*freq/Q in rad/ns. Must be positive. Like every noise parameter, it may be set after construction or cleared with None; the next simulation reflects the current value.

  • levels (int, default 10) – Fock-space truncation. Choose comfortably above the maximum expected photon occupation.

  • label (str | None, default None) – If omitted, auto-generated as resonator_{idx} via the shared labeling counter.

  • **noise_kwargs – Forwarded verbatim to BaseDeviceT1, T2, thermal_population.

Example

>>> from quchip.devices import Resonator
>>> r = Resonator(freq=7.2, internal_quality_factor=10_000, levels=8)
>>> len(r.collapse_operators()) >= 1
True
tunable_param_names = ('freq',)

Bare parameters this device exposes as differentiable / tunable scalars. fit_a_dress walks this tuple to discover what it is allowed to optimize on each device, decoupling the inverse-design surface from any specific device model. Three states, keyed on whether the value is explicitly declared:

  • No explicit declaration anywhere in the DeviceModel lineage — the default is derived: every declared parameter() field, in declaration order (see DeviceModel.__init_subclass__).

  • Explicit tuple on the class or an ancestor — exact curation, validated at class-definition time; authoritative and inherited until a subclass explicitly replaces it.

  • Explicit empty tuple — deliberately freezes the device (and its subclasses, until one replaces it) out of inverse design.

On a plain (non-DeviceModel) BaseDevice subclass there is no derivation; the default stays empty unless the subclass declares its own tuple — e.g. Fluxonium uses ("E_C", "E_J", "E_L", "phi_ext").

dressed_fit_target_fields = (('freq', 'freq'),)

(dressed_observable, declared_field) pairs used when this device appears in the desired-chip form of fit_a_dress. Empty means that the model makes no automatic dressed-target claim; circuit-level models can remain fixed until the user supplies explicit constraints.

dressed_fit_param_names = ('freq',)

Bare parameters normally varied to reproduce dressed_fit_target_fields. This remains separate from tunable_param_names: a model may expose parameters for sweeps without claiming that inverse design can identify all of them from its default dressed observables.

freq: Scalar = Parameter(default=unbound, positive=True, nonnegative=False, serialize=True, unit='GHz', symbol='\\omega', noise=False, kw_only=False, required=False)
internal_quality_factor: Scalar = Parameter(default=None, positive=True, nonnegative=False, serialize=True, unit=None, symbol=None, noise=True, kw_only=True, required=False)
approximation = 'Linear harmonic oscillator with no Kerr or cross-Kerr self-interaction.'

Declared approximation-regime statement surfaced by physics_notes() — the mechanism that keeps a model’s stated validity range attached to the class rather than buried in a docstring a caller may not read.

local_hamiltonian(op, p)[source]

Return the harmonic oscillator Hamiltonian H = freq * n.

Parameters:
Return type:

PhysicsExpr

dissipation(op, p)[source]

Return device-local Lindblad channels.

The base channels implement T1, T2, and thermal occupation. Subclasses may append channels with super().dissipation(op, p).

Parameters:
Return type:

tuple[CollapseChannel, …]

physics_notes()[source]

Return declared harmonic-oscillator and dissipation assumptions.

Return type:

list[str]

intrinsic_decay_rate()[source]

Combined lowering-channel rate: κ = 2π·freq/Q photon loss plus the thermal-emission rate.

Both internal_quality_factor and T1/thermal_population build independent lowering-operator collapse channels on this device (the internal_photon_loss channel, a pure loss channel unaffected by thermal_population, and the inherited thermal-emission channel — see intrinsic_decay_rate() for its (n̄+1)/T1 / n̄+1 formulas); this hook reports their summed rate rather than either alone, so a caller reading one scalar decay rate (e.g. an adiabatic-elimination Purcell fold) does not under-count decay when both are set. None only when neither is set.

Return type:

Any | None