InteractiveQAOATool / src /sv_disc.py
speederracer123's picture
Upload 17 files
d3527de verified
Raw
History Blame Contribute Delete
3.2 kB
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from qiskit.quantum_info import Statevector
import colorcet as cc
def sv_disc(sv, show_labels=True, phase_colors=False, num_columns=None):
'''
Display state vector using multidisc format, adapted from
'Programming Quantum Computers: Essential Algorithms and Code Samples',
by Johnston, Harrigan, and Gimeno-Segovia (O'Reilly, 2019).
Each computational basis state is represented by a disc.
Magnitude is the radius of a shaded circle in the disc.
Phase is a CCW-rotated line.
If phase_colors is True, magnitude is colored according to phase.
Parameters:
sv (qiskit.quantum_info.Statevector): state vector
show_labels (bool): print binary number for each state (default = True)
phase_colors (bool): apply color map to magnitude (default = False)
num_columns (int): maximum number of discs in each row;
if None, uses 8 if vector size <= 32, otherwise 16
'''
plt.ioff() # don't draw as fig is created -- return fig instead
ndiscs = sv.dim
maxcols = 0
if num_columns is None:
maxcols = 8 if (sv.dim <= 32) else 16
else:
maxcols = num_columns
ncols = min(sv.dim,maxcols) # no more than maxcol columns
nrows = ndiscs // ncols
if nrows*ncols != ndiscs:
nrows += 1
#colormap = cc.cm.cyclic_mybm_20_100_c48_s25
colormap = cc.cm.cyclic_isoluminant
fig, axs = plt.subplots(nrows=nrows, ncols=ncols, figsize=[1.5*ncols,1.5*nrows], gridspec_kw = {'wspace':0, 'hspace':0})
axs = axs.flat
for i in range(0,nrows*ncols):
axs[i].set_axis_off()
if show_labels:
axs[i].set_xlim(-1.5,1.5)
axs[i].set_ylim(-1.5,1.5)
else:
axs[i].set_xlim(-1.2,1.2)
axs[i].set_ylim(-1.2,1.2)
if i < ndiscs:
if show_labels: axs[i].text(0, 1.25, "{:0{width}b}".format(i,width=sv.num_qubits), ha='center', size='large')
disc = plt.Circle((0,0),1, ec='k',fc='w',zorder=0)
axs[i].add_patch(disc)
for i in range(0,ndiscs):
r = np.abs(sv.data[i])
t = 0
if r > 1e-5:
t = np.angle(sv.data[i])
if t < 0: t = 2*np.pi + t
px = np.cos(t+(np.pi/2))
py = np.sin(t+(np.pi/2))
axs[i].plot([0,px],[0, py],linewidth=1.0,color='k',zorder=10, markevery=(1,1), marker='o', markersize=5)
#axs[i].scatter(px,py,15, c='k')
color = fc=colormap(t/(2*np.pi)) if (phase_colors) else colormap(0)
mag = plt.Circle((0,0), r, fc=color, zorder=5)
axs[i].add_patch(mag)
return fig
def sv_disc_update(fig, sv):
for i in range(0, sv.dim):
ax = fig.axes[i]
# update angle
t = np.angle(sv.data[i])
if t < 0: t = 2*np.pi + t
px = np.cos(t+(np.pi/2))
py = np.sin(t+(np.pi/2))
ax.findobj(plt.Line2D)[0].set(data=[[0,px],[0,py]])
# update magnitude
ax.patches[1].set_radius(np.abs(sv.data[i]))
return