def test_partial_transpose_bipartite(): """partial transpose of bipartite systems""" rho = Qobj(np.arange(16).reshape(4, 4), dims=[[2, 2], [2, 2]]) # no transpose rho_pt = partial_transpose(rho, [0, 0]) assert_(np.abs(np.max(rho_pt.full() - rho.full())) < 1e-12) # partial transpose subsystem 1 rho_pt = partial_transpose(rho, [1, 0]) rho_pt_expected = np.array([[0, 1, 8, 9], [4, 5, 12, 13], [2, 3, 10, 11], [6, 7, 14, 15]]) assert_(np.abs(np.max(rho_pt.full() - rho_pt_expected)) < 1e-12) # partial transpose subsystem 2 rho_pt = partial_transpose(rho, [0, 1]) rho_pt_expected = np.array([[0, 4, 2, 6], [1, 5, 3, 7], [8, 12, 10, 14], [9, 13, 11, 15]]) assert_(np.abs(np.max(rho_pt.full() - rho_pt_expected)) < 1e-12) # full transpose rho_pt = partial_transpose(rho, [1, 1]) assert_(np.abs(np.max(rho_pt.full() - rho.trans().full())) < 1e-12)
def test_lindbladian(self): """ Optimise pulse for amplitude damping channel with Lindbladian dyn assert that fidelity error is below threshold """ Sx = sigmax() Sz = sigmaz() Si = identity(2) Sd = Qobj(np.array([[0, 1], [0, 0]])) Sm = Qobj(np.array([[0, 0], [1, 0]])) Sd_m = Qobj(np.array([[1, 0], [0, 0]])) gamma = 0.1 L0_Ad = gamma*(2*tensor(Sm, Sd.trans()) - (tensor(Sd_m, Si) + tensor(Si, Sd_m.trans()))) LC_x = -1j*(tensor(Sx, Si) - tensor(Si, Sx)) LC_z = -1j*(tensor(Sz, Si) - tensor(Si, Sz)) drift = L0_Ad ctrls = [LC_z, LC_x] n_ctrls = len(ctrls) initial = tensor(Si, Si) had_gate = hadamard_transform(1) target_DP = tensor(had_gate, had_gate) n_ts = 10 evo_time = 5 result = cpo.optimize_pulse(drift, ctrls, initial, target_DP, n_ts, evo_time, fid_err_targ=1e-3, max_iter=200, init_pulse_type='LIN', gen_stats=True) assert_(result.fid_err < 0.1, msg="Fidelity higher than expected") # Repeat with Qobj propagation result = cpo.optimize_pulse(drift, ctrls, initial, target_DP, n_ts, evo_time, fid_err_targ=1e-3, max_iter=200, init_pulse_type='LIN', dyn_params={'oper_dtype':Qobj}, gen_stats=True) assert_(result.fid_err < 0.1, msg="Fidelity higher than expected (Qobj propagation)") # Check same result is achieved using the create objects method optim = cpo.create_pulse_optimizer(drift, ctrls, initial, target_DP, n_ts, evo_time, fid_err_targ=1e-3, init_pulse_type='LIN', gen_stats=True) dyn = optim.dynamics p_gen = optim.pulse_generator init_amps = np.zeros([n_ts, n_ctrls]) for j in range(n_ctrls): init_amps[:, j] = p_gen.gen_pulse() dyn.initialize_controls(init_amps) # Check the exact gradient func = optim.fid_err_func_wrapper grad = optim.fid_err_grad_wrapper x0 = dyn.ctrl_amps.flatten() grad_diff = check_grad(func, grad, x0) assert_almost_equal(grad_diff, 0.0, decimal=7, err_msg="Frechet gradient outside tolerance") result2 = optim.run_optimization() assert_almost_equal(result.fid_err, result2.fid_err, decimal=3, err_msg="Direct and indirect methods produce " "different results for ADC")
def test_06_lindbladian(self): """ control.pulseoptim: amplitude damping channel Lindbladian dynamics assert that fidelity error is below threshold """ Sx = sigmax() Sz = sigmaz() Si = identity(2) Sd = Qobj(np.array([[0, 1], [0, 0]])) Sm = Qobj(np.array([[0, 0], [1, 0]])) Sd_m = Qobj(np.array([[1, 0], [0, 0]])) gamma = 0.1 L0_Ad = gamma * (2 * tensor(Sm, Sd.trans()) - (tensor(Sd_m, Si) + tensor(Si, Sd_m.trans()))) LC_x = -1j * (tensor(Sx, Si) - tensor(Si, Sx)) LC_z = -1j * (tensor(Sz, Si) - tensor(Si, Sz)) drift = L0_Ad ctrls = [LC_z, LC_x] n_ctrls = len(ctrls) initial = tensor(Si, Si) had_gate = hadamard_transform(1) target_DP = tensor(had_gate, had_gate) n_ts = 10 evo_time = 5 result = cpo.optimize_pulse(drift, ctrls, initial, target_DP, n_ts, evo_time, fid_err_targ=1e-3, max_iter=200, init_pulse_type='LIN', gen_stats=True) assert_(result.fid_err < 0.1, msg="Fidelity higher than expected") # Repeat with Qobj propagation result = cpo.optimize_pulse(drift, ctrls, initial, target_DP, n_ts, evo_time, fid_err_targ=1e-3, max_iter=200, init_pulse_type='LIN', dyn_params={'oper_dtype': Qobj}, gen_stats=True) assert_(result.fid_err < 0.1, msg="Fidelity higher than expected (Qobj propagation)") # Check same result is achieved using the create objects method optim = cpo.create_pulse_optimizer(drift, ctrls, initial, target_DP, n_ts, evo_time, fid_err_targ=1e-3, init_pulse_type='LIN', gen_stats=True) dyn = optim.dynamics p_gen = optim.pulse_generator init_amps = np.zeros([n_ts, n_ctrls]) for j in range(n_ctrls): init_amps[:, j] = p_gen.gen_pulse() dyn.initialize_controls(init_amps) # Check the exact gradient func = optim.fid_err_func_wrapper grad = optim.fid_err_grad_wrapper x0 = dyn.ctrl_amps.flatten() grad_diff = check_grad(func, grad, x0) assert_almost_equal(grad_diff, 0.0, decimal=7, err_msg="Frechet gradient outside tolerance") result2 = optim.run_optimization() assert_almost_equal(result.fid_err, result2.fid_err, decimal=3, err_msg="Direct and indirect methods produce " "different results for ADC")
# **************************************************************** # Define the physics of the problem Sx = sigmax() Sy = sigmay() Sz = sigmaz() Si = identity(2) Sd = Qobj(np.array([[0, 1], [0, 0]])) Sm = Qobj(np.array([[0, 0], [1, 0]])) Sd_m = Qobj(np.array([[1, 0], [0, 0]])) Sm_d = Qobj(np.array([[0, 0], [0, 1]])) #Amplitude damping# #Damping rate: gamma = 0.1 L0_Ad = gamma * (2 * tensor(Sm, Sd.trans()) - (tensor(Sd_m, Si) + tensor(Si, Sd_m.trans()))) #sigma X control LC_x = -1j * (tensor(Sx, Si) - tensor(Si, Sx)) #sigma Y control LC_y = -1j * (tensor(Sy, Si) - tensor(Si, Sy.trans())) #sigma Z control LC_z = -1j * (tensor(Sz, Si) - tensor(Si, Sz)) #Drift drift = L0_Ad #Controls ctrls = [LC_z, LC_x] # Number of ctrls n_ctrls = len(ctrls)
Sz = sigmaz() Si = identity(2) Sd = Qobj(np.array([[0, 1], [0, 0]])) Sm = Qobj(np.array([[0, 0], [1, 0]])) Sd_m = Qobj(np.array([[1, 0], [0, 0]])) Sm_d = Qobj(np.array([[0, 0], [0, 1]])) #Amplitude damping# #Damping rate: gamma = 0.1 L0_Ad = gamma*(2*tensor(Sm, Sd.trans()) - (tensor(Sd_m, Si) + tensor(Si, Sd_m.trans()))) #sigma X control LC_x = -1j*(tensor(Sx, Si) - tensor(Si, Sx)) #sigma Y control LC_y = -1j*(tensor(Sy, Si) - tensor(Si, Sy.trans())) #sigma Z control LC_z = -1j*(tensor(Sz, Si) - tensor(Si, Sz)) #Drift drift = L0_Ad #Controls ctrls = [LC_z, LC_x] # Number of ctrls n_ctrls = len(ctrls)