def test_EntropyConditional(): "Entropy: Conditional entropy" # test_ S(A,B|C,D)<=S(A|C)+S(B|D) rhos = [ rand_dm(16, dims=[[2, 2, 2, 2], [2, 2, 2, 2]], pure=True) for k in range(20) ] for ABCD in rhos: AC = ptrace(ABCD, [0, 2]) BD = ptrace(ABCD, [1, 3]) assert_equal( entropy_conditional(ABCD, [2, 3]) <= (entropy_conditional(AC, 1) + entropy_conditional(BD, 1)), True) # test_ S(A|B,C)<=S(A|B) rhos = [ rand_dm(8, dims=[[2, 2, 2], [2, 2, 2]], pure=True) for k in range(20) ] for ABC in rhos: AB = ptrace(ABC, [0, 1]) assert_equal( entropy_conditional(ABC, [1, 2]) <= entropy_conditional(AB, 1), True)
def timescan(self, nT=100, **kwargs): # do a gate dynamics time scan # !!! If parameters are not separately specified, chooses optimal gate parameters # for programmed gate detuning self.set_custom_parameters(**kwargs) # initialize result vectors end_populations_dndn = [] end_populations_upup = [] end_populations_updn = [] end_populations_dnup = [] fidelities = [] times, final_rhos = self.do_gate(nT=nT) for ii in range(len(times)): end_populations_upup.append(expect(self.spin_upup, final_rhos[ii])) end_populations_dndn.append(expect(self.spin_dndn, final_rhos[ii])) end_populations_updn.append(expect(self.spin_updn, final_rhos[ii])) end_populations_dnup.append(expect(self.spin_dnup, final_rhos[ii])) rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) fidelities.append( fidelity(rho_target, ptrace(final_rhos[ii], [0, 1]))**2) return times, end_populations_upup, end_populations_dndn, end_populations_updn, end_populations_dnup, fidelities
def detuning_scan(self, delta_g_vec, delta_g_0=None, **kwargs): # do a gate dynamics frequency scan # !!! If parameters are not separately specified, chooses optimal gate parameters # for programmed gate detuning self.set_custom_parameters(delta_g=delta_g_0, **kwargs) # initialize result vectors end_populations_dndn = [] end_populations_upup = [] end_populations_updn = [] end_populations_dnup = [] fidelities = [] for delta_g in delta_g_vec: self.set_gate_detuning(delta_g) times, final_rhos = self.do_gate(nT=2) end_populations_upup.append(expect(self.spin_upup, final_rhos[-1])) end_populations_dndn.append(expect(self.spin_dndn, final_rhos[-1])) end_populations_updn.append(expect(self.spin_updn, final_rhos[-1])) end_populations_dnup.append(expect(self.spin_dnup, final_rhos[-1])) rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) fidelities.append( fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return end_populations_upup, end_populations_dndn, end_populations_updn, end_populations_dnup, fidelities
def scan_tilt_angle(self, angle_max=10 / 360 * 2 * pi, angle_min=-10 / 360 * 2 * pi, n_steps=10, mode_name='rad_ip_l', **kwargs): # simulate gate fidelity for different heating rates # initialize result vectors self.set_custom_parameters(**kwargs) errors = [] rho_target = tensor(self.dn_dn, self.dn_dn) tilt_angles = np.linspace(angle_min, angle_max, n_steps) self.set_ion_temp(self.modes.modes[mode_name].nbar) detuning_offset = self.omega_z - self.modes.modes[mode_name].freq self.set_gate_detuning(self.delta_g + detuning_offset) for angle in tilt_angles: self.set_lamb_dicke_factors(mode_name=mode_name, raman_misalignment=angle) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return tilt_angles, errors
def scan_t_g(self, t_max=50e-6, t_min=10e-6, n_steps=10, tau=0, ndot=0, factor=1, gamma_el=0, gamma_ram=0, **kwargs): # simulate gate fidelity for different gate pulse durations, with delta_g # and Omega_R optimised for this t_g # i.e. determines scaling of errors due to eg heating with t_g errors = [] rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) ts = np.linspace(t_min, t_max, n_steps) for t_g in ts: delta_g = self.calc_ideal_gate_detuning(T=t_g, verbose=False) self.set_custom_parameters(delta_g=delta_g, **kwargs) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return ts, errors
def test_N_level_system(self): """ Test for circuit with N-level system. """ mat3 = qp.rand_unitary_haar(3) def controlled_mat3(arg_value): """ A qubit control an operator acting on a 3 level system """ control_value = arg_value dim = mat3.dims[0][0] return (tensor(fock_dm(2, control_value), mat3) + tensor(fock_dm(2, 1 - control_value), identity(dim))) qc = QubitCircuit(2, dims=[3, 2]) qc.user_gates = {"CTRLMAT3": controlled_mat3} qc.add_gate("CTRLMAT3", targets=[1, 0], arg_value=1) props = qc.propagators() final_fid = qp.average_gate_fidelity(mat3, ptrace(props[0], 0) - 1) assert pytest.approx(final_fid, 1.0e-6) == 1 init_state = basis([3, 2], [0, 1]) result = qc.run(init_state) final_fid = qp.fidelity(result, props[0] * init_state) assert pytest.approx(final_fid, 1.0e-6) == 1.
def scan_efficiency(self, ndot=0, fact_vec=[1, 2, 3, 4, 5], tau_mot=0, gamma_el=0, gamma_ram=0, tau_spin=0): if self.species is not 'effic_test': raise TypeError( 'Need species effic_test for this to work (factor not implemented for other ions species)' ) # initialize result vectors errors = [] efficiencies = [] rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) self.set_mot_dephasing_time(tau_mot) self.set_el_deph_rate(gamma_el) self.set_ram_scat_rate(gamma_ram) self.set_spin_dephasing_time(tau_spin) for factor in fact_vec: self.set_eff_factor(factor) self.set_heating_rate(ndot) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) efficiencies.append(self.calc_gate_eff()) return fact_vec, errors, efficiencies
def run_operator(state, QI_a, QQ_a, QI_c, QQ_c, show_fid_graph=False): start_time = time.time_ns() fid = [] prod = 1 for k in range(num_time_steps): H = H0 + Ha_I * QI_a[k] + Ha_Q * QQ_a[k] + Hc_I * QI_c[ k] + Hc_Q * QQ_c[k] U = ((-1j * dt) * H).expm() prod = U * prod bl.add_states(qt.ptrace(prod * state, 0)) fid.append(qt.fidelity(prod * state, state_target * state_init)) result = prod * state if show_fid_graph: fig, ax = plt.subplots(1, 1) ax.plot(times, fid) ax.set_title("Fidelity Over Time") ax.set_xlabel('Time (sec)') ax.set_ylabel('Fidelity') print("- Simulating the system took", str((time.time_ns() - start_time) * 1e-9)[0:4], "Seconds") return result
def test_EntropyMutual(): "Mutual information" # verify mutual information = S(A)+S(B) for pure state rhos = [rand_dm(25, dims=[[5, 5], [5, 5]], pure=True) for k in range(10)] for r in rhos: assert_equal(abs(entropy_mutual(r, [0], [1]) - ( entropy_vn(ptrace(r, 0)) + entropy_vn(ptrace(r, 1)))) < 1e-13, True) # check component selection rhos = [rand_dm(8, dims=[[2, 2, 2], [2, 2, 2]], pure=True) for k in range(10)] for r in rhos: assert_equal(abs(entropy_mutual(r, [0, 2], [1]) - (entropy_vn( ptrace(r, [0, 2])) + entropy_vn(ptrace(r, 1)))) < 1e-13, True)
def propagate2(self, ancilla_dim, N, M): na = qt.num(self.sysdim) nb = qt.num(ancilla_dim) crot = (1j * np.pi / (N * M) * qt.tensor(na, nb)).expm() ida = qt.identity(ancilla_dim) return [ qt.ptrace( qt.tensor(k.dag(), ida) * crot * qt.tensor(k, ida) * crot.dag(), 1) / (k.dag() * k).tr() for k in self.kraus ]
def Entangle_calc_DM(rho): rho0 = qt.ptrace(rho, 0) C123 = Concur_DM(rho0) X0 = entropy_lin_DM(rho0) rho1 = qt.ptrace(rho, 1) C231 = Concur_DM(rho1) X1 = entropy_lin_DM(rho1) rho2 = qt.ptrace(rho, 2) C312 = Concur_DM(rho2) X2 = entropy_lin_DM(rho2) xcomp = [X0, X1, X2] vn = min(xcomp) Tgl = Three_Tgl_DM(rho) return C123, C231, C312, vn, Tgl
def test_EntropyConditional(): "Conditional entropy" # test_ S(A,B|C,D)<=S(A|C)+S(B|D) rhos = [rand_dm(16, dims=[[2, 2, 2, 2], [2, 2, 2, 2]], pure=True) for k in range(20)] for ABCD in rhos: AC = ptrace(ABCD, [0, 2]) BD = ptrace(ABCD, [1, 3]) assert_equal(entropy_conditional(ABCD, [2, 3]) <= ( entropy_conditional(AC, 1) + entropy_conditional(BD, 1)), True) # test_ S(A|B,C)<=S(A|B) rhos = [rand_dm(8, dims=[[2, 2, 2], [2, 2, 2]], pure=True) for k in range(20)] for ABC in rhos: AB = ptrace(ABC, [0, 1]) assert_equal(entropy_conditional( ABC, [1, 2]) <= entropy_conditional(AB, 1), True)
def scan_LS(self, LS_max=-0.1, LS_min=0.1, n_steps=10, **kwargs): # simulate gate fidelity for amplitude asymmetries # initialize result vectors self.set_custom_parameters(**kwargs) errors = [] pops = [] LS_vec = np.linspace(LS_min, LS_max, n_steps) for LS in LS_vec: self.set_delta_LS(LS) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(self.rho_target, ptrace(final_rhos[-1], [0, 1]))**2) pops.append( ptrace(final_rhos[-1], [0, 1])[0, 0] + ptrace(final_rhos[-1], [0, 1])[3, 3]) return LS_vec, errors, pops
def test_EntropyMutual(): "Entropy: Mutual information" # verify mutual information = S(A)+S(B) for pure state rhos = [rand_dm(25, dims=[[5, 5], [5, 5]], pure=True) for k in range(10)] for r in rhos: assert_equal( abs( entropy_mutual(r, [0], [1]) - (entropy_vn(ptrace(r, 0)) + entropy_vn(ptrace(r, 1)))) < 1e-13, True) # check component selection rhos = [ rand_dm(8, dims=[[2, 2, 2], [2, 2, 2]], pure=True) for k in range(10) ] for r in rhos: assert_equal( abs( entropy_mutual(r, [0, 2], [1]) - (entropy_vn(ptrace(r, [0, 2])) + entropy_vn(ptrace(r, 1)))) < 1e-13, True)
def scan_el_dephasing_rate(self, gamma_max=10e-3, n_steps=10, **kwargs): # simulate gate fidelity for different elastic scattering rates # initialize result vectors self.set_custom_parameters(**kwargs) errors = [] rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) gammas = np.linspace(0, gamma_max, n_steps) self.set_heating_rate(0) for gamma in gammas: self.set_el_deph_rate(gamma) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return gammas, errors
def scan_ion_temp(self, nbar_max=1, n_steps=10, **kwargs): # simulate gate fidelity for different hinitial ion temperatures # initialize result vectors self.set_custom_parameters(**kwargs) errors = [] rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) nbars = np.linspace(0, nbar_max, n_steps) for nbar in nbars: self.set_ion_temp(nbar) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return nbars, errors
def plot_wigner(state, tensorstate, cmap='seismic', title=None, savepath=None): if tensorstate: state = qt.ptrace(state, 1) xvec = np.linspace(-7,7,81) W = qt.wigner(state, xvec, xvec, g=sqrt(2)) fig, ax = plt.subplots(figsize=(6,5)) # p = ax.pcolormesh(xvec, xvec, W, cmap=cmap, vmin=-1, vmax=+1) #'RdBu_r' # ax.plot([sqrt(pi), sqrt(pi)/2, 0, 0], [0, 0, sqrt(pi), sqrt(pi)/2], # linestyle='none', marker='.',color='black') p = ax.pcolormesh(xvec/sqrt(pi), xvec/sqrt(pi), W, cmap=cmap, vmin=-1, vmax=+1) #'RdBu_r' ax.plot([1, 1/2, 0, 0], [0, 0, 1, 1/2], linestyle='none', marker='.',color='black') fig.colorbar(p, ax=ax) plt.grid() if title: ax.set_title(title) if savepath: plt.savefig(savepath)
def purity_of_reduced(rho): """ Calculates trace of reduced density matrix square Parameters ---------- dm: qobj/array-like Input density matrix Returns ------- purityreduced: Purity of the reduced DM. 1 for pure, 0.5 for maximally mixed. """ rhopartial = ptrace(rho,0) purityreduced = purity(rhopartial) return purityreduced
def purity_of_reduced(rho): """ Calculates trace of reduced density matrix square Parameters ---------- dm: qobj/array-like Input density matrix Returns ------- purityreduced: Purity of the reduced DM. 1 for pure, 0.5 for maximally mixed. """ rhopartial = ptrace(rho, 0) purityreduced = purity(rhopartial) return purityreduced
def scan_heating_rate(self, ndot_max=1e4, n_steps=10, **kwargs): # simulate gate fidelity for different heating rates # initialize result vectors self.set_custom_parameters(**kwargs) errors = [] rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) n_dots = np.linspace(0, ndot_max, n_steps) for ndot in n_dots: self.set_heating_rate(ndot) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return n_dots, errors
def entropy_renyi_entg(rho,alpha): """ Calculate Renyi entropy of entanglement for the DM with given index (Currently limited to 2-level systems) Parameters ---------- dm: qobj/array-like Input density matrix alpha: Renyi index alpha Returns ------- ent_rn_entg: Renyi Entropy of Entanglement """ rhopartial = ptrace(rho,0) ent_rn_entg = entropy_renyi(rhopartial,alpha) return ent_rn_entg
def entropy_renyi_entg(rho, alpha): """ Calculate Renyi entropy of entanglement for the DM with given index (Currently limited to 2-level systems) Parameters ---------- dm: qobj/array-like Input density matrix alpha: Renyi index alpha Returns ------- ent_rn_entg: Renyi Entropy of Entanglement """ rhopartial = ptrace(rho, 0) ent_rn_entg = entropy_renyi(rhopartial, alpha) return ent_rn_entg
def test_N_level_system(self): """ Test for circuit with N-level system. """ mat3 = rand_dm(3, density=1.) def controlled_mat3(arg_value): """ A qubit control an operator acting on a 3 level system """ control_value = arg_value dim = mat3.dims[0][0] return (tensor(fock_dm(2, control_value), mat3) + tensor(fock_dm(2, 1 - control_value), identity(dim))) qc = QubitCircuit(2, dims=[3, 2]) qc.user_gates = {"CTRLMAT3": controlled_mat3} qc.add_gate("CTRLMAT3", targets=[1, 0], arg_value=1) props = qc.propagators() np.testing.assert_allclose(mat3, ptrace(props[0], 0) - 1)
def scan_spin_dephasing_rate(self, tau_min=1e-3, tau_max=10e-3, n_steps=10, **kwargs): # simulate gate fidelity for different spin dephasing rates # initialize result vectors self.set_custom_parameters(**kwargs) errors = [] rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) taus = np.linspace(tau_min, tau_max, n_steps) self.set_heating_rate(0) for tau in taus: self.set_spin_dephasing_time(tau) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return taus, errors
def entropy_linear_entg(rho, normalize=True): """ Calculates the linear entropy of entanglement of a density matrix Parameters: ----------- rho : qobj/array-like Input density matrix Returns: -------- linent_entg: Linear Entropy of Entanglement """ if rho.type == 'ket': rho = ket2dm(rho) if rho.type != 'oper': raise TypeError("Input must be density matrix") rhopartial = ptrace(rho,0) linent_entg = linear_entropy(rhopartial,normalize) return linent_entg
def scan_delta_g(self, delta_max=10e3, delta_min=300e3, n_steps=10, **kwargs): # simulate gate fidelity for different gate detunings, with t_g and Omega_R # optimised for this delta_g # i.e. determines scaling of errors due to eg heating with delta_g errors = [] rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) deltas = np.linspace(delta_min, delta_max, n_steps) for delta in deltas: self.set_custom_parameters(delta_g=delta, **kwargs) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return deltas, errors
def photon_dist(rho): """return diagonals of photon density matrix""" from operators import vector_to_operator from qutip import Qobj, ptrace from basis import ldim_p, ldim_s rho_small = convert_rho.dot(rho) rho_small = vector_to_operator(rho_small) rho_q = Qobj() rho_q.data = rho_small rho_q.dims = [[ldim_p, ldim_s], [ldim_p, ldim_s]] rho_q = ptrace(rho_q, 0) pops = rho_q.data.diagonal() return pops
def entropy_linear_entg(rho, normalize=True): """ Calculates the linear entropy of entanglement of a density matrix Parameters: ----------- rho : qobj/array-like Input density matrix Returns: -------- linent_entg: Linear Entropy of Entanglement """ if rho.type == 'ket': rho = ket2dm(rho) if rho.type != 'oper': raise TypeError("Input must be density matrix") rhopartial = ptrace(rho, 0) linent_entg = linear_entropy(rhopartial, normalize) return linent_entg
def scan_ampl_asym(self, ampl_asym_max=-0.1, ampl_asym_min=0.1, n_steps=10, **kwargs): # simulate gate fidelity for amplitude asymmetries # initialize result vectors self.set_custom_parameters(**kwargs) errors = [] ampl_asyms = np.linspace(ampl_asym_min, ampl_asym_max, n_steps) for ampl_asym in ampl_asyms: self.set_ampl_asym(ampl_asym) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(self.rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return ampl_asyms, errors
def scan_sq_error(self, sq_factor_max=1.05, sq_factor_min=0.995, n_steps=10, **kwargs): # simulate gate fidelity for different heating rates # initialize result vectors self.set_custom_parameters(**kwargs) errors = [] rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) sq_factors = np.linspace(sq_factor_min, sq_factor_max, n_steps) for sq_factor in sq_factors: self.set_sq_pulse_miscalibration(sq_factor) times, final_rhos = self.do_gate() errors.append( 1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return sq_factors, errors
def channel(self, rho): r""" Compute the channel on a density matrix. Parameters ---------- rho : array Returns ------- array : References ---------- See John Watrous Notes of Choi-Matrix. Note that he uses row-based vectorization. """ # Definition is taken from John Watrous. choi_rho = self.qutip.data.dot(np.kron(rho.T, np.eye(self.output_dim))) # Keep the following dimensions when doing partial trace keep = [i for i in range(self.num_out, 2 * self.num_out)] return ptrace(Qobj(choi_rho, dims=self.dim), keep).data.todense()
def entropy_entg(rho, base=2): """ Calculates the entropy of entanglement of a density matrix Parameters: ----------- rho : qobj/array-like Input density matrix base: Base of log Returns: -------- ent_entg: Entropy of Entanglement """ if rho.type == 'ket': rho = ket2dm(rho) if rho.type != 'oper': raise TypeError("Input must be density matrix") rhopartial = ptrace(rho,0) ent_entg = entropy_vn(rhopartial,base) return ent_entg
def wigner_comp(rho, xvec, yvec): """calculate wigner function of central site from density matrix rho at a grid of points defined by xvec and yvec""" global convert_rho from operators import expect, vector_to_operator from qutip import Qobj, wigner, ptrace from basis import ldim_p, ldim_s rho_small = convert_rho.dot(rho) rho_small = vector_to_operator(rho_small) rho_q = Qobj() rho_q.data = rho_small rho_q.dims = [[ldim_p, ldim_s], [ldim_p, ldim_s]] rho_q = ptrace(rho_q, 0) w = wigner(rho_q, xvec, yvec) return w
def entropy_entg(rho, base=2): """ Calculates the entropy of entanglement of a density matrix Parameters: ----------- rho : qobj/array-like Input density matrix base: Base of log Returns: -------- ent_entg: Entropy of Entanglement """ if rho.type == 'ket': rho = ket2dm(rho) if rho.type != 'oper': raise TypeError("Input must be density matrix") rhopartial = ptrace(rho, 0) ent_entg = entropy_vn(rhopartial, base) return ent_entg
def calc_fid(self, t_g=25e-6, tau=0, factor=1, delta_g=2 * pi * 80e3, Omega_r=2 * pi * 224.7e3, ndot=0, nbar=0.0): # calculate fidelity for given set of parameters # initialize result vectors rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) self.set_ion_temp(nbar) self.set_gate_detuning(delta_g) self.set_gate_length(t_g) self.set_Rabi_freq(Omega_r) self.set_eff_factor(factor) # self.set_mot_dephasing_time(tau) # self.set_el_deph_rate(gamma_el) # self.set_ram_scat_rate(gamma_ram) self.set_heating_rate(ndot) times, final_rhos = self.do_gate() error = (1 - fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return error
def parity_scan(self, analysis_phase, scramble_mw_phase=False, fixed_analysis_phase=True, scramble_laser_phase=False, is_wobble_gate=False, **kwargs): # parity scan for simulated fidelity measurement # analysis_phase: vector of analysis pi/2 pulse phases to be evaluated # for MS gate only: # faster with scramble_mw_phase=False # scramble_mw_phase: for every phase phi, set mw phase to random value, in general different to laser phase # scramble_laser_phase: for every phase phi, set laser phase phi_sum to random value, in general different to mw phase (as would be the case in an experiment) # fixed_analysis_phase: use same phase for analysis pulse and gate, ie effectively do analysis pulse with gate laser, rather than with microwaves/rf # !!! If parameters are not separately specified, chooses optimal gate parameters # for programmed gate detuning self.set_custom_parameters(**kwargs) # initialize result vectors end_populations_dndn = [] end_populations_upup = [] end_populations_updn_dnup = [] fidelities = [] times, final_rhos = self.do_gate(nT=2) for phi in analysis_phase: if is_wobble_gate: phi_analysis_1 = phi phi_analysis_2 = phi else: # for MS gate, have included all possible kinds of phase randomisations here if scramble_mw_phase: self.mw_offset_phase_1 = random.random() * 2 * pi if self.mixed_species: self.mw_offset_phase_2 = random.random() * 2 * pi else: self.mw_offset_phase_2 = self.mw_offset_phase_1 if scramble_laser_phase: self.phi_sum_1 = random.random() * 2 * pi if self.mixed_species: self.phi_sum_2 = random.random() * 2 * pi else: self.phi_sum_2 = self.phi_sum_1 if scramble_mw_phase or scramble_laser_phase: times, final_rhos = self.do_gate(nT=2) if fixed_analysis_phase: phi_analysis_1 = phi - self.phi_sum_1 phi_analysis_2 = phi - self.phi_sum_2 else: phi_analysis_1 = self.mw_offset_phase_1 + phi phi_analysis_2 = self.mw_offset_phase_2 + phi rho_after_analysis = self.U_rot(pi/2*self.sq_factor,ion_index=[1,0],phi=phi_analysis_1)*\ self.U_rot(pi/2*self.sq_factor,ion_index=[0,1],phi=phi_analysis_2)*\ final_rhos[-1]* \ self.U_rot(pi/2*self.sq_factor,ion_index=[1,0],phi=phi_analysis_1).dag() *\ self.U_rot(pi/2*self.sq_factor,ion_index=[0,1],phi=phi_analysis_2).dag() final_rho = rho_after_analysis end_populations_upup.append(expect(self.spin_upup, final_rho)) end_populations_dndn.append(expect(self.spin_dndn, final_rho)) end_populations_updn_dnup.append( expect(self.spin_updn_dnup, final_rho)) rho_target = 1 / 2 * (self.uu_uu + self.dd_dd - 1j * self.ud_ud + 1j * self.du_du) fidelities.append( fidelity(rho_target, ptrace(final_rhos[-1], [0, 1]))**2) return end_populations_upup, end_populations_dndn, end_populations_updn_dnup, fidelities