State and Process Plots¶
[1]:
# python related things
import numpy as np
from matplotlib import pyplot as plt
# quantum related things
from pyquil.gate_matrices import X, Y, Z, H, CNOT, CZ
from forest.benchmarking.operator_tools.superoperator_transformations import *
from forest.benchmarking.utils import n_qubit_pauli_basis
Define some quantum states
Single qubit quantum states
[2]:
ZERO = np.array([[1, 0], [0, 0]])
ONE = np.array([[0, 0], [0, 1]])
plus = np.array([[1], [1]]) / np.sqrt(2)
minus = np.array([[1], [-1]]) / np.sqrt(2)
PLUS = plus @ plus.T.conj()
MINUS = minus @ minus.T.conj()
plusy = np.array([[1], [1j]]) / np.sqrt(2)
minusy = np.array([[1], [-1j]]) / np.sqrt(2)
PLUSy = plusy @ plusy.T.conj()
MINUSy = minusy @ minusy.T.conj()
MIXED = np.eye(2)/2
single_qubit_states = [('0',ZERO),('1',ONE),('+',PLUS),('-',MINUS),('+i',PLUSy),('-i',MINUSy)]
Two qubit quantum states
[3]:
P00 = np.kron(ZERO, ZERO)
P01 = np.kron(ZERO, ONE)
P10 = np.kron(ONE, ZERO)
P11 = np.kron(ONE, ONE)
bell = 1/np.sqrt(2) * np.array([[1, 0, 0, 1]])
BELL = np.outer(bell, bell)
two_qubit_states = [('00',P00), ('01',P01), ('10',P10), ('11',P11),('BELL',BELL)]
Plot Pauli representation of a quantum state; color and bar¶
[4]:
# convert to pauli basis
n_qubits = 1
pl_basis_oneq = n_qubit_pauli_basis(n_qubits)
c2p_oneq = computational2pauli_basis_matrix(2**n_qubits)
oneq_states_pl = [ (state[0], np.real(c2p_oneq@vec(state[1]))) for state in single_qubit_states]
n_qubits = 2
pl_basis_twoq = n_qubit_pauli_basis(n_qubits)
c2p_twoq = computational2pauli_basis_matrix(2**n_qubits)
twoq_states_pl = [ (state[0], np.real(c2p_twoq@vec(state[1]))) for state in two_qubit_states]
[5]:
from forest.benchmarking.plotting.state_process import plot_pauli_rep_of_state, plot_pauli_bar_rep_of_state
Single Qubit states¶
Color coded plot¶
[6]:
# can plot vertically
fig, ax = plt.subplots(1)
plot_pauli_rep_of_state(oneq_states_pl[0][1], ax, pl_basis_oneq.labels, 'State is |0>')
[7]:
# or can plot horizontally
for state in oneq_states_pl:
fig, ax = plt.subplots(1)
plot_pauli_rep_of_state(state[1].transpose(), ax, pl_basis_oneq.labels, 'State is |'+state[0]+'>')
Bar plot¶
[8]:
for state in oneq_states_pl:
fig, ax = plt.subplots(1)
plot_pauli_bar_rep_of_state(state[1].flatten(), ax, pl_basis_oneq.labels, 'State is |'+state[0]+'>')
Two qubit states¶
Color coded plot¶
[9]:
# can plot vertically
fig, ax = plt.subplots(1)
plot_pauli_rep_of_state(twoq_states_pl[0][1], ax, pl_basis_twoq.labels, 'State is |0>')
# can plot horizontially
fig, ax = plt.subplots(1)
plot_pauli_rep_of_state(twoq_states_pl[0][1].transpose(), ax, pl_basis_twoq.labels, 'State is |0>')
fig, ax = plt.subplots(1)
plot_pauli_rep_of_state(twoq_states_pl[-1][1].transpose(), ax, pl_basis_twoq.labels, 'State is BELL')
Bar plot¶
[10]:
# Also bar plots
fig, ax = plt.subplots(1)
plot_pauli_bar_rep_of_state(twoq_states_pl[-1][1].flatten(), ax, pl_basis_twoq.labels, 'State is BELL')
Plot a Quantum Process as a Pauli Transfer Matrix¶
[11]:
Xpl = kraus2pauli_liouville(X)
Hpl = kraus2pauli_liouville(H)
from forest.benchmarking.plotting.state_process import plot_pauli_transfer_matrix
[12]:
f, (ax1) = plt.subplots(1, 1, figsize=(5, 4.2))
plot_pauli_transfer_matrix(np.real(Xpl), ax1, pl_basis_oneq.labels, 'X gate')
f, (ax1) = plt.subplots(1, 1, figsize=(5, 4.2))
plot_pauli_transfer_matrix(np.real(Hpl), ax1, pl_basis_oneq.labels, 'H gate')
[12]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe7d35b7ba8>
[13]:
CNOTpl = kraus2pauli_liouville(CNOT)
CZpl = kraus2pauli_liouville(CZ)
f, (ax1) = plt.subplots(1, 1, figsize=(5, 4.2))
plot_pauli_transfer_matrix(np.real(CNOTpl), ax1, pl_basis_twoq.labels, 'CNOT')
f, (ax1) = plt.subplots(1, 1, figsize=(5, 4.2))
plot_pauli_transfer_matrix(np.real(CZpl), ax1, pl_basis_twoq.labels, 'CZ')
[13]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe7d375a9b0>
Hinton Plots for states and processes¶
The warning here is the hinton_real
function only works for plotting a real matrix so the user has to be careful. It will take the absolute value of complex numbers.
Visualize a real state in the computational basis¶
[14]:
from forest.benchmarking.utils import n_qubit_computational_basis
from forest.benchmarking.plotting.hinton import hinton_real
oneq = n_qubit_computational_basis(1)
oneq_latex_labels = [r'$|{}\rangle$'.format(''.join(j)) for j in oneq.labels]
_ = hinton_real(ZERO, max_weight=1.0, xlabels=oneq_latex_labels, ylabels=oneq_latex_labels, ax=None, title=r'$|0\rangle$')
_ = hinton_real(MINUS, max_weight=1.0, xlabels=oneq_latex_labels, ylabels=oneq_latex_labels, ax=None, title=r'$|-\rangle$')
Visualize a process in the Pauli basis¶
The Pauli representation is real so we can plot any process
[15]:
_ = hinton_real(Xpl, max_weight=1.0, xlabels=pl_basis_oneq.labels, ylabels=pl_basis_oneq.labels, ax=None, title='X gate')
_ = hinton_real(Hpl, max_weight=1.0, xlabels=pl_basis_oneq.labels, ylabels=pl_basis_oneq.labels, ax=None, title='H gate')
So far things look the same as the plot_pauli_transfer_matrix
but we can plot using the traditional Hinton diagram colors, now the size of the squares makes a difference.
[16]:
from matplotlib import cm
_ = hinton_real(Hpl, max_weight=1.0, xlabels=pl_basis_oneq.labels, ylabels=pl_basis_oneq.labels,cmap = cm.Greys_r, ax=None, title='Good H gate')
_ = hinton_real(Hpl-0.3, max_weight=1.0, xlabels=pl_basis_oneq.labels, ylabels=pl_basis_oneq.labels, cmap = cm.Greys_r, ax=None, title='Bad H gate')
[ ]: