def test_lapack(): import scipy.linalg.lapack as lapak import numpy as np A = np.zeros((2, 2), dtype=complex) A[0][0] = 0.0 A[0][1] = 0.0 - 1j A[1][0] = 0.0 + 1j A[1][1] = 0.0 eig = lapak.zheevd(A) # in the first array are the eigenvalues print(eig[0][0], eig[0][1]) # and in the 2nd array are the eigenvector, as the columns for j in range(0, 2): print(eig[1][j][0]) print(eig[1][0][0], eig[1][1][0])
def simulate_SPB( R_t=None, #Position of molecule as function of time in XYZ coordinate system T=None, #Total time for which molecule is simulated E_R=None, B_R=None, #Spatial profiles of the static electric and magnetic fields microwave_fields=None, #List of microwave fields for the simulation initial_states=None, #Initial states for the system (can simulate multiple initial states with little additional cost) final_state=None, #Desired final state after the state preparation N_steps=int(1e4), #Number of timesteps for time-evolution H_path=None, #Path to Hamiltonian if not the default verbose=False, #Whether or not need to print a bunch of output plots=False #Whether or not to save plots ): """ Function that simulates state preparation B in CeNTREX. The structure of the cod is as follows: 0. Define the position of the molecule as a function of time. Position is defined in the capitalized coordinate system(XYZ where Z is along the beamline). Helps with defining time-dependence of e.g. microwave intensities and electric and magnetic fields. 1. Define electric and magnetic fields as a function of time. This is done based on spatial profiles of the EM-fields. The coordinate system for the direction of the the fields is different from the coordinate system used for defining the spatial profile: - For defining spatial profile use XYZ (Z is along beamline) - For defining direction of fields use xyz where z is along the electric field in the Main Interaction region For electric fields should use V/cm and for B-fields G. 2. Define slowly time-varying Hamiltonian. This is the Hamiltonian due to the internal dynamics of the molecule and the external DC electric and magnetic fields (maybe split into internal Hamiltonian and EM-field Hamiltonian?) 3. Define the microwave Hamiltonian. Simply the couplings due to the microwaves. Rotating wave approximation is applied and the rotating frame is used. 4. Time-evolve the system by using matrix exponentiation for solving Schroedinger eqn. 5. Make plots etc. if needed """ ### 0. Position as function of time #Check if position as function of time was provided, otherwise use a default trajectory if R_t is None: def molecule_position(t, r0, v): """ Functions that returns position of molecule at a given time for given initial position and velocity. inputs: t = time in seconds r0 = position of molecule at t = 0 in meters v = velocity of molecule in meters per second returns: r = position of molecule in metres """ r = r0 + v * t return r #Define the position of the molecule as a function of time r0 = np.array((0, 0, -100e-3)) v = np.array((0, 0, 200)) R_t = lambda t: molecule_position(t, r0, v) #Define the total time for which the molecule is simulated z0 = r0[2] vz = v[2] T = np.abs(2 * z0 / vz) ### 1. Electric and magnetic fields as function of time #Here we determine the E- and B-fields as function of time based on provided spatial #profiles of the fields #Electric field: if E_R is not None: E_t = lambda t: E_R(R_t(t)) #If spatial profile is not provided, assume a uniform 50 V/cm along z else: E_t = lambda t: np.array((0, 0, 50.)) #Magnetic field: if B_R is not None: B_t = lambda t: B_R(R_t(t)) #If spatial profile is not provided assume uniform 0.001 G along z else: B_t = lambda t: np.array((0, 0, 0.001)) ### 2. Slowly time-varying Hamiltonian #Make list of quantum numbers that defines the basis for the matrices QN = make_QN(0, 3, 1 / 2, 1 / 2) dim = len(QN) #Get H_0 from file (H_0 should be in rad/s) if H_path is None: H_0_EB = make_hamiltonian( "./hamiltonians/TlF_X_state_hamiltonian0to3_2020_03_03.py") else: H_0_EB = make_hamiltonian(H_path) #Calculate the field free Hamiltonian H_0 = H_0_EB(np.array((0, 0, 0)), np.array((0, 0, 0))) #Calculate part of the Hamiltonian that is due to electromagnetic fields H_EB_t = lambda t: H_0_EB(E_t(t), B_t(t)) - H_0 #Check that H_0 is hermitian H_test = H_0 + H_EB_t(T / 2) is_herm = np.allclose(H_test, np.conj(H_test.T)) if not is_herm: print("H_0 is non-hermitian!") ### 3. Microwave Hamiltonians #Generate the part of the Hamiltonian that describes the effect of the microwave #field(s) if microwave_fields is not None: counter = 0 #Containers for microwave coupling Hamiltonians and the microwave frequencies microwave_couplings = [] omegas = [] D_mu = np.zeros(H_0.shape) for microwave_field in microwave_fields: if verbose: counter += 1 print("\nMicrowave {:}:".format(counter)) #Find out where the peak intensity of the field is located Z_peak = microwave_field.z0 R_peak = np.array((0, 0, Z_peak)) #Determine the Hamiltonian at z0 H_peak = H_0_EB(E_R(R_peak), B_R(R_peak)) #Find the exact ground and excited states for the field at z_peak microwave_field.find_closest_eigenstates(H_peak, QN) #Calculate angular part of matrix element for main transition ME_main = microwave_field.calculate_ME_main( pol_vec=microwave_field.p_t( 0)) #Angular part of ME for main transition #Find the coupling matrices due to the microwave H_list = microwave_field.generate_couplings(QN) H_list = [H / ME_main for H in H_list] Hu_list = [np.triu(H) for H in H_list] Hl_list = [np.tril(H) for H in H_list] #Find some necessary parameters and then define the coupling matrix as a function of time Omega_t = microwave_field.find_Omega_t( R_t) #Time dependence of Rabi rate p_t = microwave_field.p_t #Time dependence of polarization of field omega = np.abs(microwave_field.calculate_frequency( H_peak, QN)) #Calculate frequency of transition omegas.append(omega) D_mu += microwave_field.generate_D( np.sum(omegas), H_peak, QN) #Matrix that shifts energies for rotating frame #Define the coupling matrix as function of time def H_mu_t_func(Hu_list, Hl_list, p_t, Omega_t, t): return ( 1 / 2 * Omega_t(t) * (Hu_list[0] * p_t(t)[0] + Hu_list[1] * p_t(t)[1] + Hu_list[2] * p_t(t)[2] + Hl_list[0] * p_t(t)[0].conj() + Hl_list[1] * p_t(t)[1].conj() + Hl_list[2] * p_t(t)[2].conj())) H_mu_t = partial(H_mu_t_func, Hu_list, Hl_list, p_t, Omega_t) microwave_couplings.append(H_mu_t) #Print output for checks if verbose: print("ME_main = {:.3E}".format(ME_main)) print("muW frequency: {:.9E} GHz".format(omega / (2 * np.pi * 1e9))) print("ground_main:") ground_main = microwave_field.ground_main ground_main.print_state() print("excited_main:") excited_main = microwave_field.excited_main excited_main.print_state() ME = excited_main.state_vector(QN).conj().T @ H_mu_t( T / 2) @ ground_main.state_vector(QN) print("Omega_T/2 = {:.3E}".format(ME / (2 * np.pi))) #Generate function that gives couplings due to all microwaves def H_mu_tot_t(t): H_mu_tot = microwave_couplings[0](t) if len(microwave_couplings) > 1: for H_mu_t in microwave_couplings[1:]: H_mu_tot = H_mu_tot + H_mu_t(t) return H_mu_tot else: H_mu_tot_t = lambda t: np.zeros(H_0.shape) if verbose: time = timeit.timeit("H_mu_tot_t(T/2)", number=10, globals=locals()) / 10 print("Time to generate H_mu_tot_t: {:.3e} s".format(time)) H_test = H_mu_tot_t(T / 2) non_zero = H_test[np.abs(H_test) > 0].shape[0] print("Non-zero elements at T/2: {}".format(non_zero)) print("Rotating frame energy shifts:") print(np.diag(D_mu) / (2 * np.pi * 1e9)) print(np.max(np.abs(H_mu_tot_t(T / 2))) / (2 * np.pi)) ### 4. Time-evolution #Now time-evolve the system by repeatedly applying the time-evolution operator with small # timestep #Make array of times at which time-evolution is performed t_array = np.linspace(0, T, N_steps) #Calculate timestep dt = T / N_steps #Set the state vector to the initial state H_t0 = H_0 + H_EB_t(0) psis = np.zeros((len(initial_states), H_t0.shape[0]), dtype=complex) ini_index = np.zeros(len(initial_states)) for i, initial_state in enumerate(initial_states): initial_state = find_closest_state(H_t0, initial_state, QN) psis[i, :] = initial_state.state_vector(QN) #Also figure out the state indices that correspond to the initial states ini_index[i] = find_state_idx_from_state(H_t0, initial_state, QN) #Set up containers to store results state_probabilities = np.zeros( (len(initial_states), len(t_array), H_t0.shape[0])) state_energies = np.zeros((len(t_array), H_t0.shape[0])) psi_t = np.zeros((len(initial_states), len(t_array), H_t0.shape[0]), dtype=complex) #Initialize the reference matrix of eigenvectors E_ref, V_ref = np.linalg.eigh(H_t0) E_ref_0 = E_ref V_ref_0 = V_ref #Loop over timesteps to evolve system in time for i, t in enumerate(tqdm(t_array)): #Calculate the necessary Hamiltonians at this time H_t = H_0 + H_EB_t(t) H_mu = H_mu_tot_t(t) #Diagonalize H_t and transform to that basis D_t, V_t, info_t = zheevd(H_t) if info_t != 0: print("zheevd didn't work for H_0") D_t, V_t = np.linalg.eigh(H_t) #Make intermediate hamiltonian by transforming H to the basis where H_0 is diagonal H_I = V_t.conj().T @ H_t @ V_t #Sort the eigenvalues so they are in ascending order index = np.argsort(D_t) D_t = D_t[index] V_t = V_t[:, index] #Find the microwave coupling matrix in the new basis: H_mu = V_t.conj().T @ H_mu @ V_t #Make total intermediate hamiltonian H_I = H_I + H_mu #Transform H_I to the rotating basis H_R = H_I + D_mu #Diagonalize H_R D_R, V_R, info_R = zheevd(H_R) if info_R != 0: print("zheevd didn't work for H_R") D_R, V_R = np.linalg.eigh(H_R) #Reorder the eigenstates so that a given index corresponds to the same "adiabatic" state energies, evecs = D_t, V_t energies, evecs = reorder_evecs(evecs, energies, V_ref) #Propagate state vector in time propagator = V_t @ V_R @ np.diag(np.exp( -1j * D_R * dt)) @ V_R.conj().T @ V_t.conj().T for j in range(0, len(initial_states)): psis[j, :] = propagator @ psis[j, :] #Calculate the overlap of the state vector with all of the eigenvectors of the Hamiltonian overlaps = np.dot(np.conj(psis[j, :]).T, evecs) probabilities = overlaps * np.conj(overlaps) #Store the probabilities, energies and the state vector state_probabilities[j, i, :] = np.real(probabilities) psi_t[j, i, :] = psis[j, :].T state_energies[i, :] = energies V_ref = evecs #Find the exact form of the desired final state and calculate overlap with state vector final_state = find_closest_state(H_0 + H_EB_t(T), final_state, QN) final_state_vec = final_state.state_vector(QN) if len(initial_states) == 1: overlap = final_state_vec.conj().T @ psis[0, :] probability = np.abs(overlap)**2 if verbose: print( "Probability to end up in desired final state: {:.3f}".format( probability)) print("desired final state|fin> = ") final_state.print_state() return t_array, state_probabilities, V_ref, QN
#Set system to its initial state psi = initial_state_vec #Loop over timesteps to evolve system in time for i in tqdm(range(0, N_steps)): #Calculate the time t = (i + 1) * dt #Calculate the necessary Hamiltonians at this time H_0 = H_0_t(t) H_mu1_i = H_mu1(t) H_mu2_i = H_mu2(t) #Diagonalize H_0 and transform to that basis D_0, V_0, info_0 = zheevd(H_0) if info_0 != 0: print("zheevd didn't work for H_0") D_0, V_0 = np.linalg.eigh(H_0) #Make intermediate hamiltonian by transforming H to the basis where H_0 is diagonal H_I = V_0.conj().T @ H_0 @ V_0 #Sort the eigenvalues so they are in ascending order index = np.argsort(D_0) D_0 = D_0[index] V_0 = V_0[:, index] #Find the microwave coupling matrix: H_mu1_i = V_0.conj().T @ H_mu1_i @ V_0 * np.exp(1j * omega_mu1 * t) H_mu1_i = block_diag(H_mu1_i[0:16, 0:16], np.zeros( (dim - 16, dim - 16)))
def propagate_state(lens_state_vec, H, QN, B, E, T, N_steps, save_fields=False): """ Function that propagates the state of a quantum system defined by Hamiltonian H from t = 0 to t=T. The initial state of the system is the eigenstate of the Hamiltonian H that has the highest overlap with initial_state_vec. The Hamiltonian may include time-dependent EM fields defined by E and B. Note: the function assumes that the E- and B-fields at times t = 0 and t = T are the same. This is done in order to be able to compare the initial and final state vectors. inputs: initial_state_vec = defines initial state of system H = Hamiltonian of system as function of B and E QN = list that defines the basis of the Hamiltonian and state vectors B = magnetic field as function of time E = electric field as function of time T = total time for which to propagate the state save_fields = Boolean that determines if EM fields as function of time should be saved outputs: probability = overlap**2 of the initial and final state vectors """ #Find the initial state by diagonalizing the Hamiltonian at t=0 and finding #which of the eigenstates is closest to initial_state_vec #Diagonalize H energies0, evecs0 = np.linalg.eigh(H(E(0), B(0))) #Find the index of the state corresponding to the lens state index_ini = find_state_idx(lens_state_vec, evecs0, n=1) #Find the exact state vector of the initial state initial_state_vec = evecs0[:, index_ini:index_ini + 1] #Define initial state psi = initial_state_vec #If fields are to be saved, initialize containers if save_fields: E_field = np.zeros((3, N_steps)) B_field = np.zeros((3, N_steps)) t_array = np.zeros((N_steps)) E_field[:, 0] = E(0) B_field[:, 0] = B(0) #Calculate timestep dt = T / N_steps #Loop over timesteps to evolve system in time: t = 0 for n in range(0, N_steps): #Calculate time for this step t += dt #Calculate fields E_t = E(t) B_t = B(t) #Evaluate hamiltonian at this time H_i = H(E_t, B_t) #Diagonalize the hamiltonian D, V, info = zheevd(H_i) #If zheevd doesn't converge, use numpy instead if info != 0: D, V = np.linalg.eigh(H_i) #Propagate the state vector psi = V @ np.diag(np.exp(-1j * D * dt)) @ np.conj(V.T) @ psi #If fields are saved, add to array if save_fields: E_field[:, n] = E_t B_field[:, n] = B_t t_array[n] = t #Determine which eigenstate of the Hamiltonian corresponds to the lens state #in the final values of the E- and B-fields #Diagonalize H energiesT, evecsT = np.linalg.eigh(H(E(t), B(t))) #Find the index of the state corresponding to the lens state index_fin = find_state_idx(lens_state_vec, evecsT, n=1) #Find the exact state vector that corresponds to the lens state in the given #E and B field final_state_vec = evecsT[:, index_fin:index_fin + 1] #Calculate overlap between the initial and final state vector overlap = np.dot(np.conj(psi).T, final_state_vec) probability = np.abs(overlap)**2 #Initialize dictionary to store results results_dict = {"probability": probability} if save_fields: results_dict["E_field"] = E_field results_dict["B_field"] = B_field results_dict["t_array"] = t_array #Return probability of staying in original state return results_dict
def von_neumann(rho): d = rho.shape[0] b = lapak.zheevd(rho) VnE = shannon(b[0]) return VnE
def simulate_RAP(r0=np.array((0, 0, -100e-3)), v=np.array((0, 0, 200)), ring_z1=-71.4375e-3, ring_z2=85.725e-3, ring_V1=4e3, ring_V2=3.6e2, B_earth=np.array((0, 0, 0)), Omega1=2 * np.pi * 200e3, Omega2=2 * np.pi * 200e3, Delta=0, delta=0, z0_mu1=0.0, z0_mu2=0.03, N_steps=1e5): """ Function that runs the rapid adiabatic passage simulation for the given parameters inputs: r0 = initial position of molecule [m] v = velocity of molecule (assumed to be constant) [m/s] ring_z1 = position of first ring electrode [m] ring_z2 = position of second ring electrode [m] ring_V1 = voltage on ring 1 [V] ring_V2 = voltage on ring 2 [V] B_earth = magnetic field of earth [G] Omega1 = Rabi rate for microwave 1 [rad/s] Omega2 = Rabi rate for microwave 2 [rad/s] Delta = 1-photon detuning [rad/s] delta = 2-photon detuning [rad/s] z0_mu1 = z-position of microwave 1 [m] z0_mu2 = z-position of microwave 2 [m] returns: probability = probability of being in the target final state """ #Define the position of the molecule as a fucntion of time r0 = np.array((0, 0, -100e-3)) v = np.array((0, 0, 200)) r_t = lambda t: molecule_position(t, r0, v) #Define the total time for which the molecule is simulated z0 = r0[2] vz = v[2] T = np.abs(2 * z0 / vz) #Define electric field as function of position E_r = lambda r: (E_field_ring(r, z0=ring_z1, V=ring_V1) + E_field_ring( r, z0=ring_z2, V=ring_V2)) #Next define electric field as function of time E_t = lambda t: E_r(r_t(t)) #Define the magnetic field B_r = lambda r: B_earth B_t = lambda t: B_r(r_t(t)) #Make list of quantum numbers that defines the basis for the matrices QN = make_QN(0, 3, 1 / 2, 1 / 2) #Get H_0 from file (H_0 should be in rad/s) H_0_EB = make_hamiltonian("../utility/TlF_X_state_hamiltonian0to3.py") #Make H_0 as function of time H_0_t = lambda t: H_0_EB(E_t(t), B_t(t)) dim = H_0_t(0).shape[0] #Fetch the initial state from file with open("../utility/initial_state0to3.pickle", 'rb') as f: initial_state_approx = pickle.load(f) #Fetch the intermediate state from file with open("../utility/intermediate_state0to3.pickle", "rb") as f: intermediate_state_approx = pickle.load(f) #Fetch the final state from file with open("../utility/final_state0to3.pickle", 'rb') as f: final_state_approx = pickle.load(f) #Find the eigenstate of the Hamiltonian that most closely corresponds to initial_state at T=0. This will be used as the #actual initial state initial_state = find_closest_state(H_0_t(0), initial_state_approx, QN) initial_state_vec = initial_state.state_vector(QN) #Find the eigenstate of the Hamiltonian that most closely corresponds to final_state_approx at t=T. This will be used to #determine what fraction of the molecules end up in the correct final state final_state = find_closest_state(H_0_t(T), final_state_approx, QN) final_state_vec = final_state.state_vector(QN) intermediate_state = find_closest_state(H_0_t(0), intermediate_state_approx, QN) intermediate_state_vec = intermediate_state.state_vector(QN) #Find the energies of ini and int so that suitable microwave frequency for mu1 can be calculated H_z0 = H_0_EB(E_r(np.array((0, 0, z0_mu1))), B_r(np.array((0, 0, z0_mu1)))) D_z0, V_z0 = np.linalg.eigh(H_z0) ini_index = find_state_idx_from_state(H_z0, initial_state_approx, QN) int_index = find_state_idx_from_state(H_z0, intermediate_state_approx, QN) fin_index = find_state_idx_from_state(H_z0, final_state_approx, QN) #Note: the energies are in 2*pi*[Hz] E_ini = D_z0[ini_index] E_int = D_z0[int_index] omega_mu1 = E_int - E_ini #Find the energies of int and fin so that suitable microwave frequency for mu2 can be calculated H_z0 = H_0_EB(E_r(np.array((0, 0, z0_mu2))), B_r(np.array((0, 0, z0_mu2)))) D_z0, V_z0 = np.linalg.eigh(H_z0) ini_index = find_state_idx_from_state(H_z0, initial_state_approx, QN) int_index = find_state_idx_from_state(H_z0, intermediate_state_approx, QN) fin_index = find_state_idx_from_state(H_z0, final_state_approx, QN) #Note: the energies are in 2*pi*[Hz] E_int = D_z0[int_index] E_fin = D_z0[fin_index] omega_mu2 = E_fin - E_int #Define dipole moment of TlF D_TlF = 2 * np.pi * 4.2282 * 0.393430307 * 5.291772e-9 / 4.135667e-15 # [rad/s/(V/cm)] #Calculate the approximate power required for each set of microwaves to get a specified peak Rabi rate for the transitions ME1 = np.abs( calculate_microwave_ED_matrix_element_mixed_state_uncoupled( initial_state_approx, intermediate_state_approx, reduced=False)) ME2 = np.abs( calculate_microwave_ED_matrix_element_mixed_state_uncoupled( intermediate_state_approx, final_state_approx, reduced=False)) P1 = calculate_power_needed(Omega1, ME1) P2 = calculate_power_needed(Omega2, ME2) #Define the microwave electric field as a function of time E_mu1_t = lambda t: microwave_field( r_t(t), power=P1, z0=z0_mu1, fwhm=1.1 * 0.0254) E_mu2_t = lambda t: microwave_field( r_t(t), power=P2, z0=z0_mu2, fwhm=1.1 * 0.0254) #Define matrix for microwaves coupling J = 0 to 1 J1_mu1 = 0 J2_mu1 = 1 omega_mu1 = omega_mu1 + Delta H1 = make_H_mu(J1_mu1, J2_mu1, omega_mu1, QN) H_mu1 = lambda t: H1(0) * D_TlF * E_mu1_t(t) #Define matrix for microwaves coupling J = 1 to 2 J1_mu2 = 1 J2_mu2 = 2 omega_mu2 = omega_mu2 + delta - Delta H2 = make_H_mu(J1_mu2, J2_mu2, omega_mu2, QN) H_mu2 = lambda t: H2(0) * D_TlF * E_mu2_t(t) #Make the matrices used to transform to rotating frame U1, D1 = make_transform_matrix(J1_mu1, J2_mu1, omega_mu1, QN) U2, D2 = make_transform_matrix(J1_mu2, J2_mu2, omega_mu2 + omega_mu1, QN) U = lambda t: U1(t) @ U2(t) D = lambda t: D1 + D2 #Define number of timesteps and make a time-array t_array = np.linspace(0, T, N_steps) #Calculate timestep dt = T / N_steps #Set system to its initial state psi = initial_state_vec #Loop over timesteps to evolve system in time for i, t in enumerate(t_array): #Calculate the necessary Hamiltonians at this time H_0 = H_0_t(t) H_mu1_i = H_mu1(t) H_mu2_i = H_mu2(t) #Diagonalize H_0 and transform to that basis D_0, V_0, info_0 = zheevd(H_0) if info_0 != 0: print("zheevd didn't work for H_0") D_0, V_0 = np.linalg.eigh(H_0) #Make intermediate hamiltonian by transforming H to the basis where H_0 is diagonal H_I = V_0.conj().T @ H_0 @ V_0 #Sort the eigenvalues so they are in ascending order index = np.argsort(D_0) D_0 = D_0[index] V_0 = V_0[:, index] #Find the microwave coupling matrix: H_mu1_i = V_0.conj().T @ H_mu1_i @ V_0 * np.exp(1j * omega_mu1 * t) H_mu1_i = block_diag(H_mu1_i[0:16, 0:16], np.zeros( (dim - 16, dim - 16))) H_mu1_i = np.triu(H_mu1_i) + np.triu( H_mu1_i).conj().T #+ np.diag(np.diag(H1)) H_mu2_i = V_0.conj().T @ H_mu2_i @ V_0 * np.exp(1j * omega_mu2 * t) H_mu2_i = block_diag(np.zeros((4, 4)), H_mu2_i[4:36, 4:36], np.zeros((dim - 36, dim - 36))) H_mu2_i = np.triu(H_mu2_i) + np.triu( H_mu2_i).conj().T #+ np.diag(np.diag(H1)) #Make total hamiltonian H_I = H_I + H_mu1_i + H_mu2_i #Find transformation matrices for rotating basis U_t = U(t) D_t = D(t) #Transform H_I to the rotating basis H_R = U_t.conj().T @ H_I @ U_t + D_t #Diagonalize H_R D_R, V_R, info_R = zheevd(H_R) if info_R != 0: print("zheevd didn't work for H_R") D_R, V_R = np.linalg.eigh(H_R) #Propagate state vector in time psi = V_0 @ V_R @ np.diag(np.exp( -1j * D_R * dt)) @ V_R.conj().T @ V_0.conj().T @ psi psi_fin = vector_to_state(psi, QN) #Calculate overlap between final target state and psi overlap = final_state_vec.conj().T @ U(T) @ psi probability = np.abs(overlap)**2 return probability
def neumann(d, rho): import scipy.linalg.lapack as lapak b = lapak.zheevd(rho) VnE = shannon(d, b[0]) return VnE
def neumann(d, rho): # Returns the von Neumann entropy of a dxd density matrix rho import scipy.linalg.lapack as lapak b = lapak.zheevd(rho) VnE = shannon(d, b[0]) return VnE
def bdsCorr(): from numpy import zeros from math import acos, sqrt c1 = -0.9 c2 = -0.8 c3 = -0.8 from states import rho_bds rho = zeros((4, 4), dtype=complex) rho = rho_bds(c1, c2, c3) eig = lapak.zheevd(rho) print('eigens:', eig[0][0], eig[0][1], eig[0][2], eig[0][3]) import discord dp = 0.05 d = 20 * (1 - 0) di = zeros(d) cc = zeros(d) mi = zeros(d) diE = zeros(d) ccE = zeros(d) miE = zeros(d) rhopE = zeros((4, 4), dtype=complex) pv = zeros(d) rhop = zeros((4, 4), dtype=complex) import kraus import tomography as tomo p = -dp for j in range(0, d): p = p + dp # rhop = kraus.rho_pd(p, rho) # ; print(rhop) # teste para ver a cara do rhop c1p = c1 * (1.0 - p)**2 c2p = c2 * (1.0 - p)**2 c3p = c3 print("p = ", p, ", c1p=", c1p, ", c2p=", c2p, ", c3p=", c3p) p00 = (1.0 + c1p - c2p + c3p) / 4.0 p01 = (1.0 + c1p + c2p - c3p) / 4.0 p10 = (1.0 - c1p + c2p + c3p) / 4.0 p11 = (1.0 - c1p - c2p - c3p) / 4.0 print("p00 = ", p00, ", p01=", p01, ", p10=", p10, ", p11=", p11) theta = 2.0 * acos(sqrt(p00 + p01)) alpha = 2.0 * acos(sqrt(p00 + p10)) print("theta = ", theta, ", alpha", alpha) print("") rhop = rho_bds(c1p, c2p, c3p) pv[j] = p di[j] = discord.discord_oz_bds(rhop) cc[j] = discord.ccorr_hv_bds(rhop) mi[j] = discord.mi_bds(rhop) '''sj = str(j) path1 = '/home/jonasmaziero/Dropbox/Research/IBM_QC/' path2 = 'tomography/BDS/bell_diagonal/' path = path1 + path2 + sj + '/' rhopE = tomo.tomo_2qb(path) diE[j] = discord.discord_oz_bds(rhopE) ccE[j] = discord.ccorr_hv_bds(rhopE) miE[j] = discord.mi_bds(rhopE) eigE = lapak.zheevd(rhopE) print('eigensE:', eigE[0][0], eigE[0][1], eigE[0][2], eigE[0][3]) print('di =', di[j], ' diE = ', diE[j])''' plt.plot(pv, di, label='di') plt.plot(pv, cc, label='cc') plt.plot(pv, mi, label='im') plt.xlabel('p') plt.legend() plt.show()