def test_state_fid(self): up = matrix.DenseOperator(np.asarray([[1], [0]])) down = matrix.DenseOperator(np.asarray([[0], [1]])) try: q_fc.state_fidelity(up, up) except ValueError: pass try: q_fc.state_fidelity(up, up.dag()) except ValueError: pass assert q_fc.state_fidelity(up.dag(), up) == 1 assert q_fc.state_fidelity(up.dag(), down) == 0 self.assertAlmostEqual( q_fc.state_fidelity(up.dag(), 1. / np.sqrt(2) * (up + down)), .5)
def test_comp_all_save_exp(self): h_drift = [ matrix.DenseOperator(np.zeros((2, 2), dtype=complex)) for _ in range(4) ] h_control = [ .5 * matrix.DenseOperator(qutip.sigmax()), .5 * matrix.DenseOperator(qutip.sigmaz()) ] ctrl_amps = np.asarray([[.5, 0, .25, .25], [0, .5, 0, 0] ]).T * 2 * np.pi n_t = 4 tau = [1 for _ in range(4)] initial_state = matrix.DenseOperator(np.eye(2)) \ * (1 + 0j) tslot_obj = solver_algorithms.SchroedingerSolver( h_ctrl=h_control, h_drift=h_drift, tau=tau, initial_state=initial_state, ctrl_amps=ctrl_amps, calculate_propagator_derivatives=True) # test the propagators # use the exponential identity for pauli operators for verification correct_props = [[[0. + 0.j, 0. - 1.j], [0. - 1.j, 0. + 0.j]], [[0. - 1.j, 0. + 0.j], [0. + 0.j, 0. + 1.j]], [[0.70710678 + 0.j, 0. - 0.70710678j], [0. - 0.70710678j, 0.70710678 + 0.j]], [[0.70710678 + 0.j, 0. - 0.70710678j], [0. - 0.70710678j, 0.70710678 + 0.j]]] correct_props = list(map(np.asarray, correct_props)) propagators = tslot_obj.propagators for i in range(n_t): np.testing.assert_array_almost_equal(propagators[i].data, correct_props[i]) # test the forward propagation correct_fwd_prop = [ initial_state.data, ] for prop in correct_props: correct_fwd_prop.append(prop @ correct_fwd_prop[-1]) forward_propagators = tslot_obj.forward_propagators for i in range(n_t + 1): np.testing.assert_array_almost_equal(forward_propagators[i].data, correct_fwd_prop[i]) # test the reverse propagation # This functionality is currently not used / supported correct_rev_prop = [initial_state.data] for prop in correct_props[::-1]: correct_rev_prop.append(correct_rev_prop[-1] @ prop) reverse_propagators = tslot_obj.reversed_propagators for i in range(n_t + 1): np.testing.assert_array_almost_equal(reverse_propagators[i].data, correct_rev_prop[i]) sx = matrix.DenseOperator(.5 * qutip.sigmax()) A = sx * -1j * .5 * 2 * math.pi B = sx * -1j prop, deriv = A.dexp(direction=B, tau=1, compute_expm=True) np.testing.assert_array_almost_equal( deriv.data, tslot_obj.frechet_deriv_propagators[0][0].data) analytic_reference = -.5 * np.eye(2, dtype=complex) np.testing.assert_array_almost_equal( analytic_reference, tslot_obj.frechet_deriv_propagators[0][0].data)
def test_save_all_noise(self): h_drift = [ matrix.DenseOperator(np.zeros((2, 2), dtype=complex)) for _ in range(4) ] h_control = [ .5 * matrix.DenseOperator(qutip.sigmax()), ] h_noise = [ .5 * matrix.DenseOperator(qutip.sigmaz()), ] ctrl_amps = np.asarray([ [.5, 0, .25, .25], ]).T * 2 * math.pi tau = [1, 1, 1, 1] n_t = len(tau) initial_state = matrix.DenseOperator(np.eye(2)) \ * (1 + 0j) mocked_noise = np.asarray([0, .5, 0, 0]) * 2 * math.pi mocked_noise = np.expand_dims(mocked_noise, 0) mocked_noise = np.expand_dims(mocked_noise, 0) noise_sample_generator = noise.NTGQuasiStatic( noise_samples=mocked_noise, n_samples_per_trace=4, standard_deviation=[ 2, ], n_traces=1, always_redraw_samples=False) time_slot_noise = solver_algorithms.SchroedingerSMonteCarlo( h_drift=h_drift, h_ctrl=h_control, initial_state=initial_state, tau=tau, ctrl_amps=ctrl_amps, h_noise=h_noise, noise_trace_generator=noise_sample_generator) # test the propagators # use the exponential identity for pauli operators for verification correct_props = [[[0. + 0.j, 0. - 1.j], [0. - 1.j, 0. + 0.j]], [[0. - 1.j, 0. + 0.j], [0. + 0.j, 0. + 1.j]], [[0.70710678 + 0.j, 0. - 0.70710678j], [0. - 0.70710678j, 0.70710678 + 0.j]], [[0.70710678 + 0.j, 0. - 0.70710678j], [0. - 0.70710678j, 0.70710678 + 0.j]]] correct_props = list(map(np.asarray, correct_props)) propagators = time_slot_noise.propagators_noise[0] for i in range(n_t): np.testing.assert_array_almost_equal(propagators[i].data, correct_props[i]) # test the forward propagation correct_fwd_prop = [ initial_state.data, ] for prop in correct_props: correct_fwd_prop.append(prop @ correct_fwd_prop[-1]) forward_propagators = time_slot_noise.forward_propagators_noise[0] for i in range(n_t + 1): np.testing.assert_array_almost_equal(forward_propagators[i].data, correct_fwd_prop[i]) # test the reverse propagation # This functionality is currently not used / supported correct_rev_prop = [initial_state] for prop in correct_props[::-1]: correct_rev_prop.append(correct_rev_prop[-1] * prop) reverse_propagators = time_slot_noise.reversed_propagators_noise[0] for i in range(n_t + 1): np.testing.assert_array_almost_equal(reverse_propagators[i].data, correct_rev_prop[i].data) sx = matrix.DenseOperator(.5 * qutip.sigmax()) A = sx * -1j * .5 * 2 * math.pi B = sx * -1j prop, deriv = A.dexp(direction=B, tau=1, compute_expm=True) np.testing.assert_array_almost_equal( deriv.data, time_slot_noise.frechet_deriv_propagators_noise[0][0][0].data)
def test_lindblad_false_dissipation(self): """ Disguise the dissipation less evolution by using the dissipation operators. """ # method 1. h_drift = [ matrix.DenseOperator(np.zeros((2, 2), dtype=complex)) for _ in range(4) ] h_control = [ .5 * matrix.DenseOperator(qutip.sigmax()), .5 * matrix.DenseOperator(qutip.sigmaz()) ] ctrl_amps = np.asarray([[.5, 0, .25, .25], [0, .5, 0, 0] ]).T * 2 * math.pi tau = [1, 1, 1, 1] def prefactor_function(_): return ctrl_amps identity = h_control[0].identity_like() dissipation_sup_op = [(identity.kron(h) - h.kron(identity)) * -1j for h in h_control] h_control = [matrix.DenseOperator(np.zeros((2, 2)))] initial_state = matrix.DenseOperator(np.eye(4)) lindblad_tslot_obj = solver_algorithms.LindbladSolver( h_ctrl=h_control, h_drift=h_drift, tau=tau, initial_state=initial_state, ctrl_amps=ctrl_amps, initial_diss_super_op=dissipation_sup_op, calculate_unitary_derivatives=False, prefactor_function=prefactor_function) propagators = lindblad_tslot_obj.propagators # test the propagators # use the exponential identity for pauli operators for verification correct_props = [[[0. + 0.j, 0. - 1.j], [0. - 1.j, 0. + 0.j]], [[0. - 1.j, 0. + 0.j], [0. + 0.j, 0. + 1.j]], [[0.70710678 + 0.j, 0. - 0.70710678j], [0. - 0.70710678j, 0.70710678 + 0.j]], [[0.70710678 + 0.j, 0. - 0.70710678j], [0. - 0.70710678j, 0.70710678 + 0.j]]] correct_props = list(map(np.asarray, correct_props)) correct_props = [np.kron(cp.conj(), cp) for cp in correct_props] for i in range(4): np.testing.assert_array_almost_equal(correct_props[i], propagators[i].data) # method 3 def diss_sup_op_func(_, _2): return lindblad_tslot_obj._diss_sup_op similar_lindblad_tslot_onj = solver_algorithms.LindbladSolver( h_ctrl=h_control, h_drift=h_drift, tau=tau, initial_state=initial_state, ctrl_amps=ctrl_amps, initial_diss_super_op=dissipation_sup_op, super_operator_function=diss_sup_op_func) propagators = similar_lindblad_tslot_onj.propagators for i in range(4): np.testing.assert_array_almost_equal(correct_props[i], propagators[i].data) # method 2 lindblad = [ matrix.DenseOperator(np.asarray([[0, 1j], [1, 0]], dtype=complex)) ] lind_lindblad_tslot_obj = solver_algorithms.LindbladSolver( h_ctrl=h_control, h_drift=h_drift, tau=tau, initial_state=initial_state, ctrl_amps=ctrl_amps, initial_diss_super_op=dissipation_sup_op, lindblad_operators=lindblad) diss_sup_op = lind_lindblad_tslot_obj._calc_diss_sup_op() li = lindblad[0] correct_diss_sup_op = li.conj(True).kron(li) \ - .5 * identity.kron(li * li.dag()) \ - .5 * (li.transpose() * li.conj()).kron(identity) for i in range(4): np.testing.assert_array_almost_equal(diss_sup_op[i].data, correct_diss_sup_op.data)
def test_gradient_calculation(self): # constants num_x = 12 num_ctrl = 2 over_sample_rate = 8 bound_type = ("n", 5) num_u = over_sample_rate * num_x + 2 * bound_type[1] tau = [100e-9 for _ in range(num_x)] lin_freq_rel = 5.614e-4 * 1e6 * 1e3 h_ctrl = [.5 * 2 * math.pi * sig_x, .5 * 2 * math.pi * sig_y] h_drift = [ matrix.DenseOperator(np.zeros((2, 2), dtype=complex)) for _ in range(num_u) ] # trivial transfer function T = np.diag(num_x * [lin_freq_rel]) T = np.expand_dims(T, 2) linear_transfer_function = \ transfer_function.CustomTF(T, num_ctrls=2) exponential_saturation_transfer_function = \ transfer_function.ExponentialTF( awg_rise_time=.2 * tau[0], oversampling=over_sample_rate, bound_type=bound_type, num_ctrls=2 ) concatenated_tf = transfer_function.ConcatenateTF( tf1=linear_transfer_function, tf2=exponential_saturation_transfer_function) concatenated_tf.set_times(np.asarray(tau)) # t_slot_comp seed = 1 np.random.seed(seed) initial_pulse = 4 * np.random.rand(num_x, num_ctrl) - 2 initial_ctrl_amps = concatenated_tf(initial_pulse) initial_state = matrix.DenseOperator(np.eye(2, dtype=complex)) tau_u = [100e-9 / over_sample_rate for _ in range(num_u)] t_slot_comp = solver_algorithms.SchroedingerSolver( h_drift=h_drift, h_ctrl=h_ctrl, initial_state=initial_state, tau=tau_u, ctrl_amps=initial_ctrl_amps, calculate_propagator_derivatives=False) target = matrix.DenseOperator( (1j * sig_x + np.eye(2, dtype=complex)) * (1 / np.sqrt(2))) fidelity_computer = q_fc.OperationInfidelity( solver=t_slot_comp, target=target, fidelity_measure='entanglement') initial_cost = fidelity_computer.costs() cost = np.zeros(shape=(3, num_ctrl, num_x)) delta_amp = 1e-3 for i in range(num_x): for j in range(num_ctrl): cost[1, j, i] = np.real(initial_cost) delta = np.zeros(shape=initial_pulse.shape) delta[i, j] = -1 * delta_amp t_slot_comp.set_optimization_parameters( concatenated_tf(initial_pulse + delta)) cost[0, j, i] = fidelity_computer.costs() delta[i, j] = delta_amp t_slot_comp.set_optimization_parameters( concatenated_tf(initial_pulse + delta)) cost[2, j, i] = fidelity_computer.costs() numeric_gradient = np.gradient(cost, delta_amp, axis=0) t_slot_comp.set_optimization_parameters(concatenated_tf(initial_pulse)) grad = fidelity_computer.grad() np.expand_dims(grad, 1) analytic_gradient = concatenated_tf.gradient_chain_rule( np.expand_dims(grad, 1)) self.assertLess( np.sum(np.abs(numeric_gradient[1].T - analytic_gradient.squeeze(1))), 1e-6) # super operators dissipation_sup_op = [matrix.DenseOperator(np.zeros((4, 4)))] initial_state_sup_op = matrix.DenseOperator(np.eye(4)) lindblad_tslot_obj = solver_algorithms.LindbladSolver( h_ctrl=h_ctrl, h_drift=h_drift, tau=tau_u, initial_state=initial_state_sup_op, ctrl_amps=initial_ctrl_amps, initial_diss_super_op=dissipation_sup_op, calculate_unitary_derivatives=False) fid_comp_sup_op = q_fc.OperationInfidelity( solver=lindblad_tslot_obj, target=target, fidelity_measure='entanglement', super_operator_formalism=True) t_slot_comp.set_optimization_parameters(initial_ctrl_amps) lindblad_tslot_obj.set_optimization_parameters(initial_ctrl_amps) self.assertAlmostEqual(fidelity_computer.costs(), fid_comp_sup_op.costs()) np.testing.assert_array_almost_equal(fid_comp_sup_op.grad(), fidelity_computer.grad())
import math import unittest from qopt import matrix, cost_functions as q_fc, solver_algorithms, \ transfer_function import numpy as np sig_0 = matrix.DenseOperator(np.eye(2)) sig_x = matrix.DenseOperator(np.asarray([[0, 1], [1, 0]])) sig_y = matrix.DenseOperator(np.asarray([[0, -1j], [1j, 0]])) sig_z = matrix.DenseOperator(np.asarray([[1, 0], [0, -1]])) class TestEntanglementFidelity(unittest.TestCase): def test_entanglement_average_fidelity(self): a = 1 - q_fc.averge_gate_fidelity(sig_x, sig_y) b = 1 - q_fc.averge_gate_fidelity(sig_x, sig_x) c = 1 - q_fc.averge_gate_fidelity(sig_x, 1 / np.sqrt(2) * (sig_y + sig_x)) a_e = 1 - q_fc.entanglement_fidelity(sig_x, sig_y) b_e = 1 - q_fc.entanglement_fidelity(sig_x, sig_x) c_e = 1 - q_fc.entanglement_fidelity(sig_x, 1 / np.sqrt(2) * (sig_y + sig_x)) self.assertAlmostEqual(a * 3 / 2, a_e) self.assertAlmostEqual(b * 3 / 2, b_e) self.assertAlmostEqual(c * 3 / 2, c_e) e_sig_x = sig_x.exp(tau=.25j * math.pi) e_sig_y = sig_y.exp(tau=.25j * math.pi)
def test_dense_control_matrix_functions(self): tau = .5j * math.pi sigma_x = matrix.DenseOperator(SIGMA_X) exponential = sigma_x.exp(tau) np.testing.assert_array_almost_equal(exponential.data, sigma_x.data * 1j) exponential = sigma_x.exp(2 * tau) np.testing.assert_array_almost_equal(exponential.data, -1 * np.eye(2)) prop_spectral, prop_grad_spectral = sigma_x.dexp(direction=sigma_x, tau=tau, compute_expm=True, method='spectral') prop_frechet, prop_grad_frechet = sigma_x.dexp(direction=sigma_x, tau=tau, compute_expm=True, method='Frechet') """ prop_approx, prop_grad_approx = sigma_x.dexp( direction=sigma_x, tau=tau, compute_expm=True, method='approx') """ prop_first_order, prop_grad_first_order = sigma_x.dexp( direction=sigma_x, tau=tau, compute_expm=True, method='first_order') prop_second_order, prop_grad_second_order = sigma_x.dexp( direction=sigma_x, tau=tau, compute_expm=True, method='second_order') prop_third_order, prop_grad_third_order = sigma_x.dexp( direction=sigma_x, tau=tau, compute_expm=True, method='third_order') np.testing.assert_array_almost_equal(prop_spectral.data, prop_frechet.data) """ np.testing.assert_array_almost_equal(prop_spectral.data, prop_approx.data) """ np.testing.assert_array_almost_equal(prop_spectral.data, prop_first_order.data) np.testing.assert_array_almost_equal(prop_spectral.data, prop_second_order.data) np.testing.assert_array_almost_equal(prop_spectral.data, prop_third_order.data) np.testing.assert_array_almost_equal(prop_grad_spectral.data, prop_grad_frechet.data) """ np.testing.assert_array_almost_equal(prop_grad_spectral.data, prop_grad_approx.data) """ # test kronecker product: np.random.seed(0) a = matrix.DenseOperator(np.random.rand(5, 5)) b = matrix.DenseOperator(np.random.rand(5, 5)) c = a.kron(b) c_2 = a.kron(b.data) c_np = np.kron(a.data, b.data) np.testing.assert_array_almost_equal(c.data, c_2.data) np.testing.assert_array_almost_equal(c.data, c_np) norm = sigma_x.norm() self.assertAlmostEqual(norm, np.sqrt(2))