Esempio n. 1
0
def test_parallel_map_fw_prop_step_loky(transmon_xgate_system):
    """Test optimization with parallel_map parameter, using loky."""
    objectives, pulse_options, tlist = transmon_xgate_system

    krotov.parallelization.USE_LOKY = True
    log = io.StringIO()
    opt_result_loky = krotov.optimize_pulses(
        objectives,
        pulse_options,
        tlist,
        propagator=krotov.propagators.expm,
        chi_constructor=krotov.functionals.chis_re,
        info_hook=partial(krotov.info_hooks.print_debug_information, out=log),
        iter_stop=1,
        skip_initial_forward_propagation=True,
        parallel_map=(
            krotov.parallelization.parallel_map,
            krotov.parallelization.parallel_map,
            krotov.parallelization.parallel_map_fw_prop_step,
        ),
    )
    tau1_loky = abs(opt_result_loky.tau_vals[0][0])
    tau2_loky = abs(opt_result_loky.tau_vals[0][1])
    assert abs(tau1_loky - 0.9693) < 1e-3
    assert abs(tau2_loky - 0.7743) < 1e-3

    krotov.parallelization.USE_LOKY = False
    # in order to be pickleable, all functions must be defined in a module
    # (transmon_xgate_system_mod)
    H = transmon_xgate_system_mod.transmon_hamiltonian()
    pulse_options = {
        H[1][1]: dict(lambda_a=1, update_shape=transmon_xgate_system_mod.S)
    }
    psi0, psi1 = transmon_xgate_system_mod.logical_basis(H)
    objectives = krotov.gate_objectives(
        basis_states=[psi0, psi1], gate=qutip.operators.sigmax(), H=H
    )
    try:
        opt_result = krotov.optimize_pulses(
            objectives,
            pulse_options,
            tlist,
            propagator=krotov.propagators.expm,
            chi_constructor=krotov.functionals.chis_re,
            iter_stop=1,
            skip_initial_forward_propagation=True,
            parallel_map=(
                krotov.parallelization.parallel_map,
                krotov.parallelization.parallel_map,
                krotov.parallelization.parallel_map_fw_prop_step,
            ),
        )
        tau1 = abs(opt_result.tau_vals[0][0])
        tau2 = abs(opt_result.tau_vals[0][1])
        assert abs(tau1_loky - tau1) < 1e-12
        assert abs(tau2_loky - tau2) < 1e-12
    except RuntimeError:
        # parallelization without LOKY doesn't work on all platforms
        pass
Esempio n. 2
0
def test_gate_objectives_pe():
    """Test gate objectives for a PE optimization"""
    from qutip import ket, tensor, sigmaz, sigmax, identity
    from weylchamber import bell_basis

    basis = [ket(n) for n in [(0, 0), (0, 1), (1, 0), (1, 1)]]
    H = [
        tensor(sigmaz(), identity(2)) + tensor(identity(2), sigmaz()),
        [tensor(sigmax(), identity(2)), lambda t, args: 1.0],
        [tensor(identity(2), sigmax()), lambda t, args: 1.0],
    ]
    objectives = krotov.gate_objectives(basis, 'PE', H)
    assert len(objectives) == 4
    bell_basis_states = bell_basis(basis)
    for state in bell_basis_states:
        assert isinstance(state, qutip.Qobj)
    for i in range(4):
        expected_objective = krotov.Objective(
            initial_state=bell_basis_states[i], target='PE', H=H
        )
        assert objectives[i] == expected_objective
    assert krotov.gate_objectives(basis, 'perfect_entangler', H) == objectives
    assert krotov.gate_objectives(basis, 'perfect entangler', H) == objectives
    assert krotov.gate_objectives(basis, 'Perfect Entangler', H) == objectives
    with pytest.raises(ValueError):
        krotov.gate_objectives(basis, 'prefect(!) entanglers', H)
Esempio n. 3
0
def test_transmon_3states_objectives():
    L = qutip.Qobj()  # dummy Liouvillian (won't be used)
    n_qubit = 3
    ket00 = qutip.ket((0, 0), dim=(n_qubit, n_qubit))
    ket01 = qutip.ket((0, 1), dim=(n_qubit, n_qubit))
    ket10 = qutip.ket((1, 0), dim=(n_qubit, n_qubit))
    ket11 = qutip.ket((1, 1), dim=(n_qubit, n_qubit))
    basis = [ket00, ket01, ket10, ket11]
    weights = [20, 1, 1]
    objectives = krotov.gate_objectives(
        basis,
        qutip_gates.sqrtiswap(),
        L,
        liouville_states_set='3states',
        weights=weights,
    )

    rho1_tgt = (
        0.4 * ket00 * ket00.dag()
        + (0.5 / 2) * ket01 * ket01.dag()
        - (0.1j / 2) * ket01 * ket10.dag()
        + (0.1j / 2) * ket10 * ket01.dag()
        + (0.5 / 2) * ket10 * ket10.dag()
        + 0.1 * ket11 * ket11.dag()
    )

    ket00_tgt = ket00
    ket01_tgt = (ket01 + 1j * ket10) / np.sqrt(2)
    ket10_tgt = (1j * ket01 + ket10) / np.sqrt(2)
    ket11_tgt = ket11
    target_basis = [ket00_tgt, ket01_tgt, ket10_tgt, ket11_tgt]
    rho2_tgt = 0.25 * sum(
        [psi * phi.dag() for (psi, phi) in product(target_basis, target_basis)]
    )

    rho3_tgt = 0.25 * (
        ket00 * ket00.dag()
        + ket01 * ket01.dag()
        + ket10 * ket10.dag()
        + ket11 * ket11.dag()
    )
    assert (objectives[0].target - rho1_tgt).norm('max') < 1e-14
    assert (objectives[1].target - rho2_tgt).norm('max') < 1e-14
    assert (objectives[2].target - rho3_tgt).norm('max') < 1e-14

    assert objectives[0].weight == 60.0 / 22.0
    assert objectives[1].weight == 3.0 / 22.0
    assert objectives[2].weight == 3.0 / 22.0
Esempio n. 4
0
def transmon_xgate_system():
    """Optimization system for a single-qubit transmont gate.

    See example "Optimization of an X-Gate for a Transmon Qubit".
    """
    def eps0(t, args):
        T = 10
        return 4 * np.exp(-40.0 * (t / T - 0.5)**2)

    def transmon_hamiltonian(Ec=0.386, EjEc=45, nstates=2, ng=0.0, T=10.0):
        Ej = EjEc * Ec
        n = np.arange(-nstates, nstates + 1)
        up = np.diag(np.ones(2 * nstates), k=-1)
        do = up.T
        H0 = qutip.Qobj(np.diag(4 * Ec * (n - ng)**2) - Ej * (up + do) / 2.0)
        H1 = qutip.Qobj(-2 * np.diag(n))

        return [H0, [H1, eps0]]

    def logical_basis(H):
        H0 = H[0]
        eigenvals, eigenvecs = scipy.linalg.eig(H0.full())
        ndx = np.argsort(eigenvals.real)
        V = eigenvecs[:, ndx]
        psi0 = qutip.Qobj(V[:, 0])
        psi1 = qutip.Qobj(V[:, 1])
        return psi0, psi1

    def S(t):
        return krotov.shapes.flattop(t,
                                     t_start=0.0,
                                     t_stop=10.0,
                                     t_rise=0.5,
                                     func='sinsq')

    tlist = np.linspace(0, 10, 100)

    H = transmon_hamiltonian()

    pulse_options = {H[1][1]: dict(lambda_a=1, update_shape=S)}

    psi0, psi1 = logical_basis(H)

    objectives = krotov.gate_objectives(basis_states=[psi0, psi1],
                                        gate=qutip.operators.sigmax(),
                                        H=H)

    return objectives, pulse_options, tlist
Esempio n. 5
0
def transmon_3states_objectives():
    # see also test_objectives:test_transmon_3states_objectives
    L = qutip.Qobj()  # dummy Liouvillian (won't be used)
    n_qubit = 3
    ket00 = qutip.ket((0, 0), dim=(n_qubit, n_qubit))
    ket01 = qutip.ket((0, 1), dim=(n_qubit, n_qubit))
    ket10 = qutip.ket((1, 0), dim=(n_qubit, n_qubit))
    ket11 = qutip.ket((1, 1), dim=(n_qubit, n_qubit))
    basis = [ket00, ket01, ket10, ket11]
    weights = [20, 1, 1]
    objectives = krotov.gate_objectives(
        basis,
        qutip_gates.sqrtiswap(),
        L,
        liouville_states_set='3states',
        weights=weights,
    )
    return objectives
Esempio n. 6
0
def iswap_state_objectives(canonical_basis):
    H = qutip.Qobj()  # dummy Hamiltonian (won't be used)
    objectives = krotov.gate_objectives(canonical_basis,
                                        qutip_gates.sqrtiswap(), H)
    return objectives
Esempio n. 7
0
    def optimize(self):
        # We can now call any Python lib to
        # perform pulse optimization (marshalling the options/parameters if required)
        # For example, one can use Qutip pulse optimization:
        # Notes about data types:
        # - targerU: flatten (row-by-row) U matrix into a 1-D array of complex numbers
        # - H0: string-type representation of the static Hamiltonian:
        # e.g.: 0.123 Z0Z1
        # - Hops: array of strings represent terms on the Hamiltonian which can be controlled.
        # Depending on the specific library we use for pulse optimization,
        # we may need to marshal these data types accordingly.
        # Run the optimization

        H = self.construct_hamiltonian()
        tlist = np.arange(0.0, self.tMax, self.dt)

        # TODO: this should be an IR transformation option
        def S(t):
            """Shape function for the field update"""
            return krotov.shapes.flattop(
                t,
                t_start=0,
                t_stop=self.tMax,
                t_rise=self.tMax / self.rise_fall_coeff,
                t_fall=self.tMax / self.rise_fall_coeff,
                func=self.func_name)

        pulse_options = {H[1][1]: dict(lambda_a=self.lambda_a, update_shape=S)}
        print('Krotov: Target Unitary Object:')
        print(self.targetObj())

        objectives = krotov.gate_objectives(
            # Target is the unitary: i.e. transform all states -> expected result.
            basis_states=self.logical_basis(),
            gate=self.targetObj(),
            H=H)

        opt_result = krotov.optimize_pulses(
            objectives,
            pulse_options,
            tlist,
            propagator=krotov.propagators.expm,
            chi_constructor=krotov.functionals.chis_ss,
            info_hook=krotov.info_hooks.print_table(
                J_T=krotov.functionals.J_T_ss),
            check_convergence=krotov.convergence.Or(
                krotov.convergence.value_below('1e-3', name='J_T'),
                krotov.convergence.check_monotonic_error,
            ),
            store_all_pulses=True,
        )

        plotFile = self.plot_control_field_iterations(opt_result)
        print(opt_result)
        print('*************************************************')
        print('**Plot of control field iterations is saved to:**')
        print(plotFile)
        print('*************************************************')

        pulse = opt_result.optimized_controls[0]
        return (0.0, pulse)
Esempio n. 8
0
def S(t):
    """Scales the Krotov methods update of the pulse value at the time t"""
    return krotov.shapes.flattop(t,
                                 t_start=0.0,
                                 t_stop=10.0,
                                 t_rise=0.5,
                                 func='sinsq')


H = transmon_hamiltonian()
psi0, psi1 = logical_basis(H)
proj0 = qutip.ket2dm(psi0)
proj1 = qutip.ket2dm(psi1)

objectives = krotov.gate_objectives(basis_states=[psi0, psi1],
                                    gate=qutip.operators.sigmax(),
                                    H=H)

guess_dynamics = [
    objectives[x].mesolve(tlist, e_ops=[proj0, proj1]) for x in [0, 1]
]

plot_population(guess_dynamics[0])
plot_population(guess_dynamics[1])

pulse_options = {H[1][1]: dict(lambda_a=1, update_shape=S)}

opt_result = krotov.optimize_pulses(
    objectives,
    pulse_options,
    tlist,