quchip.control.envelopes¶
Pulse envelope models for quantum control.
Envelopes define the time-domain waveform shape E(t) that a drive
line plays between t = 0 and t = duration. Subclasses are
auto-registered for serialization and as JAX pytrees (via
__init_subclass__), so envelope parameters — duration, amplitude,
edge width, DRAG coefficient, anything stored on the instance — remain
differentiable end-to-end.
Conventions¶
Times are ns, waveforms are complex (the real/imag parts are interpreted by the drive channel’s
DriveModulation).waveform(t, xp=jnp)must stay JAX-traceable whenxpisjax.numpy; no concretization oftor of stored parameters.
References
Motzoi et al., Simple Pulses for Elimination of Leakage, PRL 103, 110501 (2009) — motivates Gaussian envelopes with DRAG corrections for short transmon pulses.
Krantz et al., APR 6, 021318 (2019), Sec. IV.C — flat-top (Gaussian-edge) pulses for two-qubit gates.
Examples
>>> from quchip import Gaussian, LinearRamp, Square, SquareWithGaussianEdges
>>> g = Gaussian(duration=20.0, sigmas=3.0, amplitude=0.05)
>>> sq = Square(duration=10.0, amplitude=0.1, phase=0.0)
>>> fg = SquareWithGaussianEdges(duration=40.0, amplitude=0.1)
>>> lr = LinearRamp(duration=60.0, ramp_duration=50.0, amplitude=4.0)
Classes
|
Base class for pulse envelopes. |
|
Centered Gaussian pulse. |
|
Flat-top pulse with Gaussian ramp-up and ramp-down edges. |
|
Linearly rising ramp that holds at peak amplitude. |
|
Constant-amplitude pulse with optional global phase. |
|
Flat-top pulse with Gaussian ramp-up and ramp-down edges. |
- class quchip.control.envelopes.BaseEnvelope(duration, *, amplitude=1.0)[source]¶
Bases:
Registrable,ABCBase class for pulse envelopes.
Subclasses store their shape parameters as public attributes and implement
waveform(). Every public attribute is registered as a pytree leaf, so gradients flow through arbitrary envelope parameters without any extra bookkeeping. Serialization (the type registry andfrom_dictdispatch) is owned by the sharedRegistrablemixin; the JAX pytree registration below is independent of it.- Parameters:
duration (float) – Total pulse duration in ns. Must be positive at construction time when concrete; tracers are accepted unchanged.
amplitude (float) – Scalar amplitude applied on top of
waveform().
- abstractmethod waveform(t, *, xp=None)[source]¶
Evaluate the complex envelope at time points t (ns).
Pass
xp=jax.numpyto keep the computation traceable; otherwise NumPy is used.
- sample(tlist, *, real=False)[source]¶
Vectorized waveform evaluation on a time array.
Picks the array namespace from tlist (JAX if it is a JAX array/tracer, NumPy otherwise), so traced inputs stay traced and concrete inputs yield concrete outputs. Returns a complex array shaped like
tlist(or the real part ifreal=True).
- class quchip.control.envelopes.Gaussian(duration, sigmas=3, amplitude=1.0)[source]¶
Bases:
EnvelopeShapeCentered Gaussian pulse.
\[E(t) = A \exp\!\left[-\frac{(t - \tau/2)^2}{2 \sigma^2}\right], \qquad \sigma = \frac{\tau}{2 N_\sigma}.\]The
sigmasparameter \(N_\sigma\) is the number of standard deviations from the pulse center to its edge att = 0ort = duration. Gaussian pulses minimize spectral leakage onto higher transmon levels and are the starting point for DRAG corrections (Motzoi et al., PRL 103, 110501 (2009)).The scheduled window
[0, duration]starts and ends atamplitude * exp(-sigmas**2 / 2), not zero — about0.011 * amplitudeat the defaultsigmas=3. The pulse turns on and off with that jump; the Gaussian waveform itself is unchanged.- duration: Any = Parameter(default=<object object>, positive=True, nonnegative=False, serialize=True, unit='ns')¶
- class quchip.control.envelopes.GaussianEdge(duration, edge_duration, sigmas=3, amplitude=1.0)[source]¶
Bases:
EnvelopeShapeFlat-top pulse with Gaussian ramp-up and ramp-down edges.
Each edge is a Gaussian of width \(\sigma = \tau_e / (2 N_\sigma)\) where \(\tau_e\) =
edge_duration; the plateau between edges holds a constant amplitude \(A\). Totaldurationincludes both edges. Commonly used for two-qubit gates (Krantz et al. 2019, Sec. IV.C) because the flat top sets the gate area while the Gaussian edges suppress spectral leakage.- Parameters:
See also
SquareWithGaussianEdgesSame shape parameterized by
edge_frac(fraction) instead of absoluteedge_duration.
References
Krantz et al., APR 6, 021318 (2019), Sec. IV.C.
- duration: Any = Parameter(default=<object object>, positive=True, nonnegative=False, serialize=True, unit='ns')¶
- edge_duration: Any = Parameter(default=<object object>, positive=True, nonnegative=False, serialize=True, unit='ns')¶
- amplitude: Any = Parameter(default=1.0, positive=False, nonnegative=False, serialize=True, unit=None)¶
- class quchip.control.envelopes.SquareWithGaussianEdges(duration, amplitude=1.0, edge_frac=0.25, sigmas=3)[source]¶
Bases:
EnvelopeShapeFlat-top pulse with Gaussian ramp-up and ramp-down edges.
Each ramp has duration \(\tau_e = f_e \cdot \tau\) with \(f_e\) =
edge_frac; the plateau between ramps holds amplitude \(A\). Totaldurationincludes both edges. The Gaussian width is \(\sigma = \tau_e / (2 N_\sigma)\) with \(N_\sigma\) =sigmas.This is the canonical shape used in Krantz et al. 2019 (Sec. IV.C) for two-qubit gates — the flat top sets the gate area while the Gaussian edges suppress spectral leakage. Parametrizing the ramp as a fraction of the total duration makes the shape shape-invariant under changes of
duration.- Parameters:
duration (float) – Total pulse length in ns (includes both ramps).
amplitude (float) – Plateau amplitude \(A\).
edge_frac (float) – Ramp length as a fraction of the total duration. Must satisfy
0 < edge_fracand2 * edge_frac <= 1.sigmas (float) – Number of standard deviations spanned by each ramp.
- duration: Any = Parameter(default=<object object>, positive=True, nonnegative=False, serialize=True, unit='ns')¶
- amplitude: Any = Parameter(default=1.0, positive=False, nonnegative=False, serialize=True, unit=None)¶
- class quchip.control.envelopes.LinearRamp(duration, ramp_duration, amplitude=1.0)[source]¶
Bases:
EnvelopeShapeLinearly rising ramp that holds at peak amplitude.
The envelope rises linearly from 0 to
amplitudeover the firstramp_durationnanoseconds, then holds constant atamplitudefor the remainder of the pulse.\[E(t) = A \cdot \min\!\left(\frac{t}{\tau_r},\, 1\right), \qquad 0 \le t \le \tau,\]where \(\tau_r\) is
ramp_durationand \(\tau\) isduration.- Parameters:
Notes
For an adiabatic ramp into a Kerr-cat qubit, choose
ramp_durationlong compared to1 / (2 * K)(the inverse gap at the bifurcation point). See Grimm et al., Nature 584, 205 (2020).The waveform is JAX-traceable:
ramp_durationandamplitudemay be JAX tracers so the ramp parameters are differentiable.Examples
>>> from quchip.control.envelopes import LinearRamp >>> ramp = LinearRamp(duration=60.0, ramp_duration=50.0, amplitude=4.0) >>> import numpy as np >>> t = np.array([0.0, 25.0, 50.0, 55.0]) >>> np.real(ramp.waveform(t)).tolist() [0.0, 2.0, 4.0, 4.0]
- duration: Any = Parameter(default=<object object>, positive=True, nonnegative=False, serialize=True, unit='ns')¶
- ramp_duration: Any = Parameter(default=<object object>, positive=True, nonnegative=False, serialize=True, unit='ns')¶
- amplitude: Any = Parameter(default=1.0, positive=False, nonnegative=False, serialize=True, unit=None)¶
- class quchip.control.envelopes.Square(duration, amplitude=1.0, phase=0.0)[source]¶
Bases:
EnvelopeShapeConstant-amplitude pulse with optional global phase.
\[E(t) = A\, e^{i\phi}, \qquad 0 \le t \le \tau.\]- Parameters:
- duration: Any = Parameter(default=<object object>, positive=True, nonnegative=False, serialize=True, unit='ns')¶