The Bloch sphere

Visualization tools are important for understanding what is happening in a quantum circuit. A standard one is the Bloch sphere, as it represents a qubit as a three-dimensional object. We caution the reader that this tool will not help you think about multiple qubits, as it fails to demonstrate entanglement. This being said, it is very useful for understanding single qubits.

image0

As mentioned in the last section, a single-qubit state can be written as |\psi\rangle =\cos(\theta/2)|0\rangle + e^{j\phi}\sin(\theta/2)|1\rangle , where \theta and \phi are defined in the picture. We see that there is a one-to-one correspondence between pure qubit states ( \mathbb{C}^2 ) and the points on the surface of a unit sphere ( \mathbb{R}^3 ). We can reconstruct an arbitrary unknown qubit state |\psi\rangle by measuring the Bloch vector, whose vector components are the expectation values of the three Pauli operators, given by \langle X \rangle = \text{tr}(|\psi\rangle\langle \psi|X) , \langle Y \rangle = \text{tr}(|\psi\rangle\langle \psi|Y) , and \langle Z \rangle = \text{tr}(|\psi\rangle\langle \psi|Z) . The state is given by |\psi\rangle \langle\psi|=(I+\langle X\rangle X + \langle Y \rangle Y + \langle Z \rangle Z)/2 .

Each expectation value \langle Q \rangle can be obtained experimentally by first preparing the state, rotating the standard basis frame to lie along the corresponding axis Q , and making a measurement in the standard basis. The probabilities of obtaining the two possible outcomes 0 and 1 are used to evaluate the desired expectation value via \langle Q\rangle = P(0) - P(1) . As an example, let’s look at measuring the expectation value of X , \langle X\rangle = \text{tr}(|\psi\rangle\langle \psi|X) , depicted in the circuit below. Once |\psi\rangle is prepared, we implement the gate H that exchanges Z to X , then we make a measurement in the standard basis. The desired expectation value is given by  \langle X\rangle = P(0) -P(1) . Similarly, we can use the S^\dagger-H gate to measure \langle Y\rangle .

As you can see, a series of measurements is required to reconstruct the full Bloch vector, which then can be combined. This type of reconstruction is often referred to as state tomography. Efficiently running routines for tomography requires running batches of quantum scores at a time, and can be set up by more advanced users through Qiskit.

Qiskit example

# quantum_phase_bloch.py
import numpy as np

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute, Aer
from qiskit.tools.visualization import plot_bloch_vector

# Define the Quantum and Classical Registers
q = QuantumRegister(1)
c = ClassicalRegister(1)

# Build the circuits
pre = QuantumCircuit(q, c)
pre.h(q)
pre.barrier()

meas_x = QuantumCircuit(q, c)
meas_x.barrier()
meas_x.h(q)
meas_x.measure(q, c)

meas_y = QuantumCircuit(q, c)
meas_y.barrier()
meas_y.s(q).inverse()
meas_y.h(q)
meas_y.measure(q, c)

meas_z = QuantumCircuit(q, c)
meas_z.barrier()
meas_z.measure(q, c)

bloch_vector = ['x', 'y', 'z']
exp_vector = range(0, 21)
circuits = []
for exp_index in exp_vector:
    middle = QuantumCircuit(q, c)
    phase = 2*np.pi*exp_index/(len(exp_vector)-1)
    middle.u1(phase, q)
    circuits.append(pre + middle + meas_x)
    circuits.append(pre + middle + meas_y)
    circuits.append(pre + middle + meas_z)

# Execute the circuit
job = execute(circuits, backend = Aer.get_backend('qasm_simulator'), shots=1024)
result = job.result()

# Plot the result
for exp_index in exp_vector:
    bloch = [0, 0, 0]
    for bloch_index in range(len(bloch_vector)):
        data = result.get_counts(circuits[3*exp_index+bloch_index])
        try:
            p0 = data['0']/1024.0
        except KeyError:
            p0 = 0
        try:
            p1 = data['1']/1024.0
        except KeyError:
            p1 = 0
        bloch[bloch_index] = p0-p1
    plot_bloch_vector(bloch)