Esempio n. 1
0
    def test_lindblad_no_dissipation(self):
        """
        Use the previous test to verify the Lindblad master equation in absence
        of decoherence terms.
        """

        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]

        dissipation_sup_op = [matrix.DenseOperator(np.zeros((4, 4)))]
        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=True)

        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)

        analytic_reference = -.5j * np.eye(2, dtype=complex)
        sx = np.asarray([[0, 1], [1, 0]]) * (1 + 0j)
        analytic_reference = np.kron(sx, analytic_reference) \
            - np.kron(analytic_reference, sx)
        np.testing.assert_array_almost_equal(
            analytic_reference,
            lindblad_tslot_obj.frechet_deriv_propagators[0][0].data)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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())