Single Qubit Gates

In the previous section we looked at all the possible states a qubit could be in. We saw that qubits could be represented by 2D vectors, and that their states are limited to the form:

$$ |q\rangle = \cos{(\tfrac{\theta}{2})}|0\rangle + e^{i\phi}\sin{\tfrac{\theta}{2}}|1\rangle $$

Where $\theta$ and $\phi$ are real numbers. In this section we will cover gates, the operations that change a qubit between these states. Due to the number of gates and the similarities between them, this chapter is at risk of becoming a list. To counter this, we have included a few digressions to introduce important ideas at appropriate places throughout the chapter.

Contents

  1. The Pauli Gates
    1.1 The X-Gate
    1.2 The Y & Z-Gates
  2. Digression: The X, Y & Z-Bases
  3. The Hadamard Gate
  4. Digression: Measuring in Different Bases
  5. The Rϕ-gate
  6. The I, S and T-gates
    6.1 The I-Gate
    6.2 The S-Gate
    6.3 The T_Gate
  7. The General U3-gate

In The Atoms of Computation we came across some gates and used them to perform a classical computation. An important feature of quantum circuits is that, between initialising the qubits and measuring them, the operations (gates) are always reversible! These reversible gates can be represented as matrices, and as rotations around the Bloch sphere.

from qiskit import *
from math import pi
from qiskit.visualization import plot_bloch_multivector

1. The Pauli Gates

You should be familiar with the Pauli matrices from the linear algebra section. If any of the maths here is new to you, you should use the linear algebra section to bring yourself up to speed. We will see here that the Pauli matrices can represent some very commonly used quantum gates.

1.1 The X-Gate

The X-gate is represented by the Pauli-X matrix:

$$ X = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} = |0\rangle\langle1| + |1\rangle\langle0| $$

To see the effect a gate has on a qubit, we simply multiply the qubit’s statevector by the gate. We can see that the X-gate switches the amplitudes of the states $|0\rangle$ and $|1\rangle$:

$$ X|0\rangle = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}\begin{bmatrix} 1 \\ 0 \end{bmatrix} = \begin{bmatrix} 0 \\ 1 \end{bmatrix} = |1\rangle$$

Reminder: Multiplying Vectors by Matrices (Click here to expand)

Matrix multiplication is a generalisation of the inner product we saw in the last chapter. In the specific case of multiplying a vector by a matrix (as seen above), we always get a vector back: $$ M|v\rangle = \begin{bmatrix}a & b \\ c & d \\\end{bmatrix}\begin{bmatrix}v_0 \\ v_1 \\\end{bmatrix} = \begin{bmatrix}a\cdot v_0 + b \cdot v_1 \\ c \cdot v_0 + d \cdot v_1\end{bmatrix} $$ In quantum computing, we can write our matrices in terms of basis vectors: $$X = |0\rangle\langle1| + |1\rangle\langle0|$$ This can sometimes be clearer than using a box matrix as we can see what different multiplications will result in: $$ \begin{aligned} X|1\rangle & = (|0\rangle\langle1| + |1\rangle\langle0|)|1\rangle \\ & = |0\rangle\langle1|1\rangle + |1\rangle\langle0|1\rangle \\ & = |0\rangle \times 1 + |1\rangle \times 0 \\ & = |0\rangle \end{aligned} $$ In fact, when we see a ket and a bra multiplied like this: $$ |a\rangle\langle b| $$ this is called the outer product, which follows the rule: $$ |a\rangle\langle b| = \begin{bmatrix} a_0 b_0 & a_0 b_1 & \dots & a_0 b_n\\ a_1 b_0 & \ddots & & \vdots \\ \vdots & & \ddots & \vdots \\ a_n b_0 & \dots & \dots & a_n b_n \\ \end{bmatrix} $$ We can see this does indeed result in the X-matrix as seen above: $$ |0\rangle\langle1| + |1\rangle\langle0| = \begin{bmatrix}0 & 1 \\ 0 & 0 \\\end{bmatrix} + \begin{bmatrix}0 & 0 \\ 1 & 0 \\\end{bmatrix} = \begin{bmatrix}0 & 1 \\ 1 & 0 \\\end{bmatrix} = X $$

In Qiskit, we can create a short circuit to verify this:

# Let's do an X-gate on a |0> qubit
qc = QuantumCircuit(1)
qc.x(0)
qc.draw('mpl')

Let's see the result of the above circuit. Note: Here we use plot_bloch_multivector() which takes a qubit's statevector instead of the Bloch vector.

# Let's see the result
backend = Aer.get_backend('statevector_simulator')
out = execute(qc,backend).result().get_statevector()
plot_bloch_multivector(out)

We can indeed see the state of the qubit is $|1\rangle$ as expected. We can think of this as a rotation by $\pi$ radians around the x-axis of the Bloch sphere. The X-gate is also often called a NOT-gate, referring to its classical analogue.

1.2 The Y & Z-gates

Similarly to the X-gate, the Y & Z Pauli matrices also act as the Y & Z-gates in our quantum circuits:

$$ Y = \begin{bmatrix} 0 & -i \\ i & 0 \end{bmatrix} \quad\quad\quad\quad Z = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} $$$$ Y = -i|0\rangle\langle1| + i|1\rangle\langle0| \quad\quad Z = |0\rangle\langle0| - |1\rangle\langle1| $$

And, unsurprisingly, they also respectively perform rotations by $\pi$ around the y and z-axis of the Bloch sphere.

Below is a widget that displays a qubit’s state on the Bloch sphere, pressing one of the buttons will perform the gate on the qubit:

# Run the code in this cell to see the widget
from qiskit_textbook.widgets import gate_demo
gate_demo(gates='pauli')

In Qiskit, we can apply the Y and Z-gates to our circuit using:

qc.y(0) # Do Y-gate on qubit 0
qc.z(0) # Do Z-gate on qubit 0
qc.draw('mpl')

2. Digression: The X, Y & Z-Bases

Reminder: Eigenvectors of Matrices (Click here to expand) We have seen that multiplying a vector by a matrix results in a vector: $$ M|v\rangle = |v'\rangle \leftarrow \text{new vector} $$ If we chose the right vectors and matrices, we can find a case in which this matrix multiplication is the same as doing a multiplication by a scalar: $$ M|v\rangle = \lambda|v\rangle $$ (Above, $M$ is a matrix, and $\lambda$ is a scalar). For a matrix $M$, any vector that has this property is called an eigenvector of $M$. For example, the eigenvectors of the Z-matrix are the states $|0\rangle$ and $|1\rangle$: $$ \begin{aligned} Z|0\rangle & = |0\rangle \\ Z|1\rangle & = -|1\rangle \end{aligned} $$ Since we use vectors to describe the state of our qubits, we often call these vectors eigenstates in this context. Eigenvectors are very important in quantum computing, and it is important you have a solid grasp of them.

You may also notice that the Z-gate appears to have no effect on our qubit when it is in either of these two states. This is because the states $|0\rangle$ and $|1\rangle$ are the two eigenstates of the Z-gate. In fact, the computational basis (the basis formed by the states $|0\rangle$ and $|1\rangle$) is often called the Z-basis. This is not the only basis we can use, a popular basis is the X-basis, formed by the eigenstates of the X-gate. We call these two vectors $|+\rangle$ and $|-\rangle$:

$$ |+\rangle = \tfrac{1}{\sqrt{2}}(|0\rangle + |1\rangle) = \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 \\ 1 \end{bmatrix}$$$$ |-\rangle = \tfrac{1}{\sqrt{2}}(|0\rangle - |1\rangle) = \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 \\ -1 \end{bmatrix} $$

Another less commonly used basis is that formed by the eigenstates of the Y-gate. These are called:

$$ |\circlearrowleft\rangle, \quad |\circlearrowright\rangle$$

We leave it as an exercise to calculate these. There are in fact an infinite number of bases; to form one, we simply need two orthogonal vectors.

Quick Exercises

  1. Verify that $|+\rangle$ and $|-\rangle$ are in fact eigenstates of the X-gate.
  2. What eigenvalues do they have?
  3. Why would we not see these eigenvalues appear on the Bloch sphere?
  4. Find the eigenstates of the Y-gate, and their co-ordinates on the Bloch sphere.

Using only the Pauli-gates it is impossible to move our initialised qubit to any state other than $|0\rangle$ or $|1\rangle$, i.e. we cannot achieve superposition. This means we can see no behaviour different to that of a classical bit. To create more interesting states we will need more gates!

3. The Hadamard Gate

The Hadamard gate (H-gate) is a fundamental quantum gate. It allows us to move away from the poles of the Bloch sphere and create a superposition of $|0\rangle$ and $|1\rangle$. It has the matrix:

$$ H = \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix} $$

We can see that this performs the transformations below:

$$ H|0\rangle = |+\rangle $$$$ H|1\rangle = |-\rangle $$

This can be thought of as a rotation around the Bloch vector [1,0,1] (the line between the x & z-axis), or as transforming the state of the qubit between the X and Z bases.

You can play around with these gates using the widget below:

# Run the code in this cell to see the widget
from qiskit_textbook.widgets import gate_demo
gate_demo(gates='pauli+h')

Quick Exercise

  1. Write the H-gate as the outer products of vectors $|0\rangle$, $|1\rangle$, $|+\rangle$ and $|-\rangle$.
  2. Show that applying the sequence of gates: HZH, to any qubit state is equivalent to applying an X-gate.
  3. Find a combination of X, Z and H-gates that is equivalent to a Y-gate (ignoring global phase).

4. Digression: Measuring in Different Bases

We have seen that the Z-axis is not intrinsically special, and that there are infinitely many other bases. Similarly with measurement, we don’t always have to measure in the computational basis (the Z-basis), we can measure our qubits in any basis.

As an example, let’s try measuring in the X-basis. We can calculate the probability of measuring either $|+\rangle$ or $|-\rangle$:

$$ p(|+\rangle) = |\langle+|q\rangle|^2, \quad p(|-\rangle) = |\langle-|q\rangle|^2 $$

And after measurement, we are guaranteed to have a qubit in one of these two states. Since Qiskit only allows measuring in the Z-basis, we must create our own using Hadamard gates:

from qiskit.extensions import Initialize # Import the Inititialize function
# Create the X-measurement function:
def x_measurement(qc,qubit,cbit):
    """Measure 'qubit' in the X-basis, and store the result in 'cbit'"""
    qc.h(qubit)
    qc.measure(qubit, cbit)
    qc.h(qubit)
    return qc

# Initialise our qubit and measure it
qc = QuantumCircuit(1,1)
initial_state = [0,1]
initializer = Initialize(initial_state)
initializer.label = "init"
qc.append(initializer, [0])
x_measurement(qc, 0, 0)
qc.draw()

In the quick exercises above, we saw you could create an X-gate by sandwiching our Z-gate between two H-gates:

$$ X = HZH $$

Starting in the Z-basis, the H-gate switches our qubit to the X-basis, the Z-gate peforms a NOT in the X-basis, and the final H-gate returns our qubit to the Z-basis.

We can verify this always behaves like an X-gate by multiplying the matrices:

$$ HZH = \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix} \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix} = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} =X $$

Following the same logic, we have created an X-measurement by sandwiching our Z-measurement between two H-gates.

Let’s now see the results:

backend = Aer.get_backend('statevector_simulator') # Tell Qiskit how to simulate our circuit
out_state = execute(qc,backend).result().get_statevector() # Do the simulation, returning the state vector
plot_bloch_multivector(out_state) # Display the output state vector

We initialised our qubit in the state $|1\rangle$, but we can see that, after the measurement, we have collapsed our qubit to the states $|+\rangle$ or $|-\rangle$. If you run the cell again, you will see different results, but the final state of the qubit will always be $|+\rangle$ or $|-\rangle$.

Quick Exercises

  1. If we initialise our qubit in the state $|+\rangle$, what is the probability of measuring it in state $|-\rangle$?
  2. Use Qiskit to display the probability of measuring a $|0\rangle$ qubit in the states $|+\rangle$ and $|-\rangle$ (Hint: you might want to use .get_counts() and plot_histogram()).
  3. Try to create a function that measures in the Y-basis.

Measuring in different bases allows us to see Heisenberg’s famous uncertainty principle in action. Having certainty of measuring a state in the Z-basis removes all certainty of measuring a specific state in the X-basis, and vice versa. A common misconception is that the uncertainty is due to the limits in our equipment, but here we can see the uncertainty is actually part of the nature of the qubit.

For example, if we put our qubit in the state $|0\rangle$, our measurement in the Z-basis is certain to be $|0\rangle$, but our measurement in the X-basis is completely random! Similarly, if we put our qubit in the state $|-\rangle$, our measurement in the X-basis is certain to be $|-\rangle$, but now any measurement in the Z-basis will be completely random.

More generally: Whatever state our quantum system is in, there is always a measurement that has a certain outcome.

The introduction of the H-gate has allowed us to explore some interesting phenomena, but we are still very limited in our quantum operations. Let us now introduce a new type of gate:

5. The Rϕ-gate

The Rϕ-gate is parametrised, that is, it needs a number ($\phi$) to tell it exactly what to do. The Rϕ-gate performs a rotation of $\phi$ around the Z-axis (and as such is sometimes also known as the Rz-gate). It has the matrix:

$$ R_\phi = \begin{bmatrix} 1 & 0 \\ 0 & e^{i\phi} \end{bmatrix} $$

Where $\phi$ is a real number.

You can use the widget below to play around with the Rϕ-gate, specify $\phi$ using the slider:

# Run the code in this cell to see the widget
from qiskit_textbook.widgets import gate_demo
gate_demo(gates='pauli+h+rz')

In Qiskit, we specify an Rϕ-gate using rz(phi, qubit):

qc = QuantumCircuit(1)
qc.rz(pi/4, 0)
qc.draw('mpl')

You may notice that the Z-gate is a special case of the Rϕ-gate, with $\phi = \pi$. In fact there are three more commonly referenced gates we will mention in this chapter, all of which are special cases of the Rϕ-gate:

6. The I, S and T-gates

6.1 The I-gate

First comes the I-gate (aka ‘Id-gate’ or ‘Identity gate’). This is simply a gate that does nothing. Its matrix is the identity matrix:

$$ I = \begin{bmatrix} 1 & 0 \\ 0 & 1\end{bmatrix} $$

Applying the identity gate anywhere in your circuit should have no effect on the qubit state, so it’s interesting this is even considered a gate. There are two main reasons behind this, one is that it is often used in calculations, for example: proving the X-gate is its own inverse:

$$ I = XX $$

The second, is that it is often useful when considering real hardware to specify a ‘do-nothing’ or ‘none’ operation.

Quick Exercise

  1. What are the eigenstates of the I-gate?

6.2 The S-gates

The next gate to mention is the S-gate (sometimes known as the $\sqrt{Z}$-gate), this is an Rϕ-gate with $\phi = \pi/2$. It does a quarter-turn around the Bloch sphere. It is important to note that unlike every gate introduced in this chapter so far, the S-gate is not its own inverse! As a result, you will often see the S-gate, (also “S-dagger”, “Sdg” or $\sqrt{Z}^\dagger$-gate). The S-gate is clearly an Rϕ-gate with $\phi = -\pi/2$:

$$ S = \begin{bmatrix} 1 & 0 \\ 0 & e^{\frac{i\pi}{2}} \end{bmatrix}, \quad S^\dagger = \begin{bmatrix} 1 & 0 \\ 0 & e^{-\frac{i\pi}{2}} \end{bmatrix}$$

The name "$\sqrt{Z}$-gate" is due to the fact that two successively applied S-gates has the same effect as one Z-gate:

$$ SS|q\rangle = Z|q\rangle $$

This notation is common throughout quantum computing.

To add an S-gate in Qiskit:

qc = QuantumCircuit(1)
qc.s(0)   # Apply S-gate to qubit 0
qc.sdg(0) # Apply Sdg-gate to qubit 0
qc.draw('mpl')

6.3 The T-gate

The T-gate is a very commonly used gate, it is an Rϕ-gate with $\phi = \pi/4$:

$$ T = \begin{bmatrix} 1 & 0 \\ 0 & e^{\frac{i\pi}{4}} \end{bmatrix}, \quad T^\dagger = \begin{bmatrix} 1 & 0 \\ 0 & e^{-\frac{i\pi}{4}} \end{bmatrix}$$

As with the S-gate, the T-gate is sometimes also known as the $\sqrt[4]{Z}$-gate.

In Qiskit:

qc = QuantumCircuit(1)
qc.t(0)   # Apply T-gate to qubit 0
qc.tdg(0) # Apply Tdg-gate to qubit 0
qc.draw('mpl')

You can use the widget below to play around with all the gates introduced in this chapter so far:

# Run the code in this cell to see the widget
from qiskit_textbook.widgets import gate_demo
gate_demo()

7. General U-gates

As we saw earlier, the I, Z, S & T-gates were all special cases of the more general Rϕ-gate. In the same way, the U3-gate is the most general of all single-qubit quantum gates. It is a parametrised gate of the form:

$$ U_3(\theta, \phi, \lambda) = \begin{bmatrix} \cos(\theta/2) & -e^{i\lambda}\sin(\theta/2) \\ e^{i\phi}\sin(\theta/2) & e^{i\lambda+i\phi}\cos(\theta/2) \end{bmatrix} $$

Every gate in this chapter could be specified as $U_3(\theta,\phi,\lambda)$, but it is unusual to see this in a circuit diagram, possibly due to the difficulty in reading this.

Qiskit provides U2 and U1-gates, which are specific cases of the U3 gate in which $\theta = \tfrac{\pi}{2}$, and $\theta = \phi = 0$ respectively. You will notice that the U1-gate is equivalent to the Rϕ-gate.

$$ \begin{aligned} U_3(\tfrac{\pi}{2}, \phi, \lambda) = U_2 = \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 & -e^{i\lambda} \\ e^{i\phi} & e^{i\lambda+i\phi} \end{bmatrix} & \quad & U_3(0, 0, \lambda) = U_1 = \begin{bmatrix} 1 & 0 \\ 0 & e^{i\lambda}\\ \end{bmatrix} \end{aligned} $$

Before running on real IBM quantum hardware, all single-qubit operations are compiled down to $U_1$ , $U_2$ and $U_3$ . For this reason they are sometimes called the physical gates.

It should be obvious from this that there are an infinite number of possible gates, and that this also includes Rx and Ry-gates, although they are not mentioned here. It must also be noted that there is nothing special about the Z-basis, except that it has been selected as the standard computational basis. That is why we have names for the S and T-gates, but not their X and Y equivalents (e.g. $\sqrt{X}$ and $\sqrt[4]{Y}$).

import qiskit
qiskit.__qiskit_version__
{'qiskit-terra': '0.14.2',
 'qiskit-aer': '0.5.2',
 'qiskit-ignis': '0.3.3',
 'qiskit-ibmq-provider': '0.7.2',
 'qiskit-aqua': '0.7.3',
 'qiskit': '0.19.6'}