GRAPE calculation of control fields for single-qubit rotation

Robert Johansson ([email protected])

In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import time
import numpy as np
from numpy import pi
In [2]:
from qutip import *
from qutip.control import *
In [3]:
T = 1
times = np.linspace(0, T, 100)
In [4]:
theta, phi = np.random.rand(2)
In [5]:
# target unitary transformation (random single qubit rotation)
U = rz(phi) * rx(theta); U
Out[5]:
Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isherm = False\begin{equation*}\left(\begin{array}{*{11}c}(0.899-0.300j) & (-0.101-0.303j)\\(0.101-0.303j) & (0.899+0.300j)\\\end{array}\right)\end{equation*}
In [6]:
R = 150
H_ops = [sigmax(), sigmay(), sigmaz()]

H_labels = [r'$u_{x}$',
            r'$u_{y}$',
            r'$u_{z}$',
        ]
In [7]:
H0 = 0 * pi * sigmaz()

GRAPE

In [8]:
from qutip.control.grape import plot_grape_control_fields, _overlap
from qutip.control.cy_grape import cy_overlap
from qutip.control.grape import cy_grape_unitary, grape_unitary_adaptive
In [9]:
from scipy.interpolate import interp1d
from qutip.ui.progressbar import TextProgressBar
In [10]:
u0 = np.array([np.random.rand(len(times)) * 2 * pi * 0.005 for _ in range(len(H_ops))])

u0 = [np.convolve(np.ones(10)/10, u0[idx,:], mode='same') for idx in range(len(H_ops))]
In [11]:
result = cy_grape_unitary(U, H0, H_ops, R, times, u_start=u0, eps=2*pi/T, phase_sensitive=False,
                          progress_bar=TextProgressBar())
10.0%. Run time:  15.34s. Est. time left: 00:00:02:18
20.0%. Run time:  30.02s. Est. time left: 00:00:02:00
30.0%. Run time:  44.65s. Est. time left: 00:00:01:44
40.0%. Run time:  59.38s. Est. time left: 00:00:01:29
50.0%. Run time:  74.05s. Est. time left: 00:00:01:14
60.0%. Run time:  88.64s. Est. time left: 00:00:00:59
70.0%. Run time: 103.16s. Est. time left: 00:00:00:44
80.0%. Run time: 117.85s. Est. time left: 00:00:00:29
90.0%. Run time: 132.81s. Est. time left: 00:00:00:14
Total run time: 146.36s

Plot control fields for iSWAP gate in the presense of single-qubit tunnelling

In [12]:
plot_grape_control_fields(times, result.u[:,:,:] / (2 * pi), H_labels, uniform_axes=True);
In [13]:
# target unitary
U
Out[13]:
Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isherm = False\begin{equation*}\left(\begin{array}{*{11}c}(0.899-0.300j) & (-0.101-0.303j)\\(0.101-0.303j) & (0.899+0.300j)\\\end{array}\right)\end{equation*}
In [14]:
# unitary from grape pulse
result.U_f
Out[14]:
Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isherm = False\begin{equation*}\left(\begin{array}{*{11}c}(0.899-0.300j) & (-0.101-0.303j)\\(0.101-0.303j) & (0.899+0.300j)\\\end{array}\right)\end{equation*}
In [15]:
# target / result overlap
_overlap(U, result.U_f).real, abs(_overlap(U, result.U_f))**2
Out[15]:
(1.0000000000000004, 1.0000000000000009)

Verify correctness of the Hamiltonian pulses by integration

In [16]:
c_ops = []
In [17]:
U_f_numerical = propagator(result.H_t, times[-1], c_ops, args={})
In [18]:
U_f_numerical
Out[18]:
Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isherm = False\begin{equation*}\left(\begin{array}{*{11}c}(0.905-0.293j) & (-0.096-0.293j)\\(0.096-0.293j) & (0.905+0.293j)\\\end{array}\right)\end{equation*}
In [19]:
_overlap(U, U_f_numerical)
Out[19]:
(0.9998929840837077+0j)

Bloch sphere dynamics

In [20]:
psi0 = basis(2, 0)
e_ops = [sigmax(), sigmay(), sigmaz()]
In [21]:
me_result = mesolve(result.H_t, psi0, times, c_ops, e_ops)
In [22]:
b = Bloch()

b.add_points(me_result.expect)

b.add_states(psi0)
b.add_states(U * psi0)
b.render()

Process tomography

Ideal gate

In [23]:
op_basis = [[qeye(2), sigmax(), sigmay(), sigmaz()]]
op_label = [["i", "x", "y", "z"]]
In [24]:
fig = plt.figure(figsize=(8,6))

U_ideal = spre(U) * spost(U.dag())

chi = qpt(U_ideal, op_basis)

fig = qpt_plot_combined(chi, op_label, fig=fig, threshold=0.001)

Gate calculated using GRAPE

In [25]:
fig = plt.figure(figsize=(8,6))

U_ideal = spre(result.U_f) * spost(result.U_f.dag())

chi = qpt(U_ideal, op_basis)

fig = qpt_plot_combined(chi, op_label, fig=fig, threshold=0.001)

Versions

In [26]:
from qutip.ipynbtools import version_table

version_table()
Out[26]:
SoftwareVersion
Cython0.21.2
QuTiP3.1.0
IPython2.3.1
Numpy1.9.1
SciPy0.14.1
matplotlib1.4.2
Python3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2]
OSposix [linux]
Tue Jan 13 13:33:06 2015 JST