quchip.control.envelopes¶
Pulse envelope models for quantum control.
Envelopes define the local complex pulse 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; values are complex, with real and imaginary parts carrying relative I/Q structure.
Global phase belongs to scheduling, not to an envelope.
value(local_time)stays JAX-traceable; it must not concretize time or 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)
>>> fg = SquareWithGaussianEdges(duration=40.0, amplitude=0.1)
>>> lr = LinearRamp(duration=60.0, ramp_duration=50.0, amplitude=4.0)
Classes
|
Local complex pulse shape evaluated relative to its scheduled start. |
|
Centered Gaussian pulse. |
|
Gaussian pulse with a derivative quadrature. |
|
Flat-top pulse with Gaussian ramp-up and ramp-down edges. |
|
Linearly rising ramp that holds at peak amplitude. |
|
Constant-amplitude pulse. |
|
Flat-top pulse with Gaussian ramp-up and ramp-down edges. |
- class quchip.control.envelopes.Envelope(**params)[source]¶
Bases:
Registrable,ABCLocal complex pulse shape evaluated relative to its scheduled start.
- Parameters:
params (Any)
- abstractmethod value(local_time)[source]¶
Return complex I/Q shape at time relative to the pulse start.
- class quchip.control.envelopes.Gaussian(duration, sigmas=3, amplitude=1.0)[source]¶
Bases:
EnvelopeCentered 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=unbound, positive=True, nonnegative=False, serialize=True, unit='ns', symbol=None, noise=False, kw_only=False, required=True)¶
- sigmas: Any = Parameter(default=3, positive=True, nonnegative=False, serialize=True, unit=None, symbol=None, noise=False, kw_only=False, required=False)¶
- class quchip.control.envelopes.GaussianDRAG(duration, sigmas=3, amplitude=1.0, beta=0.0)[source]¶
Bases:
EnvelopeGaussian pulse with a derivative quadrature.
\[E(t) = I(t) + i\,\beta\,\frac{dI}{dt}, \qquad I(t) = A\exp\!\left[-\frac{(t-\tau/2)^2}{2\sigma^2}\right].\]betais signed and measured in ns. Its sign therefore owns the quadrature convention without an additional polarity flag.- duration: Any = Parameter(default=unbound, positive=True, nonnegative=False, serialize=True, unit='ns', symbol=None, noise=False, kw_only=False, required=True)¶
- sigmas: Any = Parameter(default=3, positive=True, nonnegative=False, serialize=True, unit=None, symbol=None, noise=False, kw_only=False, required=False)¶
- amplitude: Any = Parameter(default=1.0, positive=False, nonnegative=False, serialize=True, unit=None, symbol=None, noise=False, kw_only=False, required=False)¶
- class quchip.control.envelopes.GaussianEdge(duration, edge_duration, sigmas=3, amplitude=1.0)[source]¶
Bases:
EnvelopeFlat-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=unbound, positive=True, nonnegative=False, serialize=True, unit='ns', symbol=None, noise=False, kw_only=False, required=True)¶
- edge_duration: Any = Parameter(default=unbound, positive=True, nonnegative=False, serialize=True, unit='ns', symbol=None, noise=False, kw_only=False, required=True)¶
- sigmas: Any = Parameter(default=3, positive=True, nonnegative=False, serialize=True, unit=None, symbol=None, noise=False, kw_only=False, required=False)¶
- amplitude: Any = Parameter(default=1.0, positive=False, nonnegative=False, serialize=True, unit=None, symbol=None, noise=False, kw_only=False, required=False)¶
- class quchip.control.envelopes.SquareWithGaussianEdges(duration, amplitude=1.0, edge_frac=0.25, sigmas=3)[source]¶
Bases:
EnvelopeFlat-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=unbound, positive=True, nonnegative=False, serialize=True, unit='ns', symbol=None, noise=False, kw_only=False, required=True)¶
- amplitude: Any = Parameter(default=1.0, positive=False, nonnegative=False, serialize=True, unit=None, symbol=None, noise=False, kw_only=False, required=False)¶
- edge_frac: Any = Parameter(default=0.25, positive=True, nonnegative=False, serialize=True, unit=None, symbol=None, noise=False, kw_only=False, required=False)¶
- class quchip.control.envelopes.LinearRamp(duration, ramp_duration, amplitude=1.0)[source]¶
Bases:
EnvelopeLinearly 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.value(t)).tolist() [0.0, 2.0, 4.0, 4.0]
- duration: Any = Parameter(default=unbound, positive=True, nonnegative=False, serialize=True, unit='ns', symbol=None, noise=False, kw_only=False, required=True)¶
- ramp_duration: Any = Parameter(default=unbound, positive=True, nonnegative=False, serialize=True, unit='ns', symbol=None, noise=False, kw_only=False, required=True)¶
- amplitude: Any = Parameter(default=1.0, positive=False, nonnegative=False, serialize=True, unit=None, symbol=None, noise=False, kw_only=False, required=False)¶
- class quchip.control.envelopes.Square(duration, amplitude=1.0)[source]¶
Bases:
EnvelopeConstant-amplitude pulse.
\[E(t) = A, \qquad 0 \le t \le \tau.\]- Parameters:
- duration: Any = Parameter(default=unbound, positive=True, nonnegative=False, serialize=True, unit='ns', symbol=None, noise=False, kw_only=False, required=True)¶