Spaces:
Runtime error
Runtime error
| 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 | |