qml.pulse.transmon_drive¶
-
transmon_drive
(amplitude, phase, freq, wires, d=2)[source]¶ Returns a
ParametrizedHamiltonian
representing the drive term of a transmon qubit.The Hamiltonian is given by
\[\Omega(t) \sin\left(\phi(t) + \nu t\right) \sum_q Y_q\]where \(\{Y_q\}\) are the Pauli-Y operators on
wires
\(\{q\}\). The argumentsamplitude
,phase
andfreq
correspond to \(\Omega / (2\pi)\), \(\phi\) and \(\nu / (2\pi)\), respectively, and can all be either fixed numbers (float
) or depend on time (callable
). If they are time-dependent, they need to abide by the restrictions imposed inParametrizedHamiltonian
and have a signature of two parameters,(params, t)
.Together with the qubit \(Z\) terms in
transmon_interaction()
, driving with this term can generate \(X\) and \(Y\) rotations by setting \(\phi\) accordingly and driving on resonance (see eqs. (79) - (92) in 1904.06560). Further, it can generate entangling gates by driving at cross-resonance with a coupled qubit (see eqs. (131) - (137) in 1904.06560). Such a coupling is described intransmon_interaction()
.For realistic simulations, one may restrict the amplitude, phase and drive frequency parameters. For example, the authors in 2008.04302 impose the restrictions of a maximum amplitude \(\Omega_{\text{max}} = 20 \text{MHz}\) and the carrier frequency to deviate at most \(\nu - \omega = \pm 1 \text{GHz}\) from the qubit frequency \(\omega\) (see
transmon_interaction()
). The phase \(\phi(t)\) is typically a slowly changing function of time compared to \(\Omega(t)\).Note
Currently only supports
d=2
with qudit support planned in the future. Ford>2
, we have \(Y \mapsto i (\sigma^- - \sigma^+)\) with lowering and raising operators \(\sigma^{\mp}\).Note
Due to convention in the respective fields, we omit the factor \(\frac{1}{2}\) present in the related constructor
rydberg_drive()
See also
- Parameters
amplitude (Union[float, callable]) – Float or callable representing the amplitude of the driving field. This should be in units of frequency (GHz), and will be converted to angular frequency \(\Omega(t)\) internally where needed, i.e. multiplied by \(2 \pi\).
phase (Union[float, callable]) – Float or callable returning phase \(\phi(t)\) (in radians). Can be a fixed number (
float
) or depend on time (callable
)freq (Union[float, callable]) – Float or callable representing the frequency of the driving field. This should be in units of frequency (GHz), and will be converted to angular frequency \(\nu(t)\) internally where needed, i.e. multiplied by \(2 \pi\).
wires (Union[int, list[int]]) – Label of the qubit that the drive acts upon. Can be a list of multiple wires.
d (int) – Local Hilbert space dimension. Defaults to
d=2
and is currently the only supported value.
- Returns
a
ParametrizedHamiltonian
representing the transmon interaction- Return type
Example
We can construct a drive term acting on qubit
0
in the following way. We parametrize the amplitude and phase via \(\Omega(t)/(2 \pi) = A \times \sin^2(\pi t)\) and \(\phi(t) = \phi_0 (t - \frac{1}{2})\). The squared sine ensures that the amplitude will be strictly positive (a requirement for some hardware). For simplicity, we set the drive frequency to zero \(\nu=0\).def amp(A, t): return A * jnp.exp(-t**2) def phase(phi0, t): return phi0 freq = 0 H = qml.pulse.transmon_drive(amp, phase, freq, 0) t = 0. A = 1. phi0 = jnp.pi/2 params = [A, phi0]
Evaluated at \(t = 0\) with the parameters \(A = 1\) and \(\phi_0 = \pi/2\) we obtain \(2 \pi A \exp(0) \sin(\pi/2 + 0)\sigma^y = 2 \pi \sigma^y\).
>>> H(params, t) 6.283185307179586 * Y(0)
We can combine
transmon_drive()
withtransmon_interaction()
to create a full driven transmon Hamiltonian. Let us look at a chain of three transmon qubits that are coupled with their direct neighbors. We provide all frequencies in GHz (conversion to angular frequency, i.e. multiplication by \(2 \pi\), is taken care of internally where needed).We use values around \(\omega = 5 \times 2\pi \text{GHz}\) for resonant frequencies, and coupling strenghts on the order of around \(g = 0.01 \times 2\pi \text{GHz}\).
We parametrize the drive Hamiltonians for the qubits with amplitudes as squared sinusodials of maximum amplitude \(A\), and constant drive frequencies of value \(\nu\). We set the phase to zero \(\phi=0\), and we make the parameters \(A\) and \(\nu\) trainable for every qubit. We simulate the evolution for a time window of \([0, 5]\text{ns}\).
import jax jax.config.update("jax_enable_x64", True) qubit_freqs = [5.1, 5., 5.3] connections = [[0, 1], [1, 2]] # qubits 0 and 1 are coupled, as are 1 and 2 g = [0.02, 0.05] H = qml.pulse.transmon_interaction(qubit_freqs, connections, g, wires=range(3)) def amp(max_amp, t): return max_amp * jnp.sin(t) ** 2 freq = qml.pulse.constant # Parametrized constant frequency phase = 0.0 time = 5 for q in range(3): H += qml.pulse.transmon_drive(amp, phase, freq, q) # Parametrized drive for each qubit dev = qml.device("default.qubit", wires=range(3)) @jax.jit @qml.qnode(dev, interface="jax") def qnode(params): qml.evolve(H)(params, time) return qml.expval(qml.Z(0) + qml.Z(1) + qml.Z(2))
We evaluate the Hamiltonian with some arbitrarily chosen maximum amplitudes (here on the order of \(0.5 \times 2\pi \text{GHz}\)) and set the drive frequency equal to the qubit frequencies. Note how the order of the construction of
H
determines the order with which the parameters need to be passed toParametrizedHamiltonian
andevolve()
. We made the drive frequencies trainable parameters by providing constant callables throughconstant()
instead of fixed values (like the phase). This allows us to differentiate with respect to both the maximum amplitudes and the frequencies and optimize them.>>> max_amp0, max_amp1, max_amp2 = [0.5, 0.3, 0.6] >>> fr0, fr1, fr2 = qubit_freqs >>> params = [max_amp0, fr0, max_amp1, fr1, max_amp2, fr2] >>> qnode(params) Array(-1.57851962, dtype=float64) >>> jax.grad(qnode)(params) [Array(-13.50193649, dtype=float64), Array(3.1112141, dtype=float64), Array(16.40286521, dtype=float64), Array(-4.30485667, dtype=float64), Array(4.75813949, dtype=float64), Array(3.43272354, dtype=float64)]