quchip.chip.couplings¶
Coupling models for two-body interactions between devices.
Couplers own their local Hamiltonians. A coupling
defines the interaction Hamiltonian on the two-device subspace
H_int ∈ L(H_a ⊗ H_b); the engine embeds it into the full chip space
at assembly time. Coupling strengths are in GHz.
References
- Blais, A., Huang, R.-S., Wallraff, A., Girvin, S. M., & Schoelkopf, R. J.
Cavity quantum electrodynamics for superconducting electrical circuits: An architecture for quantum computation. PRA 69, 062320 (2004), Eq. 11.
- Krantz, P., Kjaergaard, M., Yan, F., Orlando, T. P., Gustavsson, S., &
Oliver, W. D. A quantum engineer’s guide to superconducting qubits. Applied Physics Reviews 6, 021318 (2019), §V.
- Blais, A., Grimsmo, A. L., Girvin, S. M., & Wallraff, A. Circuit quantum
electrodynamics. Rev. Mod. Phys. 93, 025005 (2021).
Classes
|
Capacitive (charge-charge) coupling between two devices. |
|
Generic two-body coupling with a user-supplied interaction. |
|
Cross-Kerr (dispersive) coupling |
|
Capacitive coupling with a scheduled parametric pump. |
- class quchip.chip.couplings.Capacitive(device_a, device_b, *, g, rwa=None, label=None)[source]¶
Bases:
CouplingModelCapacitive (charge-charge) coupling between two devices.
The capacitive interaction between two electromagnetic modes takes the canonical dipole-dipole form in the raising/lowering basis:
Full form:
H_int = g · (a + a†)(b + b†)RWA form:
H_int = g · (a†b + a b†)— derived, not authored
The coupling authors only the full form; the RWA form is the engine retaining the
Δa + Δb == 0bands of it, which is exactlyg · (a†b + a b†). The RWA drops the counter-rotating termsa banda† b†, valid whenω_a + ω_b ≫ g— the sum-frequency condition that makes those terms fast-rotating and hence negligible. This is distinct from the dispersive condition|ω_a − ω_b| ≫ g, which instead governs whether the retained exchange termg · (a†b + a b†)can be treated perturbatively (seeTunableCapacitive/eliminate()for the dispersive reduction). Whether to take the RWA is a per-coupling policy; resolution against the chip default happens inChip.resolve_rwa().- Parameters:
device_a (BaseDevice or str) – The two coupled devices, given as objects or label strings. Label-string references are late-bound via
Chip.device_b (BaseDevice or str) – The two coupled devices, given as objects or label strings. Label-string references are late-bound via
Chip.g (float) – Coupling strength in GHz. May be a traced JAX scalar for sweeps / autodiff.
rwa (bool or None) – Per-coupling RWA override.
Noneinherits the chip default.label (str, optional) – Human-readable label; defaults to
"cap_{n}".
References
Blais et al., PRA 69, 062320 (2004), Eq. 11. Krantz et al., Appl. Phys. Rev. 6, 021318 (2019), §V.B. Blais et al., Rev. Mod. Phys. 93, 025005 (2021), §II.B.
Examples
>>> from quchip import DuffingTransmon, Resonator, Capacitive >>> q = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="q") >>> r = Resonator(freq=7.0, levels=5, label="r") >>> coupling = Capacitive(q, r, g=0.05) # RWA inherited from chip >>> _strong = Capacitive(q, r, g=0.05, rwa=False) # force full quantum-Rabi form
- g: Any = Parameter(default=<object object>, positive=False, nonnegative=False, serialize=True, unit='GHz')¶
- interaction(a, b)[source]¶
Return the full capacitive interaction
g * (a + a†)(b + b†).- Parameters:
- Return type:
- classmethod from_dict(d, device_a, device_b)[source]¶
Reconstruct a capacitive coupling from serialized state.
- Parameters:
device_a (BaseDevice)
device_b (BaseDevice)
- Return type:
- class quchip.chip.couplings.Coupling(device_a, device_b, g, *, op_a=None, op_b=None, interaction=None, rwa=None, label=None)[source]¶
Bases:
BaseCouplingGeneric two-body coupling with a user-supplied interaction.
Use this escape hatch when no concrete coupling class models the desired physics (inductive, longitudinal, cross-Kerr test forms, synthetic spin-spin couplings, photonics-style beam-splitters, …). The user supplies the operator structure; this class only provides the
gscaling, RWA pass-through, and bookkeeping.Two mutually exclusive modes:
Product form —
H_int = g · op_a(device_a) ⊗ op_b(device_b):Coupling(q, r, g=0.02, op_a=lambda d: d.number_operator(), op_b=lambda d: d.number_operator())
Callable form —
H_int = g · interaction(device_a, device_b, backend):Coupling(q, r, g=0.02, interaction=lambda a, b, bk: ( bk.tensor(bk.dag(a.lowering_operator()), b.lowering_operator()) + bk.tensor(a.lowering_operator(), bk.dag(b.lowering_operator())) ))
The resolved RWA applies the structural band filter to the user-supplied operator too, keeping only the bands
rwa_keeps_band()accepts. Supplyrwa=False(or overriderwa_keeps_band) to keep a hand-built form untouched.- Parameters:
device_a (BaseDevice | str)
device_b (BaseDevice | str)
g (float)
op_a (Callable[[BaseDevice], Operator] | None)
op_b (Callable[[BaseDevice], Operator] | None)
interaction (Callable[[BaseDevice, BaseDevice, 'Backend'], Operator] | None)
rwa (bool | None)
label (str | None)
- classmethod from_dict(d, device_a, device_b)[source]¶
Reject deserialization because callables cannot be reconstructed.
- Parameters:
device_a (BaseDevice)
device_b (BaseDevice)
- Return type:
- class quchip.chip.couplings.CrossKerr(device_a, device_b, *, chi, rwa=None, label=None)[source]¶
Bases:
CouplingModelCross-Kerr (dispersive) coupling
H_int = χ · n̂_a n̂_b.The effective diagonal interaction left when an exchange coupling is reduced in the dispersive regime — the natural coupling for effective readout chips (qubit + resonator +
CrossKerrprobed by an ordinary charge line) and static-ZZ modeling. Diagonal in both endpoints, so the RWA and full forms coincide and the term is frame-trivial.Declared approximation: this is a uniform-pull model — one χ per edge, the same shift per endpoint excitation; per-level χ differences, dispersive breakdown at the critical photon number, and Purcell decay are not represented (fold Purcell into endpoint
T1viaeliminate()when it matters).- Parameters:
device_a (BaseDevice or str) – The two coupled devices, as objects or label strings.
device_b (BaseDevice or str) – The two coupled devices, as objects or label strings.
chi (float) – Cross-Kerr shift in GHz per excitation pair, sign included (convention: full pull
E₁₁ − E₁₀ − E₀₁ + E₀₀). May be a JAX tracer.rwa (bool or None) – Per-coupling RWA override; irrelevant to the produced operator (both forms coincide) but stored for policy uniformity.
label (str, optional) – Defaults to
"crosskerr_{n}".
- chi: Any = Parameter(default=<object object>, positive=False, nonnegative=False, serialize=True, unit='GHz')¶
- interaction(a, b)[source]¶
Full form
χ · n̂_a n̂_b(diagonal; identical under RWA).- Parameters:
- Return type:
- class quchip.chip.couplings.TunableCapacitive(device_a, device_b, *, g_0, rwa=None, label=None)[source]¶
Bases:
CouplingModelCapacitive coupling with a scheduled parametric pump.
Effective two-body interaction with a static mean coupling strength:
\[\begin{split}H_{\text{int}} \;=\; g_0 \cdot \left\{\begin{array}{ll} (a + a^\dagger)(b + b^\dagger) & \text{if } \texttt{rwa} = \texttt{False} \\ (a^\dagger b + a b^\dagger) & \text{if } \texttt{rwa} = \texttt{True} \end{array}\right.\end{split}\]where \(g_0\) is the static coupling strength in GHz; it may be a JAX tracer and flows through
jax.grad()without concretization.Time-dependence is not a construction-time parameter: a
ParametricDrivewired onto this coupling schedules a pump δ(t) viapump(), multiplying the same operator structure the static term uses (parametric_interaction()/rwa_parametric_interaction()).- Parameters:
device_a (BaseDevice) – The two coupled devices.
device_b (BaseDevice) – The two coupled devices.
g_0 (float) – Static (mean) coupling strength in GHz. May be a JAX tracer.
rwa (bool or None) – Per-coupling RWA override;
Noneinherits the chip default.label (str, optional) – Human-readable label; defaults to
"tunable_cap_{n}".
Notes
The pump multiplies
parametric_interaction()/rwa_parametric_interaction()in the chip’s frame natively — no separate frame or carrier logic lives on the coupling; a pump tone at the qubits’ difference frequency|ω_a − ω_b|activates the parametric beam-splitter / iSWAP exchange, while a tone at the sum frequencyω_a + ω_binstead activates two-mode-squeezing (a†b†) terms. Either is expressed via the drive’sfreqargument, not a coupling-side carrier.References
McKay, Filipp, Mezzacapo, Magesan, Chow & Gambetta, Universal Gate for Fixed-Frequency Qubits via a Tunable Bus, Phys. Rev. Applied 6, 064007 (2016) — parametric two-qubit gates via coupler flux modulation.
Krantz et al., A quantum engineer’s guide to superconducting qubits, Appl. Phys. Rev. 6, 021318 (2019), §V.D — tunable couplers.
Examples
>>> from quchip import Chip, ControlEquipment, DuffingTransmon, ParametricDrive, TunableCapacitive >>> q0 = DuffingTransmon(freq=5.0, anharmonicity=-0.25, levels=3, label="q0") >>> q1 = DuffingTransmon(freq=5.2, anharmonicity=-0.22, levels=3, label="q1") >>> tc = TunableCapacitive(q0, q1, g_0=0.0, label="tc") >>> pump = ParametricDrive(tc, label="pump") >>> chip = Chip([q0, q1], couplings=[tc], control_equipment=ControlEquipment([pump])) >>> # seq.pump(tc, envelope=..., freq=...) schedules δg(t); see QuantumSequence.pump.
- g_0: Any = Parameter(default=<object object>, positive=False, nonnegative=False, serialize=True, unit='GHz')¶
- parametric_interaction(a, b)[source]¶
Modulable structure
(a + a†)(b + b†)a scheduled pump multiplies.- Parameters:
- Return type: