# Playing with single-qubit gates

In this file we will visualize the behaviour of single-qubit rotation gates. I've written out some video-making functions to make it more exciting!

**Important note**: The movies created here are stored on-disk and then read into the notebook player, so this script will be creating new files and directories on your HD.


```python
import numpy as np

from qiskit import QuantumRegister, ClassicalRegister
from qiskit import QuantumCircuit
from qiskit import execute, BasicAer

import qiskit.tools.visualization as qvis

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning) 

import matplotlib.pyplot as plt
# We will run a shell command to knit the image files together
import os

# For in-notebook video display
import io
import base64
from IPython.display import HTML
```

This function creates a movie given a name and a sequence of angles to rotate through. You can ignore this for now, but run it so you have the function for later.


```python
def create_movie(name, rotation_sequence, start_from_plus = False):
    # If start_from_plus is set to true, we'll apply a Hadamard before doing anything
    # else so that we initialize the qubit in the |+> state 
    
    # Create the movie directory; overwrite if one of the same name is already present
    os.system(f"rm -r {name}")
    os.system(f"mkdir {name}")

    # Apply the rotations and save the images
    for idx_frame, rotation in enumerate(rotation_sequence):
        q = QuantumRegister(1)
        circ = QuantumCircuit(q)

        if start_from_plus:
            circ.h(q)
            
        circ.u3(*rotation, q)

        backend = BasicAer.get_backend('statevector_simulator') # the device to run on
        result = execute(circ, backend).result()
        psi  = result.get_statevector(circ)
        img = qvis.plot_bloch_multivector(psi, title=f"{name}")
        img.savefig(f"{name}/{name}_{str(idx_frame)}.png")
        plt.show()

    # Create the movie
    os.system(f'ffmpeg -r 20 -i {name}/{name}_%01d.png {name}/{name}_animated.webm')
 
    # Return the movie for display - thank you stackoverflow!
    video = io.open(f'{os.getcwd()}/{name}/{name}_animated.webm', 'r+b').read()
    encoded = base64.b64encode(video)
    return HTML(data=''''''.format(encoded.decode('ascii')))
```

In the cell below, we will choose form of our rotation and set up a series of angles to plot at. We will be using the u3 operator provided by Qiskit. u3 allows us to specify a 3 parameter rotation of the form

\begin{equation}
 u3(\theta, \phi, \lambda) = \begin{pmatrix}
                                 \cos(\theta/2) & -e^{i\lambda}\sin(\theta/2) \\
                                 e^{i\phi}\sin(\theta/2) & e^{i\lambda + i\phi} \cos(\theta/2)
                             \end{pmatrix}
\end{equation}

Here are the parameterizations of u3 for the Pauli rotation gates:

\begin{eqnarray}
 R_x (\theta) &=& u3 (\theta, -\pi/2, \pi/2) \\
 R_y (\theta) &=& u3 (\theta, 0, 0) \\
 R_z (\theta) &=& u3 (0, 0, \theta)
\end{eqnarray}

We can use these three alone to produce most of our universal gate set. For the Hadamard, though, we need something extra because it is not a rotation around one of the Cartesian axes. (It is in fact a rotation around $\hat{x} + \hat{z}$).

\begin{equation}
 H = u3(\pi/2, 0, \pi)
\end{equation}


```python
# An X rotation
rotation_angle = np.pi
name = "x_gate" 
num_frames = 40 
intermediate_angles = np.linspace(0, rotation_angle, num_frames)
rotation_sequence = [(theta, -np.pi/2, np.pi/2) for theta in intermediate_angles] # The form of the tuple here specifies which gate you perform

create_movie(name, rotation_sequence)
```


```python
# A Y rotation
rotation_angle = np.pi
name = "y_rotation" 
num_frames = 40 
intermediate_angles = np.linspace(0, rotation_angle, num_frames)
rotation_sequence = [(theta, 0, 0) for theta in intermediate_angles] # The form of the tuple here specifies which gate you perform

create_movie(name, rotation_sequence)
```


```python
# A Z rotation
rotation_angle = np.pi
name = "z_rotation" 
num_frames = 40 
intermediate_angles = np.linspace(0, rotation_angle, num_frames)
rotation_sequence = [(0, 0, theta) for theta in intermediate_angles] # The form of the tuple here specifies which gate you perform

create_movie(name, rotation_sequence, start_from_plus=True)
```


```python
# S gate
rotation_angle = np.pi/2
name = "s_gate" 
num_frames = 40 
intermediate_angles = np.linspace(0, rotation_angle, num_frames)
rotation_sequence = [(0, 0, theta) for theta in intermediate_angles] # The form of the tuple here specifies which gate you perform

create_movie(name, rotation_sequence, start_from_plus=True)
```


```python
# T gate
rotation_angle = np.pi/4
name = "t_gate" 
num_frames = 40 
intermediate_angles = np.linspace(0, rotation_angle, num_frames)
rotation_sequence = [(0, 0, theta) for theta in intermediate_angles] # The form of the tuple here specifies which gate you perform

create_movie(name, rotation_sequence, start_from_plus=True)
```

To animate the Hadamard matrix, which is not an $x$, $y$, or $z$ rotation alone, we will need to use the general form of a unitary that creates a superposition. From the Qiskit documentation, that is $u3(\pi/2, \phi, \lambda)$:
\begin{equation}
  u3(\pi/2, \phi, \lambda) = \frac{1}{\sqrt{2}} \begin{pmatrix}
                                                  1 & -e^{-i\lambda} \\
                                                  e^{i\phi} & e^{i(\phi+\lambda)}
                                                  \end{pmatrix}
\end{equation}
To get the Hadamard, we will need to play with the second *and* third parameters of the tuple going from 0 to $\pi$.


```python
# Hadamard rotation
name = "hadamard_gate" 
num_frames = 40 
intermediate_angles_x = np.linspace(0, np.pi/2, num_frames)
intermediate_angles_y = np.linspace(-np.pi/2, 0, num_frames)
intermediate_angles_z = np.linspace(np.pi/2, np.pi, num_frames)
rotation_sequence = [(intermediate_angles_x[i], intermediate_angles_y[i], intermediate_angles_z[i]) for i in range(num_frames)] 
create_movie(name, rotation_sequence)
```


```python

```

6944cbd96e25b66024522463b48266a8ba882f68
ipynb
Jupyter Notebook
01-gate-model-theory/notebooks/Single-Qubit-Gates.ipynb
a-capra/Intro-QC-TRIUMF
9738e6a49f226367247cf7bc05a00751f7bf2fe5
MIT
2019-05-09T17:40:20.000Z
2021-12-15T12:23:17.000Z
01-gate-model-theory/notebooks/Single-Qubit-Gates.ipynb
a-capra/Intro-QC-TRIUMF
9738e6a49f226367247cf7bc05a00751f7bf2fe5
MIT
2021-09-29T07:34:09.000Z
2021-09-29T21:01:29.000Z
01-gate-model-theory/notebooks/Single-Qubit-Gates.ipynb
a-capra/Intro-QC-TRIUMF
9738e6a49f226367247cf7bc05a00751f7bf2fe5
MIT
2019-05-09T18:45:49.000Z
2021-12-15T12:23:21.000Z
Qwen/Qwen-72B
1. YES
2. YES