rydopt.pulses

Pulse Ansatz Functions

A pulse ansatz function is a function of time that additionally takes a set of parameters as input. It describes the time evolution of, e.g., the laser phase or the laser detuning. Below, we list pre-implemented pulse ansatz functions that can be used right away.

class PulseAnsatzFunction(num_params)[source]

Abstract base class for configurable pulse ansatz functions.

Parameters:

num_params (int)

property num_params: int

Number of scalar parameters expected by this ansatz.

General Pulse Ansatz Functions

sin_series(t, duration, ansatz_params)[source]

Sine-series pulse ansatz with fixed integer harmonics.

\[f(t) = \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi n}{T} t \right)\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(N\) entries \((\alpha_1, \dots, \alpha_N)\), where \(\alpha_n\) is the amplitude of the \(n\)-th harmonic.

Returns:

Values of \(f(t)\).

Return type:

Array

cos_series(t, duration, ansatz_params)[source]

Cosine-series pulse ansatz with fixed odd half-integer harmonics.

\[f(t) = \sum_{n=1}^N \beta_n \cos\!\left( \frac{(2n - 1)\pi}{T} t \right)\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(N\) entries \((\beta_1, \dots, \beta_N)\), where \(\beta_n\) is the amplitude of the \(n\)-th odd half-integer cosine mode.

Returns:

Values of \(f(t)\).

Return type:

Array

sin_crab(t, duration, ansatz_params)[source]

Sine-only CRAB pulse ansatz.

\[f(t) = \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right)\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(2N\) entries \((A_1, \alpha_1, \dots, A_N, \alpha_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

cos_crab(t, duration, ansatz_params)[source]

Cosine-only CRAB pulse ansatz.

\[f(t) = \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right)\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(2N\) entries \((B_1, \beta_1, \dots, B_N, \beta_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

sin_cos_crab(t, duration, ansatz_params)[source]

Combined sine and cosine CRAB pulse ansatz.

\[\begin{split}f(t) = \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right) \\ \quad + \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right)\end{split}\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(4N\) entries \((A_1, \alpha_1, B_1, \beta_1, \dots, A_N, \alpha_N, B_N, \beta_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

cos_sin_crab(t, duration, ansatz_params)[source]

Combined cosine and sine CRAB pulse ansatz.

\[\begin{split}f(t) = \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right) \\ \quad + \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right)\end{split}\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(4N\) entries \((B_1, \beta_1, A_1, \alpha_1, \dots, B_N, \beta_N, A_N, \alpha_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

const(t, _duration, ansatz_params)[source]

Constant pulse.

\[f(t) = c_0\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • _duration (float | Array) – Pulse duration \(T\) (unused).

  • ansatz_params (Array) – Array with entry \((c_0)\).

Returns:

Values of \(f(t)\).

Return type:

Array

const_sin_crab(t, duration, ansatz_params)[source]

Constant offset plus sine CRAB pulse ansatz.

\[f(t) = c_0 + \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right)\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(2N+1\) entries \((c_0, A_1, \alpha_1, \dots, A_N, \alpha_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

const_cos_crab(t, duration, ansatz_params)[source]

Constant offset plus cosine CRAB pulse ansatz.

\[f(t) = c_0 + \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right)\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(2N+1\) entries \((c_0, B_1, \beta_1, \dots, B_N, \beta_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

const_sin_cos_crab(t, duration, ansatz_params)[source]

Constant offset plus combined sine and cosine CRAB pulse ansatz.

\[\begin{split}f(t) = c_0 + \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right) \\ \quad + \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right)\end{split}\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(4N+1\) entries \((c_0, A_1, \alpha_1, B_1, \beta_1, \dots, A_N, \alpha_N, B_N, \beta_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

const_cos_sin_crab(t, duration, ansatz_params)[source]

Constant offset plus combined cosine and sine CRAB pulse ansatz.

\[\begin{split}f(t) = c_0 + \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right) \\ \quad + \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right)\end{split}\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(4N+1\) entries \((c_0, B_1, \beta_1, A_1, \alpha_1, \dots, B_N, \beta_N, A_N, \alpha_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

lin_sin_crab(t, duration, ansatz_params)[source]

Straight line plus sine CRAB pulse ansatz.

\[f(t) = c_1 (t - T/2) + \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right)\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(2N+1\) entries \((c_1, A_1, \alpha_1, \dots, A_N, \alpha_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

lin_cos_crab(t, duration, ansatz_params)[source]

Straight line plus cosine CRAB pulse ansatz.

\[f(t) = c_1 (t - T/2) + \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right)\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(2N+1\) entries \((c_1, B_1, \beta_1, \dots, B_N, \beta_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

lin_sin_cos_crab(t, duration, ansatz_params)[source]

Straight line plus combined sine and cosine CRAB pulse ansatz.

\[\begin{split}f(t) = c_1 (t - T/2) + \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right) \\ \quad + \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right)\end{split}\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(4N+1\) entries \((c_1, A_1, \alpha_1, B_1, \beta_1, \dots, A_N, \alpha_N, B_N, \beta_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

lin_cos_sin_crab(t, duration, ansatz_params)[source]

Straight line plus combined cosine and sine CRAB pulse ansatz.

\[\begin{split}f(t) = c_1 (t - T/2) + \sum_{n=1}^N \beta_n \cos\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(B_n)\right) (t - T/2) \right) \\ \quad + \sum_{n=1}^N \alpha_n \sin\!\left( \frac{2\pi}{T}\, n\left(1 + \tfrac{1}{2}\tanh(A_n)\right) (t - T/2) \right)\end{split}\]
Parameters:
  • t (float | Array) – Time samples at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with \(4N+1\) entries \((c_1, B_1, \beta_1, A_1, \alpha_1, \dots, B_N, \beta_N, A_N, \alpha_N)\).

Returns:

Values of \(f(t)\).

Return type:

Array

Soft-Box Pulse Ansatz Functions

softbox_hann(t, duration, ansatz_params)[source]

Soft-box pulse ansatz with Hann-shaped edges, also known as Tukey window.

The Hann window on \(\xi \in [0, 1]\) is

\[w(\xi) = a_0 - a_1 \cos(2\pi \xi),\]

with \(a_0 = 0.5\), \(a_1 = 0.5\). The pulse ansatz \(f(t)\) uses the rising and falling halves of this window:

\[\begin{split}f(t) = \begin{cases} 0, & t < 0 \ \text{or}\ t > T, \\[4pt] A\,w\!\left(\dfrac{t}{\alpha T}\right), & 0 \le t < \alpha T / 2, \\[8pt] A, & \alpha T / 2 \le t \le T - \alpha T / 2, \\[8pt] A\,w\!\left( 1 - \dfrac{T - t}{\alpha T} \right), & T - \alpha T / 2 < t \le T. \end{cases}\end{split}\]
Parameters:
  • t (float | Array) – Time samples \(t\) at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with two entries \((A, \alpha)\).

Returns:

Values of \(f(t)\).

Return type:

Array

softbox_blackman(t, duration, ansatz_params)[source]

Soft-box pulse ansatz with Blackman-shaped edges.

The Blackman window on \(\xi \in [0, 1]\) is

\[w(\xi) = a_0 - a_1 \cos(2\pi \xi) + a_2 \cos(4\pi \xi),\]

with \(a_0 = 0.42\), \(a_1 = 0.5\), \(a_2 = 0.08\). The pulse ansatz \(f(t)\) uses the rising and falling halves of this window:

\[\begin{split}f(t) = \begin{cases} 0, & t < 0 \ \text{or}\ t > T, \\[4pt] A\,w\!\left(\dfrac{t}{\alpha T}\right), & 0 \le t < \alpha T / 2, \\[8pt] A, & \alpha T / 2 \le t \le T - \alpha T / 2, \\[8pt] A\,w\!\left( 1 - \dfrac{T - t}{\alpha T} \right), & T - \alpha T / 2 < t \le T. \end{cases}\end{split}\]
Parameters:
  • t (float | Array) – Time samples \(t\) at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with two entries \((A, \alpha)\).

Returns:

Values of \(f(t)\).

Return type:

Array

softbox_nuttall(t, duration, ansatz_params)[source]

Soft-box pulse ansatz with Nuttall-shaped edges.

The Nuttall window on \(\xi \in [0, 1]\) is

\[w(\xi) = a_0 - a_1 \cos(2\pi \xi) + a_2 \cos(4\pi \xi) - a_3 \cos(6\pi \xi),\]

with \(a_0 = 0.355768\), \(a_1 = 0.487396\), \(a_2 = 0.144232\), \(a_3 = 0.012604\). The pulse ansatz \(f(t)\) uses the rising and falling halves of this window:

\[\begin{split}f(t) = \begin{cases} 0, & t < 0 \ \text{or}\ t > T, \\[4pt] A\,w\!\left(\dfrac{t}{\alpha T}\right), & 0 \le t < \alpha T / 2, \\[8pt] A, & \alpha T / 2 \le t \le T - \alpha T / 2, \\[8pt] A\,w\!\left( 1 - \dfrac{T - t}{\alpha T} \right), & T - \alpha T / 2 < t \le T. \end{cases}\end{split}\]
Parameters:
  • t (float | Array) – Time samples \(t\) at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with two entries \((A, \alpha)\).

Returns:

Values of \(f(t)\).

Return type:

Array

softbox_planck(t, duration, ansatz_params)[source]

Planck-taper window.

The Planck-taper on \(\xi \in (0, 1)\) is

\[w(\xi) = \frac{1}{ \exp\!\left( \frac{1}{\xi} - \frac{1}{1 - \xi} \right) + 1 },\]

with \(w(0)=0\) and \(w(1)=1\) by continuity. The pulse ansatz \(f(t)\) uses a rising and a falling Planck taper:

\[\begin{split}f(t) = \begin{cases} 0, & t < 0 \ \text{or}\ t > T, \\[4pt] A\,w\!\left(\dfrac{t}{\alpha T/2}\right), & 0 \le t < \alpha T / 2, \\[8pt] A, & \alpha T / 2 \le t \le T - \alpha T / 2, \\[8pt] A\,w\!\left( \dfrac{T - t}{\alpha T/2} \right), & T - \alpha T / 2 < t \le T. \end{cases}\end{split}\]
Parameters:
  • t (float | Array) – Time samples \(t\) at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with two entries \((A, \alpha)\).

Returns:

Values of \(f(t)\).

Return type:

Array

softbox_fifth_order_smoothstep(t, duration, ansatz_params)[source]

Soft-box pulse ansatz with 5th-order-smoothstep-shaped edges.

The 5th-order smoothstep on \(\xi \in [0, 1]\) is

\[w(\xi) = 6\xi^5 - 15\xi^4 + 10\xi^3,\]

which interpolates smoothly from 0 to 1 with vanishing first and second derivatives at both endpoints. The pulse ansatz \(f(t)\) uses a rising and a falling smoothstep:

\[\begin{split}f(t) = \begin{cases} 0, & t < 0 \ \text{or}\ t > T, \\[4pt] A\,w\!\left(\dfrac{t}{\alpha T/2}\right), & 0 \le t < \alpha T / 2, \\[8pt] A, & \alpha T / 2 \le t \le T - \alpha T / 2, \\[8pt] A\,w\!\left( \dfrac{T - t}{\alpha T/2} \right), & T - \alpha T / 2 < t \le T. \end{cases}\end{split}\]
Parameters:
  • t (float | Array) – Time samples \(t\) at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with two entries \((A, \alpha)\).

Returns:

Values of \(f(t)\).

Return type:

Array

softbox_seventh_order_smoothstep(t, duration, ansatz_params)[source]

Soft-box pulse ansatz with 7th-order-smoothstep-shaped edges.

The 7th-order smoothstep \(S_3\) on \(\xi \in [0, 1]\) is

\[w(\xi) = -20\xi^7 + 70\xi^6 - 84\xi^5 + 35\xi^4,\]

which interpolates smoothly from 0 to 1 with vanishing derivatives up to third order at both endpoints. The pulse ansatz \(f(t)\) uses a rising and a falling smoothstep:

\[\begin{split}f(t) = \begin{cases} 0, & t < 0 \ \text{or}\ t > T, \\[4pt] A\,w\!\left(\dfrac{t}{\alpha T/2}\right), & 0 \le t < \alpha T / 2, \\[8pt] A, & \alpha T / 2 \le t \le T - \alpha T / 2, \\[8pt] A\,w\!\left( \dfrac{T - t}{\alpha T/2} \right), & T - \alpha T / 2 < t \le T. \end{cases}\end{split}\]
Parameters:
  • t (float | Array) – Time samples \(t\) at which \(f(t)\) is evaluated.

  • duration (float | Array) – Pulse duration \(T\).

  • ansatz_params (Array) – Array with two entries \((A, \alpha)\).

Returns:

Values of \(f(t)\).

Return type:

Array

Pulse Ansatz Classes

An object of a pulse ansatz class is used to describe a complete laser pulse. Here, we provide two classes: one that describes a single-photon pulse and one that describes a two-photon pulse. Both classes implement the protocol PulseAnsatz.

class SinglePhotonPulseAnsatz(detuning_ansatz=<factory>, phase_ansatz=<factory>, rabi_ansatz=<factory>)[source]

Data class that stores ansatz functions for the laser pulse that couples the qubit state \(|1\rangle\) to the Rydberg state \(|r\rangle\).

RydOpt models the atom-light interaction in the rotating frame, using the rotating wave approximation. The Hamiltonian of the driven two-level ladder system \(|1\rangle \leftrightarrow |r\rangle\) is

\[\begin{split}H_\mathrm{drive}(t)=\begin{pmatrix} 0 & \frac{\Omega(t)}{2} e^{-i\xi(t)} \\ \frac{\Omega(t)}{2} e^{i\xi(t)} & -\Delta(t) \end{pmatrix}.\end{split}\]

For available ansatz functions for the detuning \(\Delta(t)\), phase \(\xi(t)\), and Rabi frequency \(\Omega(t)\) sweeps, see below. The function optimize allows optimizing the parameters of the ansatz functions and duration of the laser pulse to maximize the gate fidelity. Initial parameters can be provided to the function as PulseParams(duration, detuning_params, phase_params, rabi_params).

Example

>>> import rydopt as ro
>>> pulse = ro.pulses.SinglePhotonPulseAnsatz(
...     detuning_ansatz=ro.pulses.Const(),
...     phase_ansatz=ro.pulses.SinCrab(2),
... )
Parameters:
detuning_ansatz

Detuning sweep \(\Delta(t)\), default is zero.

Type:

PulseAnsatzFunction

phase_ansatz

Phase sweep \(\xi(t)\), default is zero.

Type:

PulseAnsatzFunction

rabi_ansatz

Rabi frequency amplitude sweep \(\Omega(t)\), default is one.

Type:

PulseAnsatzFunction

property param_counts: tuple[int, int, int]

Returns the numbers of parameters for each of the three ansatz function making up the total pulse ansatz.

Returns:

Tuple (detuning_ansatz.num_params, phase_ansatz.num_params, rabi_ansatz.num_params)

unpack_params(trainable_params)[source]

Convert pulse parameters to a PulseParams instance.

Accepts either a packed parameter vector or an already-unpacked parameter tuple. Packed parameters are interpreted as

(duration, detuning_params, phase_params, rabi_params)

with the ansatz parameter blocks having sizes determined by param_counts.

Parameters:

trainable_params (ParamsFloatLike) – Pulse parameters in packed or unpacked form.

Returns:

A PulseParams object containing the pulse duration and the parameter arrays for the detuning, phase, and Rabi-frequency ansatz functions.

Return type:

PulseParams[float]

evaluate_pulse_functions(t, params)[source]

Evaluate the detuning, phase, and the rabi sweeps for fixed parameters at the given times.

Parameters:
  • t (float | Array) – Time samples at which the functions are evaluated

  • params (ParamsFloatLike) – Pulse parameters

Returns:

Tuple (detuning_1, detuning_r, phase, rabi)

Return type:

tuple[Array, Array, Array, Array]

class TwoPhotonPulseAnsatz(lower_transition, upper_transition, decay=0.0)[source]

Data class that stores an effective two-photon pulse ansatz that couples the qubit state \(|1\rangle\) to the Rydberg state \(|r\rangle\) via the intermediate state \(|e\rangle\).

RydOpt models the atom-light interaction in the rotating frame, using the rotating wave approximation. The Hamiltonian of the driven three-level ladder system \(|1\rangle \leftrightarrow |e\rangle \leftrightarrow |r\rangle\) is taken as

\[\begin{split}H_\mathrm{3lvl}(t)= \begin{pmatrix} 0 & \frac{\Omega_\ell(t)}{2}\,e^{-i\xi_\ell(t)} & 0 \\[6pt] \frac{\Omega_\ell(t)}{2}\,e^{i\xi_\ell(t)} & -\Delta_\ell(t) - i \frac{\gamma}{2}& \frac{\Omega_u(t)}{2}\,e^{-i\xi_u(t)} \\[6pt] 0 & \frac{\Omega_u(t)}{2}\,e^{i\xi_u(t)} & -\Delta_\ell(t)-\Delta_u(t) \end{pmatrix},\end{split}\]

where the lower/upper laser couples \(|1\rangle \leftrightarrow |e\rangle\) / \(|e\rangle \leftrightarrow |r\rangle\) with Rabi frequency amplitudes \(\Omega_{\ell/u}(t)\), phases \(\xi_{\ell/u}(t)\), detunings \(\Delta_{\ell/u}(t)\). \(\gamma\) is the decay rate of the intermediate state.

The implementation is restricted to the adiabatic-elimination regime (\(|\Delta_\ell| \gg |\Omega_\ell|, |\Omega_u|, |\delta|\) and \(|\Delta_\ell|^2 \gg |\dot{\Omega}_\ell|, |\dot{\Omega}_u|, |\dot{\delta}|\) with \(\delta = \Delta_\ell+\Delta_u\)), where the system can be treated by an effective two-level Hamiltonian on the subspace \(\{|1\rangle,|r\rangle\}\):

\[\begin{split}H_\mathrm{drive}(t)= \begin{pmatrix} -\Delta_{1,\mathrm{eff}}(t) & \frac{\Omega_\mathrm{eff}(t)}{2} e^{-i\xi_\mathrm{eff}(t)} \\ \frac{\Omega_\mathrm{eff}(t)}{2} e^{i\xi_\mathrm{eff}(t)} & -\Delta_{r,\mathrm{eff}}(t) \end{pmatrix}.\end{split}\]

The effective controls are computed as

\[\begin{split}\Omega_\mathrm{eff}(t)&=\frac{\Omega_\ell(t)\Omega_u(t)}{2(\Delta_\ell(t)+i\gamma/2)}, \\ \xi_\mathrm{eff}(t)&=\xi_\ell(t)+\xi_u(t), \\ \Delta_{1,\mathrm{eff}}(t)&=- \frac{\Omega_\ell(t)^2}{4(\Delta_\ell(t)+i\gamma/2)} \\ \Delta_{r,\mathrm{eff}}(t)&=\Delta_\ell(t)+\Delta_u(t)- \frac{\Omega_u(t)^2}{4(\Delta_\ell(t)+i\gamma/2)}.\end{split}\]

For available ansatz functions for the detuning, phase, and Rabi frequency sweeps, see below. The function optimize allows optimizing the parameters of the ansatz functions and duration of the laser pulse to maximize the gate fidelity. Initial parameters can be provided to the function as PulseParams(duration, detuning_params, phase_params, rabi_params). Each parameter array within the tuple is packed as [*lower_transition_params, *upper_transition_params]. The split positions are inferred from the ansatz parameter counts of lower_transition.

Example

>>> import rydopt as ro
>>> lower = ro.pulses.SinglePhotonPulseAnsatz(
...     detuning_ansatz=ro.pulses.Const(),
...     phase_ansatz=ro.pulses.SinCrab(4),
... )
>>> upper = ro.pulses.SinglePhotonPulseAnsatz(
...     detuning_ansatz=ro.pulses.Const(),
...     rabi_ansatz=ro.pulses.Const(),
... )
>>> pulse = ro.pulses.TwoPhotonPulseAnsatz(
...     lower_transition=lower,
...     upper_transition=upper,
... )
Parameters:
lower_transition

Ansatz for the lower transition \(|1\rangle \leftrightarrow |e\rangle\).

Type:

SinglePhotonPulseAnsatz

upper_transition

Ansatz for the upper transition \(|e\rangle \leftrightarrow |r\rangle\).

Type:

SinglePhotonPulseAnsatz

decay

Decay rate of the intermediate state, default is zero.

Type:

float

unpack_params(trainable_params)[source]

Convert packed pulse parameters to a PulseParams instance.

Parameters:

trainable_params (ParamsFloatLike) – Packed pulse parameters.

Returns:

A PulseParams object containing the pulse duration and the packed detuning, phase, and Rabi-frequency parameter arrays.

Return type:

PulseParams[float]

evaluate_pulse_functions(t, params)[source]

Evaluate the effective two-photon detuning, phase, and the rabi sweeps for fixed parameters at the given times.

Parameters:
  • t (float | Array) – Time samples at which the functions are evaluated

  • params (ParamsFloatLike) – Pulse parameters

Returns:

Tuple (detuning_1, detuning_r, phase, rabi)

Return type:

tuple[Array, Array, Array, Array]

Pulse Family Ansatz

class PulseFamilyAnsatz(detuning_ansatz=<factory>, phase_ansatz=<factory>, rabi_ansatz=<factory>, pulse_map=<factory>)[source]

Data class that stores ansatz functions for a family of laser pulses.

A pulse family describes a continuous family of gates argumentized by a gate argument \(\phi\) (for example, the target phase of a controlled phase gate). Rather than optimizing an independent pulse for each value of \(\phi\), the pulse duration and ansatz parameters are represented as functions of \(\phi\).

RydOpt models this dependence through a parameter map. The packed pulse parameters are optimized once and mapped to the pulse duration and ansatz parameters for a specific gate argument value. By default, PolynomialPulseMap represents each pulse parameter as a polynomial of fixed degree in \(\phi\).

For available ansatz functions for the detuning \(\Delta(t)\), phase \(\xi(t)\), and Rabi frequency \(\Omega(t)\) sweeps, see below. The function optimize_family allows optimizing the pulse-family parameters to maximize fidelity across a target gate family. Initial pulse-family parameters can be provided as PulseFamilyParams(duration_params, detuning_params, phase_params, rabi_params), where each array contains the coefficients used by pulse_map to construct the corresponding pulse duration or ansatz parameters for a given gate argument value.

Example

>>> import rydopt as ro
>>> degrees = [2, 0, 3, 0]
>>> num_phase_params = 10
>>> pulse_map = ro.pulses.PolynomialPulseMap(degrees)
>>> pulse_family = ro.pulses.PulseFamilyAnsatz(
...     detuning_ansatz=ro.pulses.Const(),
...     phase_ansatz=ro.pulses.SinCrab(num_phase_params),
...     pulse_map=pulse_map,
... )
Parameters:
detuning_ansatz

Detuning sweep \(\Delta(t)\), default is zero.

Type:

PulseAnsatzFunction

phase_ansatz

Phase sweep \(\xi(t)\), default is zero.

Type:

PulseAnsatzFunction

rabi_ansatz

Rabi frequency amplitude sweep \(\Omega(t)\), default is one.

Type:

PulseAnsatzFunction

pulse_map

Maps optimized pulse-family parameters to the pulse duration and ansatz parameters for a given gate argument value. The default PolynomialPulseMap represents each pulse parameter as a fixed-degree polynomial in the gate argument.

Type:

rydopt.pulses.pulse_family_ansatz.PulseParamMap

property pulse_ansatz: SinglePhotonPulseAnsatz

Generate the pulse ansatz corresponding to a given gate argument.

static target_argument(gate_arg)[source]

Return the gate-family argument.

The argument is used as the input to pulse_map when generating pulse-family parameters.

Parameters:

gate_arg (float | Array | None)

Return type:

float | Array

unpack_params(trainable_params)[source]

Convert pulse-family parameters to a PulseFamilyParams.

Parameters:

trainable_params (ParamsFloatLike) – Packed or unpacked pulse-family trainable parameters.

Returns:

Pulse-family duration and ansatz parameter coefficients.

Return type:

PulseFamilyParams[float]

generate_pulse_params(trainable_params, gate_arg=None)[source]

Generate duration and ansatz parameter arrays for a gate argument.

Parameters:
Return type:

PulseParams

generate_duration(trainable_params, gate_arg=None)[source]

Generate the pulse duration for a given gate argument.

Parameters:
Return type:

float | Array

Pulse Maps

class PolynomialPulseMap(degrees=<factory>)[source]

Polynomial map of ansatz parameters.

Converts trainable pulse parameters into ansatz parameters given the target argument of the gate. Each component is treated as a polynomial in the target argument, with per-component degree given by degrees.

Parameters:

degrees (Sequence[int]) – polynomial degree for (duration, detuning, phase, rabi).

class PolynomialPulseMapWithCustomDuration(degrees=<factory>, duration_map=<function empirical_cphase_duration>, num_duration_params=3)[source]

Polynomial map of ansatz parameters with a custom expression for the gate duration.

The duration is computed by a user-provided callable duration_map that takes the target argument and the duration parameter array and returns the pulse duration. By default, the empirical expression empirical_cphase_duration() with the three duration parameters (piduration, prefactor, exponent) is used. Detuning, laser phase, and Rabi parameters use the polynomial mapping from PolynomialPulseMap.

Parameters:
  • degrees (Sequence[int]) – polynomial degree for (duration, detuning, phase, rabi). The duration degree is ignored because the duration uses duration_map.

  • duration_map (Callable[[Array, Array], Array]) – Callable (target_argument, duration_params) -> duration used to compute the pulse duration. Defaults to empirical_cphase_duration().

  • num_duration_params (int) – Number of duration parameters expected by duration_map. Defaults to 3, matching empirical_cphase_duration().

empirical_cphase_duration(target_phase, duration_params)[source]

Empirical expression for the duration of controlled-phase gates.

The duration parameters are (piduration, prefactor, exponent). The expression is based on fitting the functional form to controlled-phase gate durations for a range of target phases. The durations were extracted from Extended Data Fig. 5b of Evered et al., Nature 622, 268-272 (2023). The expression is given by

\[T(\theta) = T_\pi \left[ 1 - \left(1 - x^p\right)^q \right],\]

where

\[x = 1 - \left|\frac{\theta}{\pi} - 1\right|, \qquad q = \frac{A}{T_\pi 2^p}.\]

Here \(\theta\) is the target phase in radians clipped to the range \([0, 2\pi]\), \(T_\pi\) is piduration, \(A\) is prefactor, and \(p\) is exponent. The expression is symmetric under \(\theta \mapsto 2\pi - \theta\), satisfies \(T(\pi) = T_\pi\), and has the endpoint behavior

\[T(\theta) \sim A\left(\frac{\theta}{2\pi}\right)^p \qquad \theta \to 0,\]

with the corresponding symmetric behavior near \(\theta \to 2\pi\).

Parameters:
  • target_phase (Array) – Target phase \(\theta\) in radians.

  • duration_params (Array) – Array of the three duration parameters (piduration, prefactor, exponent).

Returns:

The pulse duration \(T(\theta)\).

Return type:

Array

Pulse Parameters

The parameters of a pulse can be specified in several ways. We provide classes that can be used to specify all parameters of a pulse or a pulse family. Moreover, we provide types that indicate how parameters may be specified without using the respective class.

class PulseParams(duration, detuning_params=(), phase_params=(), rabi_params=())[source]

Pulse-parameter container.

The container stores pulse parameters components (duration, detuning_params, phase_params, rabi_params).

Parameters:
  • duration (JaxArrayLike | npt.ArrayLike)

  • detuning_params (JaxArrayLike | npt.ArrayLike)

  • phase_params (JaxArrayLike | npt.ArrayLike)

  • rabi_params (JaxArrayLike | npt.ArrayLike)

class PulseFamilyParams(duration=(), detuning_params=(), phase_params=(), rabi_params=())[source]

PulseFamily parameter container.

Stores the four pulse-family parameter groups

(duration_params, detuning_params, phase_params, rabi_params).

For users, each parameter group is exposed through the corresponding property with its original shape preserved. Internally, all parameter arrays are stored as one-dimensional flattened arrays to support efficient concatenation, JAX transformations, and pytree handling.

The original array shapes are recorded and used to reconstruct the public parameter views when accessed through the properties.

Parameters:
  • duration (JaxArrayLike | npt.ArrayLike)

  • detuning_params (JaxArrayLike | npt.ArrayLike)

  • phase_params (JaxArrayLike | npt.ArrayLike)

  • rabi_params (JaxArrayLike | npt.ArrayLike)

type ParamsFloatLike = PulseParams[float] | PulseFamilyParams[float] | Sequence[float] | jax.Array | numpy.ndarray | tuple[jax.Array, jax.Array, jax.Array, jax.Array]

Pulse configuration as either PulseParams(duration, detuning_params, phase_params, rabi_params), PulseFamilyParams(duration_params, detuning_params, phase_params, rabi_params), an unpacked parameter tuple, or a packed parameter array/sequence.

  • duration / duration_params - Gate duration or pulse-family duration parameters

  • detuning_params - Parameters for the detuning sweep

  • phase_params - Parameters for the phase sweep

  • rabi_params - Parameters for the Rabi frequency amplitude sweep

type ParamsBoolLike = PulseParams[bool] | PulseFamilyParams[bool] | Sequence[bool] | jax.Array | numpy.ndarray

Boolean masks as either PulseParams(fixed_duration, fixed_detuning_params, fixed_phase_params, fixed_rabi_params), PulseFamilyParams(fixed_duration_params, fixed_detuning_params, fixed_phase_params, fixed_rabi_params), or a packed boolean mask array/sequence, marking which pulse parameters are held constant during optimization.

  • fixed_duration / fixed_duration_params - Whether the duration or duration parameters are fixed

  • fixed_detuning_params - Boolean mask of fixed detuning parameters

  • fixed_phase_params - Boolean mask of fixed phase parameters

  • fixed_rabi_params - Boolean mask of fixed Rabi frequency amplitude parameters