class BlochPlot(): ''' Dynamic plot context, intended for displaying geometries. like removing axes, equal axis, dynamically tune your figure and save it. Args: figsize (tuple, default=(6,4)): figure size. filename (filename, str): filename to store generated figure, if None, it will not save a figure. Attributes: figsize (tuple, default=(6,4)): figure size. filename (filename, str): filename to store generated figure, if None, it will not save a figure. ax (Axes): matplotlib Axes instance. Examples: with BlochPlot() as bp: bp.ball.add_vectors([0.4, 0.6, 0.8]) ''' def __init__(self, figsize=(6, 4), filename=None, dpi=300): self.figsize = figsize self.filename = filename self.ax = None def __enter__(self): from qutip import Bloch3d, Bloch plt.ion() self.fig = plt.figure(figsize=self.figsize) self.ax = Axes3D(self.fig, azim=-30, elev=15) self.ball = Bloch(axes=self.ax) self.ball.zlabel = [r'$|N\rangle$', r'$|S\rangle$'] return self def __exit__(self, *args): self.ax.axis('off') self.ax.set_aspect("equal") #self.ball.make_sphere() self.ball.make_sphere() plt.close() if self.filename is not None: print('Press `c` to save figure to "%s", `Ctrl+d` to break >>' % self.filename) pdb.set_trace() plt.savefig(self.filename, dpi=300) else: pdb.set_trace() def add_polar(self, theta, phi, color=None): self.ball.add_vectors(polar2vec([1, theta, phi])) self.ball.vector_color.append(color) def text(self, vec, txt, fontsize=14): if len(vec) == 2: vec = polar2vec(*vec) self.ax.text(vec[0], vec[1], vec[2], txt, fontsize=fontsize, va='center', ha='center')
def __enter__(self): from qutip import Bloch3d, Bloch plt.ion() self.fig = plt.figure(figsize=self.figsize) self.ax = Axes3D(self.fig, azim=-30, elev=15) self.ball = Bloch(axes=self.ax) self.ball.zlabel = [r'$|N\rangle$', r'$|S\rangle$'] return self
def bloch_animate(self, pnts, name="Bloch_animate"): """ Animates the path of a state through the set of pure states - requires ffmpeg """ from pylab import figure import matplotlib.animation as animation from mpl_toolkits.mplot3d import Axes3D # set up plot environment fig = figure() ax = Axes3D(fig, azim=-40, elev=30) sphere = Bloch(axes=ax) # define animation function (from qutip docs) def animate(i): sphere.clear() sphere.add_points( [pnts[0][:i + 1], pnts[1][:i + 1], pnts[2][:i + 1]]) sphere.make_sphere() return ax def init(): sphere.vector_color = ['r'] return ax ani = animation.FuncAnimation(fig, animate, np.arange(len(pnts[0])), init_func=init, repeat=False) ani.save(name + ".mp4", fps=20)
def plot_quantum_state(amplitudes): """ Thin function to abstract the plotting on the Bloch sphere. """ bloch_sphere = Bloch() vec = get_vector(amplitudes[0], amplitudes[1]) bloch_sphere.add_vectors(vec) bloch_sphere.show() bloch_sphere.clear()
def PlotStateQWP(InputState, qwpAngle): OutputState = QWP(qwpAngle) @ InputState pntsX = [ StateToBloch(QWP(th) @ InputState)[0] for th in arange(0, pi, pi / 64) ] pntsY = [ StateToBloch(QWP(th) @ InputState)[1] for th in arange(0, pi, pi / 64) ] pntsZ = [ StateToBloch(QWP(th) @ InputState)[2] for th in arange(0, pi, pi / 64) ] pnts = [pntsX, pntsY, pntsZ] bsph = Bloch() bsph.add_points(pnts) bsph.add_vectors(StateToBloch(OutputState)) bsph.add_vectors(StateToBloch(InputState)) return bsph.show()
def bloch_plot(self, filename, points=None, save=False): """ Plot the current state on the Bloch sphere using qutip. """ if points is None: # convert current state into density operator rho = np.outer(self.state.H, self.state) # get Bloch vector representation points = self.get_bloch_vec(rho) # Can only plot systems of dimension 2 at this time assert len( points ) == 3, "System dimension must be spin 1/2 for Bloch sphere plot" # create instance of 3d plot bloch = Bloch(fig=1, figsize=[9, 9], view=[190, 10]) # add state bloch.add_points(points) bloch.render() if save is True: print('Bloch plot saved to Sim Results folder') path = 'C:/Users/Boundsy/Desktop/Uni Work/PHS2360/Sim Results/' + str( filename) + '.png' bloch.fig.savefig(path, dpi=800, transparent=True)
def bloch_field(self, time): """ Plot magnetic field vector normalised to the bloch sphere """ # seperate coordinates into axis set xb = self.fields[0](time) yb = self.fields[1](time) zb = self.fields[2](time) # add to list and normalise points = [list(xb), list(yb), list(zb)] sqsum = 0.0 for i, point in enumerate(points[0]): # compute magnitude and store largest value sqsum_test = np.sqrt(points[0][i]**2 + points[1][i]**2 + points[2][i]**2) if sqsum_test > sqsum: sqsum = sqsum_test points = points / sqsum # create Bloch sphere instance bloch = Bloch() # add points and show bloch.add_points(points) bloch.show()
def bloch_plot(self, points=None): """ Plot the current state on the Bloch sphere using qutip. """ if points is None: # convert current state into density operator rho = np.outer(self.state.H, self.state) # get Bloch vector representation points = self.get_bloch_vec(rho) # Can only plot systems of dimension 2 at this time assert len( points ) == 3, "System dimension must be spin 1/2 for Bloch sphere plot" # create instance of 3d plot bloch = Bloch(figsize=[9, 9]) # add state bloch.add_points(points) bloch.add_vectors([0, 0, 1]) bloch.render(bloch.fig, bloch.axes) bloch.fig.savefig("bloch.png", dpi=600, transparent=True) bloch.show()
def bloch_from_dataframe(df, fig, axes): """ Plot Bloch sphere :param df: pd.DataFrame :param axes: :return: """ bloch = Bloch(fig=fig, axes=axes) bloch.vector_color = plt.get_cmap('viridis')(np.linspace(0, 1, len(df))) bloch.add_states([ Qobj([[row.Jxx, row.beta + 1j * row.gamma], [row.beta - 1j * row.gamma, row.Jyy]]) for _, row in df.iterrows() ]) bloch.make_sphere()
def animate(states): fig = figure() ax = Axes3D(fig,azim=-40,elev=30) sphere = Bloch(axes=ax) def animate(i): sphere.clear() sphere.add_states([states[i]]) sphere.make_sphere() return ax def init(): sphere.vector_color = ['r'] return ax ani = animation.FuncAnimation(fig, animate, np.arange(len(states)), init_func=init, blit=False, repeat=True) ani.save('decoherence.mp4', fps=20)
def field_plot(self, params, bloch=[False, 1]): """ Plots the signal components given simulation parameters over the specified time doman """ # get time varying fields and simulation data time, cparams, Bfields = field_get(params=params) # plot magnetic field vector on Bloch sphere if bloch[0]: Bfields = Bfields[::bloch[1], :] # normalise each magnetic field vector for i in range(len(Bfields)): norm = np.sqrt(Bfields[i, 0]**2 + Bfields[i, 1]**2 + Bfields[i, 2]**2) Bfields[i, 0] /= norm Bfields[i, 1] /= norm Bfields[i, 2] /= norm # extract x,y,z fields Bx = Bfields[:, 0] By = Bfields[:, 1] Bz = Bfields[:, 2] # define bloch object b = Bloch() b.add_points([Bx, By, Bz]) b.show() else: # plot fields fig, ax = plt.subplots(nrows=3, ncols=1, sharex=True, sharey=False) for i, row in enumerate(ax): # plot each component, skipping zero time value row.plot(time, Bfields[:, i]) row.set_title("Field vector along {} axis".format( ['x', 'y', 'z'][i])) plt.ylabel('Frequency (Hz)') plt.xlabel("Time (s)") #plt.ylabel("Ampltiude ($Hz/Gauss$)") plt.show()
def func(f1, b, set): """ This function Perform the gate application on the initial state of qubit and then the state tomography, at the same time compute the analytical bloch state. INCOME: f1="string", b="string" fig_data="svg",fig_data2="svg" """ #### Create the bloch-sphere on qutip b1 = Bloch() b2 = Bloch() ## create the analyical quantum state and perform tranformation ## Add states to the bloch sphere and plot it b1.add_states(analytic(f1, b)) if not set: states = qtomography(f1, b) b2.add_vectors(states) else: ### implements for states = qtomography_s(f1, b) for i in states: b2.add_points(i) b2.add_vectors(np.average(states, axis=0)) ### b2.render() fig_data = print_figure(b2.fig, 'svg') b1.render() fig_data2 = print_figure(b1.fig, 'svg') #b1.show() #b2.show() b1.clear() b2.clear() return fig_data, fig_data2
def animate_bloch(vectors, duration=0.1, save_all=False): numberOfLoops = 1 #Enter '1' to apply only ONE mode [Excitation or Relaxation] or '2' to to apply only BOTH modes [Excitation and Relaxation] starting with the selected mode if numberOfLoops == 1: maxAngle = 2 * np.pi elif numberOfLoops == 2: maxAngle = 4 * np.pi mode = 1 #Enter '0' to activate Excitation Mode or '1' to activate Relaxation Mode omega = np.pi / 6 #Enter the angular frequency z = 0 sqAngle = np.pi / 2 a = 5 vectorM = Bloch() # vectorM.view = [90,90] #Activate this line to view magnetization’s trajectory on x-y plane images = [] for t in np.arange(omega, maxAngle, 0.1): if mode == 0: z = np.pi / 2 * np.sin(t / (4)) if t == 2 * np.pi: mode = 1 elif mode == 1: z = np.pi / 2 * np.cos(t / (4)) if t == 2 * np.pi: mode = 0 else: pass vectorM.clear() vectorM.add_vectors([ np.sin(omega) * np.cos(t), np.sin(omega) * np.sin(t), np.cos(omega) ]) vectorM.add_vectors( [np.sin(z) * np.cos(a * t), np.sin(z) * np.sin(a * t), np.cos(z)]) vectorM.add_vectors([ np.sin(sqAngle) * np.cos(t), np.sin(sqAngle) * np.sin(t), np.cos(sqAngle) ]) filename = 'temp_file.png' vectorM.save(filename) images.append(imageio.imread(filename)) imageio.mimsave('bloch_anim.gif', images, duration=duration)
# ist qutip installiert? # https://numpy.org/install/#python-numpy-install-guide # importieren der numpy Library mit der Abkuerzung np # um nicht immer numpy schreiben zu muessen import numpy as np # importieren der Python eigene Mathematik Library import math # Beispielseite zu qutip # http://qutip.org/docs/3.1.0/guide/guide-bloch.html # %% -1- # Bloch() erzeugt eine Bloch # mit b verweisen wir spaeter auf diese b = Bloch() # b.show() zeigt die aktuelle Blochkugel an b.show() print('-1-') input('Press ENTER to continue.' ) # Ansonst wird Fenster sofort wieder geschlossen bzw. ueberschrieben. # %% -2- # hinzufuegen eines Vektor # x,y,z v = [1, 0, 0] # dazu geben wir einen Vektor in die x-Richtung an b.add_vectors( v) # mit b.add_vectors wird der Vektor v der Blochkugel hinzugefuegt b.show() print('-2-')
def __init__(self, fig): ################################################################# # # Initialize plotting exact plots tools # ################################################################# # p = np.linspace(-20., 20., 1000)[:, np.newaxis] # q = np.linspace(-20., 20., 1000)[np.newaxis, :] # # self.hybrid = CAnalyticQCHybrid(p, q, kT=0.5) # # img_params = dict( # extent=[q.min(), q.max(), p.min(), p.max()], # origin='lower', # cmap='seismic', # # norm=WignerNormalize(vmin=-0.1, vmax=0.1) # norm=WignerSymLogNorm(linthresh=1e-10, vmin=-0.01, vmax=0.1) # ) p = np.linspace(-0.1, 0.1, 500)[:, np.newaxis] q = np.linspace(-0.1, 0.1, 500)[np.newaxis, :] self.hybrid = SolAGKEq(p=p, q=q, omega=1., beta=1e5, alpha=0.95) img_params = dict( extent=[q.min(), q.max(), p.min(), p.max()], origin='lower', cmap='seismic', #norm=WignerNormalize(vmin=-0.1, vmax=0.1) norm=WignerSymLogNorm(linthresh=1e-10, vmin=-0.01, vmax=0.1)) # List to save the total hybrid energy for testing (it must be a conserved quantity) self.total_energy = [] # List to save the x component of the Bloch vector self.sigma_1 = [] ################################################################# # # Initialize plotting facility # ################################################################# self.fig = fig self.fig.suptitle( "Quantum-classical hybrid $m=1$, $\omega=1$, $\\alpha=0.95$, $\\beta={:.1e}$ (a.u.) (a.u.)" .format(self.hybrid.beta)) self.ax = fig.add_subplot(221) self.ax.set_title('Classical density') # generate empty plots self.img_classical_density = self.ax.imshow([[0]], **img_params) self.ax.set_xlabel('$q$ (a.u.)') self.ax.set_ylabel('$p$ (a.u.)') ax = fig.add_subplot(222) ax.set_title('Quantum purity') self.quantum_purity_plot, = ax.plot([0., 1000000], [1, 0.5]) ax.set_xlabel('time (a.u.)') ax.set_ylabel("quantum purity") self.time = [] self.qpurity = [] ax = fig.add_subplot(223) ax.set_title("Coordinate distribution") self.c_coordinate_distribution, = ax.semilogy( [self.hybrid.q.min(), self.hybrid.q.max()], [1e-11, 1e0], label="hybrid") ax.legend() ax.set_xlabel('$q$ (a.u.)') ax.set_ylabel('Probability density') ax = fig.add_subplot(224, projection='3d', azim=0, elev=0) self.bloch = Bloch(axes=ax) self.bloch.make_sphere()
class CVisualizeAnim(object): """ Class for drawing animation """ def __init__(self, fig): ################################################################# # # Initialize plotting exact plots tools # ################################################################# # p = np.linspace(-20., 20., 1000)[:, np.newaxis] # q = np.linspace(-20., 20., 1000)[np.newaxis, :] # # self.hybrid = CAnalyticQCHybrid(p, q, kT=0.5) # # img_params = dict( # extent=[q.min(), q.max(), p.min(), p.max()], # origin='lower', # cmap='seismic', # # norm=WignerNormalize(vmin=-0.1, vmax=0.1) # norm=WignerSymLogNorm(linthresh=1e-10, vmin=-0.01, vmax=0.1) # ) p = np.linspace(-0.1, 0.1, 500)[:, np.newaxis] q = np.linspace(-0.1, 0.1, 500)[np.newaxis, :] self.hybrid = SolAGKEq(p=p, q=q, omega=1., beta=1e5, alpha=0.95) img_params = dict( extent=[q.min(), q.max(), p.min(), p.max()], origin='lower', cmap='seismic', #norm=WignerNormalize(vmin=-0.1, vmax=0.1) norm=WignerSymLogNorm(linthresh=1e-10, vmin=-0.01, vmax=0.1)) # List to save the total hybrid energy for testing (it must be a conserved quantity) self.total_energy = [] # List to save the x component of the Bloch vector self.sigma_1 = [] ################################################################# # # Initialize plotting facility # ################################################################# self.fig = fig self.fig.suptitle( "Quantum-classical hybrid $m=1$, $\omega=1$, $\\alpha=0.95$, $\\beta={:.1e}$ (a.u.) (a.u.)" .format(self.hybrid.beta)) self.ax = fig.add_subplot(221) self.ax.set_title('Classical density') # generate empty plots self.img_classical_density = self.ax.imshow([[0]], **img_params) self.ax.set_xlabel('$q$ (a.u.)') self.ax.set_ylabel('$p$ (a.u.)') ax = fig.add_subplot(222) ax.set_title('Quantum purity') self.quantum_purity_plot, = ax.plot([0., 1000000], [1, 0.5]) ax.set_xlabel('time (a.u.)') ax.set_ylabel("quantum purity") self.time = [] self.qpurity = [] ax = fig.add_subplot(223) ax.set_title("Coordinate distribution") self.c_coordinate_distribution, = ax.semilogy( [self.hybrid.q.min(), self.hybrid.q.max()], [1e-11, 1e0], label="hybrid") ax.legend() ax.set_xlabel('$q$ (a.u.)') ax.set_ylabel('Probability density') ax = fig.add_subplot(224, projection='3d', azim=0, elev=0) self.bloch = Bloch(axes=ax) self.bloch.make_sphere() def __call__(self, frame_num): """ Draw a new frame :param frame_num: current frame number :return: image objects """ # convert the frame number to time t = 4000. * frame_num # calculate the hybrid density matrix self.hybrid.calculate_D(t) # Save total energy self.total_energy.append(self.hybrid.energy()) # Save <sigma_1> self.sigma_1.append(self.hybrid.average_sigma_1()) # plot the classical density c_rho = self.hybrid.classical_density() self.img_classical_density.set_array(c_rho) self.ax.set_title( 'Classical density \n $t = {:.1f}$ (a.u.)'.format(t)) # plot the coordinate distribution for the classical density coordinate_marginal = c_rho.sum(axis=0) # coordinate_marginal *= self.hybrid.dp coordinate_marginal /= coordinate_marginal.max() self.c_coordinate_distribution.set_data(self.hybrid.q.reshape(-1), coordinate_marginal) # plot quantum purity self.time.append(t) self.qpurity.append(self.hybrid.quantum_purity()) self.quantum_purity_plot.set_data(self.time, self.qpurity) # plot Bloch vector self.bloch.clear() self.bloch.add_states(Qobj(self.hybrid.quantum_density())) self.bloch.make_sphere() # # self.pauli.propagate(100) return self.img_classical_density, self.quantum_purity_plot, self.bloch,
# point2 = np.array([0., 0., 1.]) # # # # pitch = np.arctan(point1[2] / point1[1]) # # roll = - np.arctan(point1[0] / np.sign(point1[1]) * np.hypot(point1[1], point1[2])) # # # ## print(R_pitch(pitch).dot(R_roll(roll).dot(np.array([0, 1, 0])))) # # # hl = np.array([[0., 774.0801861], [1600., 825.23757385], [np.nan, np.nan]]) # hl_homo = np.array([np.hstack([hl[0] - 800, 800]), np.hstack([hl[1] - 800, 800])]) # # # hvps = np.array([[830.73055179,800.6414392],[1158.09074533, 811.10824692]]) # img = Image.open('/home/zhup/Desktop/Pano/Pano_hl_z_vp/3_im_hl.jpg') # draw = ImageDraw.Draw(img) # draw.line([tuple(hvps[0]), tuple(hvps[1])], width=6, fill='yellow') # img.save(os.path.join(root, 'render_part3.jpg')) b = Bloch() b.point_color = ['m', 'k', 'g', 'b', 'w', 'c', 'y', 'r'] b.zlabel = ['$z$', ''] b.point_marker = ['o'] b.point_size = [3] b.frame_width = 0.5 fig = plt.figure(figsize=(20, 20)) b.fig = fig name = os.path.join('zenith_on_sphere.jpg') b.save(name=name)
def PlotStateAnalyzer(InputState, hwpAngle, qwpAngle): QWPstate = QWP(qwpAngle) @ InputState OutputState = HWP(hwpAngle) @ QWP(qwpAngle) @ InputState pntsX = [ StateToBloch(QWP(th) @ InputState)[0] for th in arange(0, pi, pi / 64) ] pntsY = [ StateToBloch(QWP(th) @ InputState)[1] for th in arange(0, pi, pi / 64) ] pntsZ = [ StateToBloch(QWP(th) @ InputState)[2] for th in arange(0, pi, pi / 64) ] pnts = [pntsX, pntsY, pntsZ] pntsX2 = [ StateToBloch(HWP(th) @ QWP(qwpAngle) @ InputState)[0] for th in arange(0, pi, pi / 64) ] pntsY2 = [ StateToBloch(HWP(th) @ QWP(qwpAngle) @ InputState)[1] for th in arange(0, pi, pi / 64) ] pntsZ2 = [ StateToBloch(HWP(th) @ QWP(qwpAngle) @ InputState)[2] for th in arange(0, pi, pi / 64) ] pnts2 = [pntsX2, pntsY2, pntsZ2] bsph = Bloch() bsph.add_points(pnts) bsph.add_points(pnts2) bsph.add_vectors(StateToBloch(OutputState)) bsph.add_vectors(StateToBloch(InputState)) bsph.add_vectors(StateToBloch(QWPstate)) return bsph.show()
def draw_consensus_rectified_sphere(hv_points, root): b = Bloch() b.point_color = ['m', 'k', 'g', 'b', 'w', 'c', 'y', 'r'] b.zlabel = ['$z$', ''] b.point_marker = ['o'] b.point_size = [80] b.frame_width = 1.2 fig = plt.figure(figsize=(20, 20)) b.fig = fig x = (basis(2, 0) + (1 + 0j) * basis(2, 1)).unit() y = (basis(2, 0) + (0 + 1j) * basis(2, 1)).unit() z = (basis(2, 0) + (0 + 0j) * basis(2, 1)).unit() b.add_states([x, y, z]) for i in range(len(hv_points)): # Transform xyz to zxy coordinates tmp2 = np.vstack( [hv_points[i][:, 2], hv_points[i][:, 0], hv_points[i][:, 1]]).T tmp = tmp2.T b.add_points(tmp) # b.add_points([ 0.99619469809174555, 0.087155742747658166, 0]) # b.add_points([0.99619469809174555, -0.087155742747658166, 0]) # b.add_points(tmp) name = os.path.join(root, 'consensus_zenith_on_rectified_sphere.jpg') b.save(name=name)
def draw_center_hvps_rectified_sphere(hv_points, root): b = Bloch() b.point_color = ['m', 'k', 'g', 'b', 'w', 'c', 'y', 'r'] b.zlabel = ['$z$', ''] b.point_marker = ['o'] b.point_size = [80] b.frame_width = 1.2 fig = plt.figure(figsize=(20, 20)) b.fig = fig x = (basis(2, 0) + (1 + 0j) * basis(2, 1)).unit() y = (basis(2, 0) + (0 + 1j) * basis(2, 1)).unit() z = (basis(2, 0) + (0 + 0j) * basis(2, 1)).unit() b.add_states([x, y, z]) for i in range(len(hv_points)): # Transform xyz to zxy coordinates tmp1 = np.array([hv_points[i][2], hv_points[i][0], hv_points[i][1]]) tmp2 = np.vstack([tmp1, -tmp1]).T tmp = tmp2 b.add_points(tmp) name = os.path.join(root, 'consensus_hvps_center_on_rectified_sphere.jpg') b.save(name=name)
for epoch in range(epochs): iters = 0 diff = 1 tol = 1e-7 while jnp.all(diff > tol) and iters < max_iters: prev_weights = weights der = jnp.asarray(der_cost(*prev_weights.T, init_ket)) weights = weights + alpha * der state_hist.append(Qobj(onp.dot(rot(*weights), init_ket))) iters += 1 diff = jnp.absolute(weights - prev_weights) fidel = cost(*weights.T, init_ket) progress = [epoch + 1, fidel] if (epoch) % 1 == 0: print("Epoch: {:2f} | Fidelity: {:3f}".format(*jnp.asarray(progress))) # ## Bloch Sphere Visualization # # As we see above, we started off with a very low fidelity (~0.26). With gradient descent iterations, we progressively achieve better fidelities via better parameters, $\phi$, $\theta$, and $\omega$. To see it visually, we render our states on to a Bloch sphere. # # We see how our optimizer (Gradient Descent in this case) finds a (nearly) optimal path to walk from $|1 \rangle$ (green arrow pointing exactly south) to very close to the target state $|0 \rangle$ (brown arrow pointing exactly north), as desired. b = Bloch() b.add_states(Qobj(init_ket)) b.add_states(basis(2, 0)) for state in range(0, len(state_hist), 6): b.add_states(state_hist[state]) b.show()
class CVisualizeAnim(object): """ Class for drawing animation """ def __init__(self, fig): ################################################################# # # Initialize plotting exact plots tools # ################################################################# # p = np.linspace(-20., 20., 1000)[:, np.newaxis] # q = np.linspace(-20., 20., 1000)[np.newaxis, :] # # self.hybrid = CAnalyticQCHybrid(p, q, kT=0.5) # # img_params = dict( # extent=[q.min(), q.max(), p.min(), p.max()], # origin='lower', # cmap='seismic', # # norm=WignerNormalize(vmin=-0.1, vmax=0.1) # norm=WignerSymLogNorm(linthresh=1e-10, vmin=-0.01, vmax=0.1) # ) p = np.linspace(-25, 25, 600)[:, np.newaxis] q = np.linspace(-25, 25, 600)[np.newaxis, :] self.hybrid = CAnalyticQCHybrid(p=p, q=q, omega=1., beta=2., alpha=0.95) img_params = dict( extent=[q.min(), q.max(), p.min(), p.max()], origin='lower', cmap='seismic', # norm=WignerNormalize(vmin=-0.1, vmax=0.1) norm=WignerSymLogNorm(linthresh=1e-10, vmin=-0.01, vmax=0.1)) ################################################################# # # Initialize Pauli propagator # ################################################################# self.pauli = SplitOpPauliLike1D( X_amplitude=2. * q.max(), X_gridDIM=512, dt=0.0001, K0="0.5 * P ** 2", V0="0.5 * X ** 2", V1="0.5 * 0.95 * X ** 2", # kT=self.hybrid.kT, # parameters controlling the width of the initial wavepacket ).set_wavefunction("exp(-0.5 * X ** 2)") ################################################################# # # Initialize plotting facility # ################################################################# self.fig = fig self.fig.suptitle( "Quantum-classical hybrid $m=1$, $\omega=1$, $\\alpha=0.95$, $\\beta={:.1e}$ (a.u.) (a.u.)" .format(self.hybrid.beta)) self.ax = fig.add_subplot(221) self.ax.set_title('Classical density') # generate empty plots self.img_classical_density = self.ax.imshow([[0]], **img_params) self.ax.set_xlabel('$q$ (a.u.)') self.ax.set_ylabel('$p$ (a.u.)') ax = fig.add_subplot(222) ax.set_title('Quantum purity') self.quantum_purity_plot, = ax.plot([0., 40], [1, 0.5], label='hybrid') self.pauli_quantum_purity_plot, = ax.plot([0., 40], [1, 0.5], label='Pauli') ax.set_xlabel('time (a.u.)') ax.set_ylabel("quantum purity") ax.legend() self.time = [] self.qpurity = [] self.pauli_qpurity = [] ax = fig.add_subplot(223) ax.set_title("Coordinate distribution") self.c_coordinate_distribution, = ax.semilogy( [self.hybrid.q.min(), self.hybrid.q.max()], [1e-11, 1e0], label="hybrid") self.pauli_coordinate_distribution, = ax.semilogy( [self.hybrid.q.min(), self.hybrid.q.max()], [1e-11, 1e0], label="Pauli") ax.legend() ax.set_xlabel('$q$ (a.u.)') ax.set_ylabel('Probability density') ax = fig.add_subplot(224, projection='3d', azim=90, elev=0) self.bloch = Bloch(axes=ax) self.bloch.make_sphere() def __call__(self, frame_num): """ Draw a new frame :param frame_num: current frame number :return: image objects """ # convert the frame number to time #t = 0.05 * frame_num t = self.pauli.t # calculate the hybrid density matrix self.hybrid.calculate_D(t) # plot the classical density c_rho = self.hybrid.classical_density() self.img_classical_density.set_array(c_rho) self.ax.set_title( 'Classical density \n $t = {:.1f}$ (a.u.)'.format(t)) # plot the coordinate distribution for the classical density coordinate_marginal = c_rho.sum(axis=0) # coordinate_marginal *= self.hybrid.dp coordinate_marginal /= coordinate_marginal.max() self.c_coordinate_distribution.set_data(self.hybrid.q.reshape(-1), coordinate_marginal) coordinate_density = self.pauli.coordinate_density coordinate_density /= coordinate_density.max() self.pauli_coordinate_distribution.set_data( self.pauli.X, coordinate_density) # plot quantum purity self.time.append(t) self.qpurity.append(self.hybrid.quantum_purity()) self.quantum_purity_plot.set_data(self.time, self.qpurity) # Get the Pauli density matrix rho12 = np.sum(self.pauli.psi1 * self.pauli.psi2.conjugate()) rho_pauli = np.array( [[np.sum(np.abs(self.pauli.psi1)**2), rho12], [rho12.conjugate(), np.sum(np.abs(self.pauli.psi2)**2)]]) rho_pauli *= self.pauli.dX # plot Pauli purity self.pauli_qpurity.append(rho_pauli.dot(rho_pauli).trace().real) self.pauli_quantum_purity_plot.set_data(self.time, self.pauli_qpurity) # plot Bloch vector self.bloch.clear() self.bloch.add_states( [Qobj(self.hybrid.quantum_density()), Qobj(rho_pauli)]) self.bloch.make_sphere() # self.pauli.propagate(1000) return self.img_classical_density, self.quantum_purity_plot, self.pauli_quantum_purity_plot,\ self.bloch, self.pauli_coordinate_distribution
def draw_sphere_zenith(zenith_points, hv_points, root): b = Bloch() b.point_color = ['m', 'k', 'g', 'b', 'w', 'c', 'y', 'r'] b.zlabel = ['$z$', ''] b.point_marker = ['o'] b.point_size = [30] b.frame_width = 1.2 fig = plt.figure(figsize=(20, 20)) b.fig = fig x = (basis(2, 0) + (1 + 0j) * basis(2, 1)).unit() y = (basis(2, 0) + (0 + 1j) * basis(2, 1)).unit() z = (basis(2, 0) + (0 + 0j) * basis(2, 1)).unit() b.add_states([x, y, z]) for i in range(len(zenith_points)): # Transform xyz to zxy coordinates tmp1 = np.array( [zenith_points[i][2], zenith_points[i][0], zenith_points[i][1]]) tmp2 = np.vstack( [hv_points[i][:, 2], hv_points[i][:, 0], hv_points[i][:, 1]]).T tmp = np.vstack([tmp1, -tmp1, tmp2]).T b.add_points(tmp) # tmp1 = np.array([zenith_points[-1][2], zenith_points[-1][0], zenith_points[-1][1]]) # tmp = np.array([tmp1, -tmp1]).T # b.add_points(tmp) name = os.path.join(root, 'zenith_on_sphere.jpg') b.save(name=name)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue Jul 30 12:26:48 2019 @author: banano """ # from qutip import Bloch, Bloch3d b1 = Bloch() vec = [0,1,0] b1.add_vectors(vec) b1.vector_color = ['k'] b2 = Bloch() vec = [0,0,1] b2.add_vectors(vec) b2.vector_color = ['r'] b2.show() b1.show()
def bloch_plot2(self, filename, save=False, vecList=[], vecColour=[], view=[190, 10], points=None, folder=False, fig=False, ax=False): """ Plot the current state on the Bloch sphere using qutip. """ if points is None: # convert current state into density operator rho = np.outer(self.state.H, self.state) # get Bloch vector representation points = self.get_bloch_vec(rho) # Can only plot systems of dimension 2 at this time assert len( points ) == 3, "System dimension must be spin 1/2 for Bloch sphere plot" # create instance of 3d plot if not fig or not ax: bloch = Bloch(figsize=[9, 9], view=view) else: bloch = Bloch(fig=fig, axes=ax, view=view) # add state bloch.add_points(points) # bloch.zlabel = [r'$\left|+z\right>$',r'$\left|-z\right>$'] bloch.zlabel = [r'$\ket{+_z}$', r'$\ket{-_z}$'] # bloch.ylabel = [r'$\ket{+_y}$',r'$\ket{-_y}$'] # bloch.ylabel = [r'$\ket{+_y}$',r'$\ket{-_y}$'] # print(vecList.shape) # add vectors if vecList.shape[1] == 3: if len(vecColour) >= vecList.shape[0] and len(vecColour) > 0: bloch.vector_color = vecColour else: bloch.vector_color = ['#CC6600', 'royalblue', 'r', 'm', 'g'] bloch.add_vectors(vecList) # add field vector # bloch.add_vectors([1,0,0.15]) # bloch.add_vectors([0,0,1]) # bloch.add_vectors([1,0,0]) # render bloch sphere if not fig or not ax: bloch.render() else: # bloch.render(fig = fig, axes = ax) bloch.render(fig=fig) # save output if save is True: if not folder: folder = 'C:/Users/Boundsy/Desktop/Uni Work/PHS2360/Sim Results/' print('Bloch plot saved to ' + str(folder)) path1 = folder + str(filename) + '.png' path2 = folder + str(filename) + '.pdf' bloch.fig.savefig(path1, dpi=800, transparent=True) bloch.fig.savefig(path2, dpi=800, transparent=True) # return axes for annotations return bloch.fig, bloch.axes
def bloch_plot(self, points=None, F=None): """ Plot the current state on the Bloch sphere using qutip. """ # create instance of 3d plot bloch = Bloch(figsize=[9, 9]) bloch.add_vectors([0, 0, 1]) bloch.xlabel = ['$<F_x>$', ''] bloch.ylabel = ['$<F_y>$', ''] bloch.zlabel = ['$<F_z>$', ''] if self.spin == 'half': if points is None: # convert current state into density operator rho = np.outer(self.state.H, self.state) # get Bloch vector representation points = self.get_bloch_vec(rho) # Can only plot systems of dimension 2 at this time assert len( points ) == 3, "System dimension must be spin 1/2 for Bloch sphere plot" # create instance of 3d plot bloch = Bloch(figsize=[9, 9]) elif self.spin == 'one': #points is list of items in format [[x1,x2],[y1,y2],[z1,z2]] if points is None: points = [getStars(self.state)] bloch.point_color = ['g', 'r', 'b'] #ensures point and line are same colour bloch.point_marker = ['o', 'd', 'o'] #bloch.point_color = ['g','r'] #ensures point and line are same colour #bloch.point_marker = ['o','d'] for p in points: bloch.add_points([p[0][0], p[1][0], p[2][0]]) bloch.add_points([p[0][1], p[1][1], p[2][1]]) bloch.add_points(p, meth='l') ''' bloch.point_color = ['b','b'] #ensures point and line are same colour bloch.point_marker = ['o','o'] for p in points: bloch.add_points(p) bloch.add_points(p, meth='l') ''' # add state #bloch.render(bloch.fig, bloch.axes) #bloch.fig.savefig("bloch.png",dpi=600, transparent=True) bloch.show()
def maj_vid(self, points): #takes screenshots of majorana stars over time to produce vid if points is None: points = [getStars(self.state)] i = 0 for p in points: bloch = Bloch(figsize=[9, 9]) bloch.xlabel = ['$<F_x>$', ''] bloch.ylabel = ['$<F_y>$', ''] bloch.zlabel = ['$<F_z>$', ''] bloch.point_color = ['g', 'r', 'b'] #ensures point and line are same colour bloch.point_marker = ['o', 'd', 'o'] bloch.add_points([p[0][0], p[1][0], p[2][0]]) bloch.add_points([p[0][1], p[1][1], p[2][1]]) bloch.add_points(p, meth='l') bloch.render(bloch.fig, bloch.axes) bloch.fig.savefig( "bloch" + str(i).zfill(int(np.ceil(np.log10(len(points))))) + ".png", dpi=600, transparent=False) i += 1
def __init__(self, fig): ################################################################# # # Initialize plotting exact plots tools # ################################################################# # p = np.linspace(-20., 20., 1000)[:, np.newaxis] # q = np.linspace(-20., 20., 1000)[np.newaxis, :] # # self.hybrid = CAnalyticQCHybrid(p, q, kT=0.5) # # img_params = dict( # extent=[q.min(), q.max(), p.min(), p.max()], # origin='lower', # cmap='seismic', # # norm=WignerNormalize(vmin=-0.1, vmax=0.1) # norm=WignerSymLogNorm(linthresh=1e-10, vmin=-0.01, vmax=0.1) # ) p = np.linspace(-25, 25, 600)[:, np.newaxis] q = np.linspace(-25, 25, 600)[np.newaxis, :] self.hybrid = CAnalyticQCHybrid(p=p, q=q, omega=1., beta=2., alpha=0.95) img_params = dict( extent=[q.min(), q.max(), p.min(), p.max()], origin='lower', cmap='seismic', # norm=WignerNormalize(vmin=-0.1, vmax=0.1) norm=WignerSymLogNorm(linthresh=1e-10, vmin=-0.01, vmax=0.1)) ################################################################# # # Initialize Pauli propagator # ################################################################# self.pauli = SplitOpPauliLike1D( X_amplitude=2. * q.max(), X_gridDIM=512, dt=0.0001, K0="0.5 * P ** 2", V0="0.5 * X ** 2", V1="0.5 * 0.95 * X ** 2", # kT=self.hybrid.kT, # parameters controlling the width of the initial wavepacket ).set_wavefunction("exp(-0.5 * X ** 2)") ################################################################# # # Initialize plotting facility # ################################################################# self.fig = fig self.fig.suptitle( "Quantum-classical hybrid $m=1$, $\omega=1$, $\\alpha=0.95$, $\\beta={:.1e}$ (a.u.) (a.u.)" .format(self.hybrid.beta)) self.ax = fig.add_subplot(221) self.ax.set_title('Classical density') # generate empty plots self.img_classical_density = self.ax.imshow([[0]], **img_params) self.ax.set_xlabel('$q$ (a.u.)') self.ax.set_ylabel('$p$ (a.u.)') ax = fig.add_subplot(222) ax.set_title('Quantum purity') self.quantum_purity_plot, = ax.plot([0., 40], [1, 0.5], label='hybrid') self.pauli_quantum_purity_plot, = ax.plot([0., 40], [1, 0.5], label='Pauli') ax.set_xlabel('time (a.u.)') ax.set_ylabel("quantum purity") ax.legend() self.time = [] self.qpurity = [] self.pauli_qpurity = [] ax = fig.add_subplot(223) ax.set_title("Coordinate distribution") self.c_coordinate_distribution, = ax.semilogy( [self.hybrid.q.min(), self.hybrid.q.max()], [1e-11, 1e0], label="hybrid") self.pauli_coordinate_distribution, = ax.semilogy( [self.hybrid.q.min(), self.hybrid.q.max()], [1e-11, 1e0], label="Pauli") ax.legend() ax.set_xlabel('$q$ (a.u.)') ax.set_ylabel('Probability density') ax = fig.add_subplot(224, projection='3d', azim=90, elev=0) self.bloch = Bloch(axes=ax) self.bloch.make_sphere()
@author: wittek """ from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from qutip import Bloch from graphics_utils import initialize_graphics colors = initialize_graphics() fig = plt.figure() axes = Axes3D(fig) axes.grid = True axes.axis("off") axes.set_axis_off() b=Bloch() b.fig = fig b.axes = axes #b.fig = fig #b.frame_width=1 b.sphere_color = 'white' b.sphere_alpha = 0.1 #b.size = [10, 10] b.make_sphere() plt.savefig('./bloch_sphere.svg',bbox_inches='tight') #b.show() #b.save('bloch_sphere.pdf',format='pdf')
def create_gif(qstates, qstart, qtarget, name): ''' Inputs: # qstates: list of states as np.arrays # qstart, qtarget: respectively the target ans start state # name: name of the output gif ''' b = Bloch() duration = 5 #framerate images = [] for (qstate, i) in zip(qstates, range(0, len(qstates))): b.clear() b.point_color = "r" # options: 'r', 'g', 'b' etc. b.point_marker = ['o'] b.point_size = [40] b.add_states(qutip_qstate(qstart)) b.add_states(qutip_qstate(qtarget)) for previous in range(i): b.add_states(qutip_qstate(qstates[previous]), "point") #plots previous visited states as points b.add_states(qutip_qstate(qstate)) filename = 't.png' b.save(filename) images.append(imageio.imread(filename)) imageio.mimsave(name, images, 'GIF', fps=duration)
def PlotBlochState(state): bsph = Bloch() bsph.add_vectors(StateToBloch(state)) return bsph.show()