def plot_wigner_function(state, res=100): """Plot the equal angle slice spin Wigner function of an arbitrary quantum state. Args: state (np.matrix[[complex]]): - Matrix of 2**n x 2**n complex numbers - State Vector of 2**n x 1 complex numbers res (int) : number of theta and phi values in meshgrid on sphere (creates a res x res grid of points) Returns: none: plot is shown with matplotlib on the screen References: [1] T. Tilma, M. J. Everitt, J. H. Samson, W. J. Munro, and K. Nemoto, Phys. Rev. Lett. 117, 180401 (2016). [2] R. P. Rundle, P. W. Mills, T. Tilma, J. H. Samson, and M. J. Everitt, Phys. Rev. A 96, 022117 (2017). """ state = np.array(state) if state.ndim == 1: state = np.outer(state, state) # turns state vector to a density matrix state = np.matrix(state) num = int(np.log2(len(state))) # number of qubits phi_vals = np.linspace(0, np.pi, num=res, dtype=np.complex_) theta_vals = np.linspace(0, 0.5 * np.pi, num=res, dtype=np.complex_) # phi and theta values for WF w = np.empty([res, res]) harr = np.sqrt(3) delta_su2 = np.zeros((2, 2), dtype=np.complex_) # create the spin Wigner function for theta in range(res): costheta = harr * np.cos(2 * theta_vals[theta]) sintheta = harr * np.sin(2 * theta_vals[theta]) for phi in range(res): delta_su2[0, 0] = 0.5 * (1 + costheta) delta_su2[0, 1] = -0.5 * (np.exp(2j * phi_vals[phi]) * sintheta) delta_su2[1, 0] = -0.5 * (np.exp(-2j * phi_vals[phi]) * sintheta) delta_su2[1, 1] = 0.5 * (1 - costheta) kernel = 1 for i in range(num): kernel = np.kron(kernel, delta_su2) # creates phase point kernel w[phi, theta] = np.real(np.trace(state * kernel)) # Wigner function # Plot a sphere (x,y,z) with Wigner function facecolor data stored in Wc fig = plt.figure(figsize=(11, 9)) ax = fig.gca(projection='3d') w_max = np.amax(w) # Color data for plotting w_c = cm.seismic_r((w + w_max) / (2 * w_max)) # color data for sphere w_c2 = cm.seismic_r( (w[0:res, int(res / 2):res] + w_max) / (2 * w_max)) # bottom w_c3 = cm.seismic_r((w[int(res / 4):int(3 * res / 4), 0:res] + w_max) / (2 * w_max)) # side w_c4 = cm.seismic_r( (w[int(res / 2):res, 0:res] + w_max) / (2 * w_max)) # back u = np.linspace(0, 2 * np.pi, res) v = np.linspace(0, np.pi, res) x = np.outer(np.cos(u), np.sin(v)) y = np.outer(np.sin(u), np.sin(v)) z = np.outer(np.ones(np.size(u)), np.cos(v)) # creates a sphere mesh ax.plot_surface(x, y, z, facecolors=w_c, vmin=-w_max, vmax=w_max, rcount=res, ccount=res, linewidth=0, zorder=0.5, antialiased=False) # plots Wigner Bloch sphere ax.plot_surface(x[0:res, int(res / 2):res], y[0:res, int(res / 2):res], -1.5 * np.ones((res, int(res / 2))), facecolors=w_c2, vmin=-w_max, vmax=w_max, rcount=res / 2, ccount=res / 2, linewidth=0, zorder=0.5, antialiased=False) # plots bottom reflection ax.plot_surface(-1.5 * np.ones((int(res / 2), res)), y[int(res / 4):int(3 * res / 4), 0:res], z[int(res / 4):int(3 * res / 4), 0:res], facecolors=w_c3, vmin=-w_max, vmax=w_max, rcount=res / 2, ccount=res / 2, linewidth=0, zorder=0.5, antialiased=False) # plots side reflection ax.plot_surface(x[int(res / 2):res, 0:res], 1.5 * np.ones((int(res / 2), res)), z[int(res / 2):res, 0:res], facecolors=w_c4, vmin=-w_max, vmax=w_max, rcount=res / 2, ccount=res / 2, linewidth=0, zorder=0.5, antialiased=False) # plots back reflection ax.w_xaxis.set_pane_color((0.4, 0.4, 0.4, 1.0)) ax.w_yaxis.set_pane_color((0.4, 0.4, 0.4, 1.0)) ax.w_zaxis.set_pane_color((0.4, 0.4, 0.4, 1.0)) ax.set_xticks([], []) ax.set_yticks([], []) ax.set_zticks([], []) ax.grid(False) ax.xaxis.pane.set_edgecolor('black') ax.yaxis.pane.set_edgecolor('black') ax.zaxis.pane.set_edgecolor('black') ax.set_xlim(-1.5, 1.5) ax.set_ylim(-1.5, 1.5) ax.set_zlim(-1.5, 1.5) m = cm.ScalarMappable(cmap=cm.seismic_r) m.set_array([-w_max, w_max]) plt.colorbar(m, shrink=0.5, aspect=10) plt.show()
def plot_wigner_function(state, res=100): """Plot the equal angle slice spin Wigner function of an arbitrary quantum state. Args: state (np.matrix[[complex]]): - Matrix of 2**n x 2**n complex numbers - State Vector of 2**n x 1 complex numbers res (int) : number of theta and phi values in meshgrid on sphere (creates a res x res grid of points) Returns: none: plot is shown with matplotlib on the screen References: [1] T. Tilma, M. J. Everitt, J. H. Samson, W. J. Munro, and K. Nemoto, Phys. Rev. Lett. 117, 180401 (2016). [2] R. P. Rundle, P. W. Mills, T. Tilma, J. H. Samson, and M. J. Everitt, Phys. Rev. A 96, 022117 (2017). """ state = np.array(state) if state.ndim == 1: state = np.outer(state, state) # turns state vector to a density matrix state = np.matrix(state) num = int(np.log2(len(state))) # number of qubits phi_vals = np.linspace(0, np.pi, num=res, dtype=np.complex_) theta_vals = np.linspace(0, 0.5*np.pi, num=res, dtype=np.complex_) # phi and theta values for WF w = np.empty([res, res]) harr = np.sqrt(3) delta_su2 = np.zeros((2, 2), dtype=np.complex_) # create the spin Wigner function for theta in range(res): costheta = harr*np.cos(2*theta_vals[theta]) sintheta = harr*np.sin(2*theta_vals[theta]) for phi in range(res): delta_su2[0, 0] = 0.5*(1+costheta) delta_su2[0, 1] = -0.5*(np.exp(2j*phi_vals[phi])*sintheta) delta_su2[1, 0] = -0.5*(np.exp(-2j*phi_vals[phi])*sintheta) delta_su2[1, 1] = 0.5*(1-costheta) kernel = 1 for i in range(num): kernel = np.kron(kernel, delta_su2) # creates phase point kernel w[phi, theta] = np.real(np.trace(state*kernel)) # Wigner function # Plot a sphere (x,y,z) with Wigner function facecolor data stored in Wc fig = plt.figure(figsize=(11, 9)) ax = fig.gca(projection='3d') w_max = np.amax(w) # Color data for plotting w_c = cm.seismic_r((w+w_max)/(2*w_max)) # color data for sphere w_c2 = cm.seismic_r((w[0:res, int(res/2):res]+w_max)/(2*w_max)) # bottom w_c3 = cm.seismic_r((w[int(res/4):int(3*res/4), 0:res]+w_max)/(2*w_max)) # side w_c4 = cm.seismic_r((w[int(res/2):res, 0:res]+w_max)/(2*w_max)) # back u = np.linspace(0, 2 * np.pi, res) v = np.linspace(0, np.pi, res) x = np.outer(np.cos(u), np.sin(v)) y = np.outer(np.sin(u), np.sin(v)) z = np.outer(np.ones(np.size(u)), np.cos(v)) # creates a sphere mesh ax.plot_surface(x, y, z, facecolors=w_c, vmin=-w_max, vmax=w_max, rcount=res, ccount=res, linewidth=0, zorder=0.5, antialiased=False) # plots Wigner Bloch sphere ax.plot_surface(x[0:res, int(res/2):res], y[0:res, int(res/2):res], -1.5*np.ones((res, int(res/2))), facecolors=w_c2, vmin=-w_max, vmax=w_max, rcount=res/2, ccount=res/2, linewidth=0, zorder=0.5, antialiased=False) # plots bottom reflection ax.plot_surface(-1.5*np.ones((int(res/2), res)), y[int(res/4):int(3*res/4), 0:res], z[int(res/4):int(3*res/4), 0:res], facecolors=w_c3, vmin=-w_max, vmax=w_max, rcount=res/2, ccount=res/2, linewidth=0, zorder=0.5, antialiased=False) # plots side reflection ax.plot_surface(x[int(res/2):res, 0:res], 1.5*np.ones((int(res/2), res)), z[int(res/2):res, 0:res], facecolors=w_c4, vmin=-w_max, vmax=w_max, rcount=res/2, ccount=res/2, linewidth=0, zorder=0.5, antialiased=False) # plots back reflection ax.w_xaxis.set_pane_color((0.4, 0.4, 0.4, 1.0)) ax.w_yaxis.set_pane_color((0.4, 0.4, 0.4, 1.0)) ax.w_zaxis.set_pane_color((0.4, 0.4, 0.4, 1.0)) ax.set_xticks([], []) ax.set_yticks([], []) ax.set_zticks([], []) ax.grid(False) ax.xaxis.pane.set_edgecolor('black') ax.yaxis.pane.set_edgecolor('black') ax.zaxis.pane.set_edgecolor('black') ax.set_xlim(-1.5, 1.5) ax.set_ylim(-1.5, 1.5) ax.set_zlim(-1.5, 1.5) m = cm.ScalarMappable(cmap=cm.seismic_r) m.set_array([-w_max, w_max]) plt.colorbar(m, shrink=0.5, aspect=10) plt.show()
def plot_wigner_sphere(fig, ax, wigner, reflections): """Plots a coloured Bloch sphere. Parameters ---------- fig An instance of matplotlib.pyplot.figure. ax An axes instance in fig. wigner : list of float the wigner transformation at `steps` different theta and phi. reflections : bool If the reflections of the sphere should be plotted as well. Notes ------ Special thanks to Russell P Rundle for writing this function. """ ax.set_xlabel("x") ax.set_ylabel("y") ax.set_zlabel("z") steps = len(wigner) theta = np.linspace(0, np.pi, steps) phi = np.linspace(0, 2 * np.pi, steps) x = np.outer(np.sin(theta), np.cos(phi)) y = np.outer(np.sin(theta), np.sin(phi)) z = np.outer(np.cos(theta), np.ones(steps)) wigner = np.real(wigner) wigner_max = np.real(np.amax(np.abs(wigner))) wigner_c1 = cm.seismic_r((wigner + wigner_max) / (2 * wigner_max)) # Plot coloured Bloch sphere: ax.plot_surface(x, y, z, facecolors=wigner_c1, vmin=-wigner_max, vmax=wigner_max, rcount=steps, ccount=steps, linewidth=0, zorder=0.5, antialiased=None) if reflections: wigner_c2 = cm.seismic_r((wigner[0:steps, 0:steps]+wigner_max) / (2*wigner_max)) # bottom wigner_c3 = cm.seismic_r((wigner[0:steps, 0:steps]+wigner_max) / (2*wigner_max)) # side wigner_c4 = cm.seismic_r((wigner[0:steps, 0:steps]+wigner_max) / (2*wigner_max)) # back # Plot bottom reflection: ax.plot_surface(x[0:steps, 0:steps], y[0:steps, 0:steps], -1.5*np.ones((steps, steps)), facecolors=wigner_c2, vmin=-wigner_max, vmax=wigner_max, rcount=steps/2, ccount=steps/2, linewidth=0, zorder=0.5, antialiased=False) # Plot side reflection: ax.plot_surface(-1.5*np.ones((steps, steps)), y[0:steps, 0:steps], z[0:steps, 0:steps], facecolors=wigner_c3, vmin=-wigner_max, vmax=wigner_max, rcount=steps/2, ccount=steps/2, linewidth=0, zorder=0.5, antialiased=False) # Plot back reflection: ax.plot_surface(x[0:steps, 0:steps], 1.5*np.ones((steps, steps)), z[0:steps, 0:steps], facecolors=wigner_c4, vmin=-wigner_max, vmax=wigner_max, rcount=steps/2, ccount=steps/2, linewidth=0, zorder=0.5, antialiased=False) # Create colourbar: m = cm.ScalarMappable(cmap=cm.seismic_r) m.set_array([-wigner_max, wigner_max]) plt.colorbar(m, shrink=0.5, aspect=10) plt.show()
def scale_val(val): return (val - minval) / (maxval - minval) frame = 0 isovals = np.linspace(-4, 4, 20) for isoval in isovals[isovals > 0]: print("processing isoval " + str(isoval)) if isoval > 0: surface = dsPos.surface(boxregion, "dvs", isoval) else: surface = ds.surface(boxregion, "dvs", isoval) p3dc = Poly3DCollection(surface.triangles, linewidth=0.0) p3dc.set_facecolor(cm.seismic_r(scale_val(isoval))) fig = plt.figure() ax = fig.gca(projection='3d') ax.add_collection(p3dc) # add the reference grids for Tr in Traces: ax.plot(Tr.projection['x'], Tr.projection['y'], Tr.projection['z'], 'k', alpha=0.3) ax.set_axis_off() if first_val: max_extent = (surface.vertices.max(axis=1) -
from matplotlib import cm dark_blue = [31, 120, 180] light_blue = [166, 206, 227] light_orange = [253, 205, 172] light_purple = [203, 213, 232] green = [115, 163, 72] orange = [253, 174, 97] yellow = [227, 198, 52] value_pen_cm = lambda t: cm.seismic_r(t) value_con = tuple([c / 256 for c in green]) value_pen_width = .5 value_con_width = 1 def episodic_failure_colors(t): return cm.hsv(t)