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 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 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 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)
print('-2-') input('Press ENTER to continue.') # %% -3- # Achsen koennen auch umbenannt werden # dazu kann Latex-Code verwendet werden jedoch muss beachtet werden, # dass fuer Latex-Code \ --> \\ verwendet werden sollte b.xlabel = ["$\\left|45^\\circ \\right>$", "$\\left|-45^\\circ \\right>$"] b.ylabel = ["$\\left|\\sigma^+\\right>$", "$\\left|\\sigma^- \\right>$"] b.zlabel = ["$\\left|H\\right>$", "$\\left|V\\right>$"] b.show() print('-3-') input('Press ENTER to continue.') # %% -4- b.clear() # Loescht alle Zustaende auf der Blochkugel # behaltet jedoch Einstellungen wie z.B. Achsenbeschriftung # Normierung eines Vektors v = [1 / math.sqrt(3), 1 / math.sqrt(3), -1 / math.sqrt(3)] w = [1, -1, 1] / np.sqrt(3) # automatische Normierung eines Vektors # mittel der numpy Library # [email protected] ist dabei eine Vektor-Vektor Multiplikation # wobei der hintere Vektor zuerst transponiert werden muss ('.T) u = np.array([3, 0, 1]) u = u / np.sqrt(u @ u.T) # Es koennen auch mehrere Vektoren gleichzeitig hinzugefuegt werden b.add_vectors([v, w, u])
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,
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