def test_11_time_dependent_drift(self):
        """
        control.pulseoptim: Hadamard gate with fixed and time varying drift
        assert that goal is achieved for both and that different control
        pulses are produced (only) when they should be
        """
        # Hadamard
        H_0 = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 20
        evo_time = 10

        drift_amps_flat = np.ones([n_ts], dtype=float)
        dript_amps_step = [np.round(float(k)/n_ts) for k in range(n_ts)]

        # Run the optimisations
        result_fixed = cpo.optimize_pulse_unitary(H_0, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_(result_fixed.goal_achieved,
                    msg="Fixed drift goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_fixed.termination_reason, result_fixed.fid_err))

        H_d = [drift_amps_flat[k]*H_0 for k in range(n_ts)]
        result_flat = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_(result_flat.goal_achieved, msg="Flat drift goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_flat.termination_reason, result_flat.fid_err))

        # Check fixed and flat produced the same pulse
        assert_almost_equal(result_fixed.final_amps, result_flat.final_amps,
                            decimal=9,
                            err_msg="Flat and fixed drift result in "
                                    "different control pules")

        H_d = [dript_amps_step[k]*H_0 for k in range(n_ts)]
        result_step = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_(result_step.goal_achieved, msg="Step drift goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_step.termination_reason, result_step.fid_err))

        # Check step and flat produced different results
        assert_(np.any(
            np.abs(result_flat.final_amps - result_step.final_amps) > 1e-3),
                            msg="Flat and step drift result in "
                                    "the same control pules")
    def test_9_time_dependent_drift(self):
        """
        control.pulseoptim: Hadamard gate with fixed and time varying drift
        assert that goal is achieved for both and that different control
        pulses are produced (only) when they should be
        """
        # Hadamard
        H_0 = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 20
        evo_time = 10
        
        drift_amps_flat = np.ones([n_ts], dtype=float)
        dript_amps_step = [np.round(float(k)/n_ts) for k in range(n_ts)]
        
        # Run the optimisations
        result_fixed = cpo.optimize_pulse_unitary(H_0, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-10, 
                        init_pulse_type='LIN', 
                        gen_stats=True)
        assert_(result_fixed.goal_achieved, 
                    msg="Fixed drift goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_fixed.termination_reason, result_fixed.fid_err))
                    
        H_d = [drift_amps_flat[k]*H_0 for k in range(n_ts)]
        result_flat = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-10, 
                        init_pulse_type='LIN', 
                        gen_stats=True)
        assert_(result_flat.goal_achieved, msg="Flat drift goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_flat.termination_reason, result_flat.fid_err))
                    
        # Check fixed and flat produced the same pulse
        assert_almost_equal(result_fixed.final_amps, result_flat.final_amps, 
                            decimal=9, 
                            err_msg="Flat and fixed drift result in "
                                    "different control pules")
                            
        H_d = [dript_amps_step[k]*H_0 for k in range(n_ts)]
        result_step = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-10, 
                        init_pulse_type='LIN', 
                        gen_stats=True)
        assert_(result_step.goal_achieved, msg="Step drift goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_step.termination_reason, result_step.fid_err))
                    
        # Check step and flat produced different results
        assert_(np.any(
            np.abs(result_flat.final_amps - result_step.final_amps) > 1e-3), 
                            msg="Flat and step drift result in "
                                    "the same control pules")
Beispiel #3
0
    def test_02_1_qft(self):
        """
        control.pulseoptim: QFT gate with linear initial pulses
        assert that goal is achieved and fidelity error is below threshold
        """
        Sx = sigmax()
        Sy = sigmay()
        Sz = sigmaz()
        Si = 0.5 * identity(2)

        H_d = 0.5 * (tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz))
        H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)]
        U_0 = identity(4)
        # Target for the gate evolution - Quantum Fourier Transform gate
        U_targ = qft.qft(2)

        n_ts = 10
        evo_time = 10

        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-9,
                                            init_pulse_type='LIN',
                                            gen_stats=True)

        assert_(result.goal_achieved,
                msg="QFT goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
        assert_almost_equal(result.fid_err,
                            0.0,
                            decimal=7,
                            err_msg="QFT infidelity too high")

        # check bounds
        result2 = cpo.optimize_pulse_unitary(H_d,
                                             H_c,
                                             U_0,
                                             U_targ,
                                             n_ts,
                                             evo_time,
                                             fid_err_targ=1e-9,
                                             amp_lbound=-1.0,
                                             amp_ubound=1.0,
                                             init_pulse_type='LIN',
                                             gen_stats=True)
        assert_((result2.final_amps >= -1.0).all()
                and (result2.final_amps <= 1.0).all(),
                msg="Amplitude bounds exceeded for QFT")
 def test_state_to_state(self):
     """
     control.pulseoptim: state-to-state transfer 
     linear initial pulse used
     assert that goal is achieved
     """       
     # 2 qubits with Ising interaction
     # some arbitary coupling constants
     alpha = [0.9, 0.7]
     beta  = [0.8, 0.9]
     Sx = sigmax()
     Sz = sigmaz()
     H_d = (alpha[0]*tensor(Sx,identity(2)) + 
           alpha[1]*tensor(identity(2),Sx) +
           beta[0]*tensor(Sz,identity(2)) +
           beta[1]*tensor(identity(2),Sz))
     H_c = [tensor(Sz,Sz)]
     
     q1_0 = q2_0 = Qobj([[1], [0]])
     q1_T = q2_T = Qobj([[0], [1]])
     
     psi_0 = tensor(q1_0, q2_0)
     psi_T = tensor(q1_T, q2_T)
     
     n_ts = 10
     evo_time = 18
     
     # Run the optimisation
     result = cpo.optimize_pulse_unitary(H_d, H_c, psi_0, psi_T, 
                     n_ts, evo_time, 
                     fid_err_targ=1e-10, 
                     init_pulse_type='LIN', 
                     gen_stats=True)
     assert_(result.goal_achieved, msg="State-to-state goal not achieved. "
                 "Terminated due to: {}, with infidelity: {}".format(
                 result.termination_reason, result.fid_err))
     assert_almost_equal(result.fid_err, 0.0, decimal=10, 
                         err_msg="Hadamard infidelity too high")
                         
     #Try with Qobj propagation
     result = cpo.optimize_pulse_unitary(H_d, H_c, psi_0, psi_T, 
                     n_ts, evo_time, 
                     fid_err_targ=1e-10, 
                     init_pulse_type='LIN', 
                     dyn_params={'oper_dtype':Qobj},
                     gen_stats=True)
     assert_(result.goal_achieved, msg="State-to-state goal not achieved "
                 "(Qobj propagation)"
                 "Terminated due to: {}, with infidelity: {}".format(
                 result.termination_reason, result.fid_err))
    def test_01_2_unitary_hadamard_no_stats(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses (no stats)
        assert that goal is achieved
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        #Try without stats
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=False)
        assert_(result.goal_achieved, msg="Hadamard goal not achieved "
                                            "(no stats). "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
    def test_01_4_unitary_hadamard_qobj(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses (Qobj)
        assert that goal is achieved
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        #Try with Qobj propagation
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        dyn_params={'oper_dtype':Qobj},
                        gen_stats=True)
        assert_(result.goal_achieved, msg="Hadamard goal not achieved "
                                            "(Qobj propagation). "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
Beispiel #7
0
    def test_01_1_unitary_hadamard(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses
        assert that goal is achieved and fidelity error is below threshold
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            gen_stats=True)
        assert_(result.goal_achieved,
                msg="Hadamard goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
        assert_almost_equal(result.fid_err,
                            0.0,
                            decimal=10,
                            err_msg="Hadamard infidelity too high")
Beispiel #8
0
    def test_01_3_unitary_hadamard_tau(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses (tau)
        assert that goal is achieved
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        # Run the optimisation
        #Try setting timeslots with tau array
        tau = np.arange(1.0, 10.0, 1.0)
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            tau=tau,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            gen_stats=False)
        assert_(result.goal_achieved,
                msg="Hadamard goal not achieved "
                "(tau as timeslots). "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
Beispiel #9
0
    def test_01_2_unitary_hadamard_no_stats(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses (no stats)
        assert that goal is achieved
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        #Try without stats
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            gen_stats=False)
        assert_(result.goal_achieved,
                msg="Hadamard goal not achieved "
                "(no stats). "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
Beispiel #10
0
    def test_02_2_qft_bounds(self):
        """
        control.pulseoptim: QFT gate with linear initial pulses (bounds)
        assert that amplitudes remain in bounds
        """
        Sx = sigmax()
        Sy = sigmay()
        Sz = sigmaz()
        Si = 0.5 * identity(2)

        H_d = 0.5 * (tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz))
        H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)]
        U_0 = identity(4)
        # Target for the gate evolution - Quantum Fourier Transform gate
        U_targ = qft.qft(2)

        n_ts = 10
        evo_time = 10

        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-9,
                                            amp_lbound=-1.0,
                                            amp_ubound=1.0,
                                            init_pulse_type='LIN',
                                            gen_stats=True)
        assert_((result.final_amps >= -1.0).all()
                and (result.final_amps <= 1.0).all(),
                msg="Amplitude bounds exceeded for QFT")
Beispiel #11
0
    def test_01_4_unitary_hadamard_qobj(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses (Qobj)
        assert that goal is achieved
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        #Try with Qobj propagation
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            dyn_params={'oper_dtype': Qobj},
                                            gen_stats=True)
        assert_(result.goal_achieved,
                msg="Hadamard goal not achieved "
                "(Qobj propagation). "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
    def test_02_2_qft_bounds(self):
        """
        control.pulseoptim: QFT gate with linear initial pulses (bounds)
        assert that amplitudes remain in bounds
        """
        Sx = sigmax()
        Sy = sigmay()
        Sz = sigmaz()
        Si = 0.5*identity(2)

        H_d = 0.5*(tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz))
        H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)]
        U_0 = identity(4)
        # Target for the gate evolution - Quantum Fourier Transform gate
        U_targ = qft.qft(2)

        n_ts = 10
        evo_time = 10

        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-9,
                        amp_lbound=-1.0, amp_ubound=1.0,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_((result.final_amps >= -1.0).all() and
                    (result.final_amps <= 1.0).all(),
                    msg="Amplitude bounds exceeded for QFT")
Beispiel #13
0
def optimise_and_evaluate_fidelity(target_state_: Qobj,
                                   geometry: BaseGeometry):
    norm_V = C6 / (LATTICE_SPACING**6) / characteristic_V
    norm_H_d, norm_H_c, psi_0 = get_normalised_hamiltonian(N, norm_V, geometry)

    result = cpo.optimize_pulse_unitary(
        norm_H_d,
        norm_H_c,
        psi_0,
        target_state_,
        n_ts,
        norm_t,
        amp_lbound=-3,
        amp_ubound=3,
        # pulse_scaling=1, pulse_offset=1,
        gen_stats=True,
        alg="GRAPE",
        init_pulse_type="RND",
        max_wall_time=30,
        max_iter=5000,
        fid_err_targ=1e-3,
        log_level=qutip.logging_utils.WARN,
    )
    result.stats.report()

    final_fidelity = qutip.fidelity(target_state_, result.evo_full_final)**2
    print(f"Final fidelity: {final_fidelity:.5f}")

    print(f"Final gradient normal: {result.grad_norm_final:.3e}")
    print(f"Terminated due to: {result.termination_reason}")

    return final_fidelity
    def test_01_1_unitary_hadamard(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses
        assert that goal is achieved and fidelity error is below threshold
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_(result.goal_achieved, msg="Hadamard goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
        assert_almost_equal(result.fid_err, 0.0, decimal=10,
                            err_msg="Hadamard infidelity too high")
Beispiel #15
0
def get_pulseoptim_results(H_d, H_c, U_targ, alg='CRAB'):

    # Number of time slots
    n_ts = 10
    # Time allowed for the evolution
    evo_time = 1

    fid_err_targ = 1e-10
    # Maximum iterations for the optisation algorithm
    max_iter = 200
    # Maximum (elapsed) time allowed in seconds
    max_wall_time = 120
    # Minimum gradient (sum of gradients squared)
    # as this tends to 0 -> local minima has been found
    min_grad = 1e-20

    p_type = 'SQUARE'

    return cpo.optimize_pulse_unitary(H_d,
                                      H_c,
                                      identity(2),
                                      U_targ,
                                      n_ts,
                                      evo_time,
                                      fid_err_targ=fid_err_targ,
                                      min_grad=min_grad,
                                      max_iter=max_iter,
                                      max_wall_time=max_wall_time,
                                      out_file_ext=None,
                                      init_pulse_type=p_type,
                                      alg=alg,
                                      log_level=log_level,
                                      gen_stats=True)
    def test_02_1_qft(self):
        """
        control.pulseoptim: QFT gate with linear initial pulses
        assert that goal is achieved and fidelity error is below threshold
        """
        Sx = sigmax()
        Sy = sigmay()
        Sz = sigmaz()
        Si = 0.5*identity(2)

        H_d = 0.5*(tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz))
        H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)]
        U_0 = identity(4)
        # Target for the gate evolution - Quantum Fourier Transform gate
        U_targ = qft.qft(2)

        n_ts = 10
        evo_time = 10

        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-9,
                        init_pulse_type='LIN',
                        gen_stats=True)

        assert_(result.goal_achieved, msg="QFT goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
        assert_almost_equal(result.fid_err, 0.0, decimal=7,
                            err_msg="QFT infidelity too high")

        # check bounds
        result2 = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-9,
                        amp_lbound=-1.0, amp_ubound=1.0,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_((result2.final_amps >= -1.0).all() and
                    (result2.final_amps <= 1.0).all(),
                    msg="Amplitude bounds exceeded for QFT")
Beispiel #17
0
    def test_01_5_unitary_hadamard_oo(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses (OO)
        assert that goal is achieved and pulseoptim method achieves
        same result as OO method
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        optim = cpo.create_pulse_optimizer(H_d,
                                           H_c,
                                           U_0,
                                           U_targ,
                                           n_ts,
                                           evo_time,
                                           fid_err_targ=1e-10,
                                           dyn_type='UNIT',
                                           init_pulse_type='LIN',
                                           gen_stats=True)
        dyn = optim.dynamics

        init_amps = optim.pulse_generator.gen_pulse().reshape([-1, 1])
        dyn.initialize_controls(init_amps)

        result_oo = optim.run_optimization()

        # Run the pulseoptim func
        result_po = cpo.optimize_pulse_unitary(H_d,
                                               H_c,
                                               U_0,
                                               U_targ,
                                               n_ts,
                                               evo_time,
                                               fid_err_targ=1e-10,
                                               init_pulse_type='LIN',
                                               gen_stats=True)

        assert_almost_equal(result_oo.fid_err,
                            result_po.fid_err,
                            decimal=10,
                            err_msg="OO and pulseoptim methods produce "
                            "different results for Hadamard")
Beispiel #18
0
    def test_04_unitarity(self):
        """
        control: unitarity checking (via dump)
        Dump out processing data and use to check unitary evolution
        """

        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 1000
        evo_time = 4

        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-9,
                                            init_pulse_type='LIN',
                                            dyn_params={'dumping': 'FULL'},
                                            gen_stats=True)

        # check dumps were generated
        optim = result.optimizer
        dyn = optim.dynamics
        assert_(dyn.dump is not None, msg='dynamics dump not created')

        # Use the dump to check unitarity of all propagators and evo_ops
        dyn.unitarity_tol = 1e-14
        nu_prop = 0
        nu_fwd_evo = 0
        nu_onto_evo = 0
        for d in dyn.dump.evo_dumps:
            for k in range(dyn.num_tslots):
                if not dyn._is_unitary(d.prop[k]): nu_prop += 1
                if not dyn._is_unitary(d.fwd_evo[k]): nu_fwd_evo += 1
                if not dyn._is_unitary(d.onto_evo[k]): nu_onto_evo += 1
        assert_(nu_prop == 0,
                msg="{} propagators found to be non-unitary".format(nu_prop))
        assert_(
            nu_fwd_evo == 0,
            msg="{} fwd evo ops found to be non-unitary".format(nu_fwd_evo))
        assert_(
            nu_onto_evo == 0,
            msg="{} onto evo ops found to be non-unitary".format(nu_onto_evo))
def get_optimised_controls(N: int, n_ts: int, norm_t: float, norm_V: float, target_state_symmetric: bool = True,
                           optim_kwargs: dict = None,
                           ghz_state: BaseGHZState = None,
                           alg="GRAPE") -> OptimResult:
    norm_H_d, norm_H_c, psi_0 = get_normalised_hamiltonian(N, norm_V)
    if ghz_state is None:
        ghz_state = StandardGHZState(N)
    target_state = ghz_state.get_state_tensor(target_state_symmetric)

    optim_shared_kwargs = dict(
        amp_lbound=0, amp_ubound=3,
        # amp_lbound=0, amp_ubound=2e9 * norm_scaling,
        gen_stats=True,
        max_wall_time=300, max_iter=10000, fid_err_targ=1e-10,
        log_level=qutip.logging_utils.WARN,
    )

    optim_kwargs_ = {**optim_shared_kwargs}

    if alg == "GRAPE":
        optim_kwargs_['init_pulse_type'] = "RND"
    else:
        optim_kwargs_['guess_pulse_type'] = "RND"

    optim_kwargs_ = {**optim_kwargs_, **optim_kwargs}
    if alg == "GRAPE":
        norm_result = cpo.optimize_pulse_unitary(
            norm_H_d, norm_H_c,
            psi_0, target_state,
            n_ts, norm_t,
            # pulse_scaling=1e9 * norm_scaling, pulse_offset=1e9 * norm_scaling,
            # pulse_scaling=0.5,
            # optim_method="FMIN_BFGS",
            **optim_kwargs_
        )
    else:
        norm_result = cpo.opt_pulse_crab_unitary(
            norm_H_d, norm_H_c,
            psi_0, target_state,
            n_ts, norm_t,
            # num_coeffs=10,
            # guess_pulse_scaling=0.1,
            # guess_pulse_scaling=1e9 * norm_scaling, guess_pulse_offset=1e9 * norm_scaling,
            **optim_kwargs_
        )
    return norm_result
Beispiel #20
0
    def test_05_1_state_to_state(self):
        """
        control.pulseoptim: state-to-state transfer
        linear initial pulse used
        assert that goal is achieved
        """
        # 2 qubits with Ising interaction
        # some arbitary coupling constants
        alpha = [0.9, 0.7]
        beta = [0.8, 0.9]
        Sx = sigmax()
        Sz = sigmaz()
        H_d = (alpha[0] * tensor(Sx, identity(2)) +
               alpha[1] * tensor(identity(2), Sx) +
               beta[0] * tensor(Sz, identity(2)) +
               beta[1] * tensor(identity(2), Sz))
        H_c = [tensor(Sz, Sz)]

        q1_0 = q2_0 = Qobj([[1], [0]])
        q1_T = q2_T = Qobj([[0], [1]])

        psi_0 = tensor(q1_0, q2_0)
        psi_T = tensor(q1_T, q2_T)

        n_ts = 10
        evo_time = 18

        # Run the optimisation
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            psi_0,
                                            psi_T,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            gen_stats=True)
        assert_(result.goal_achieved,
                msg="State-to-state goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
        assert_almost_equal(result.fid_err,
                            0.0,
                            decimal=10,
                            err_msg="Hadamard infidelity too high")
    def test_04_unitarity(self):
        """
        control: unitarity checking (via dump)
        Dump out processing data and use to check unitary evolution
        """

        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 1000
        evo_time = 4

        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-9,
                        init_pulse_type='LIN',
                        dyn_params={'dumping':'FULL'},
                        gen_stats=True)

        # check dumps were generated
        optim = result.optimizer
        dyn = optim.dynamics
        assert_(dyn.dump is not None, msg='dynamics dump not created')

        # Use the dump to check unitarity of all propagators and evo_ops
        dyn.unitarity_tol = 1e-14
        nu_prop = 0
        nu_fwd_evo = 0
        nu_onto_evo = 0
        for d in dyn.dump.evo_dumps:
            for k in range(dyn.num_tslots):
                if not dyn._is_unitary(d.prop[k]): nu_prop += 1
                if not dyn._is_unitary(d.fwd_evo[k]): nu_fwd_evo += 1
                if not dyn._is_unitary(d.onto_evo[k]): nu_onto_evo += 1
        assert_(nu_prop==0,
                msg="{} propagators found to be non-unitary".format(nu_prop))
        assert_(nu_fwd_evo==0,
                msg="{} fwd evo ops found to be non-unitary".format(
                                                                nu_fwd_evo))
        assert_(nu_onto_evo==0,
                msg="{} onto evo ops found to be non-unitary".format(
                                                                nu_onto_evo))
def get_optimised_controls(N: int, n_ts: int, alg: str,
                           norm_geometry: BaseGeometry) -> OptimResult:
    norm_H_d, norm_H_c, psi_0 = get_normalised_hamiltonian(N, norm_geometry)
    target_state = StandardGHZState(N).get_state_tensor()

    norm_scaling = 0.5 / characteristic_V

    optim_shared_kwargs = dict(
        amp_lbound=AMP_BOUNDS[0],
        amp_ubound=AMP_BOUNDS[1],
        # amp_lbound=0, amp_ubound=2e9 * norm_scaling,
        gen_stats=True,
        max_wall_time=MAX_WALL_TIME,
        max_iter=10000000,
        fid_err_targ=1e-10,
        log_level=qutip.logging_utils.WARN,
    )
    if alg == "GRAPE":
        norm_result = cpo.optimize_pulse_unitary(
            norm_H_d,
            norm_H_c,
            psi_0,
            target_state,
            n_ts,
            norm_t,
            # pulse_scaling=1e9 * norm_scaling, pulse_offset=1e9 * norm_scaling,
            # pulse_scaling=0.5,
            # optim_method="FMIN_BFGS",
            init_pulse_type="RND",
            **optim_shared_kwargs)
    else:
        norm_result = cpo.opt_pulse_crab_unitary(
            norm_H_d,
            norm_H_c,
            psi_0,
            target_state,
            n_ts,
            norm_t,
            num_coeffs=20,
            guess_pulse_scaling=0.1,
            # guess_pulse_scaling=1e9 * norm_scaling, guess_pulse_offset=1e9 * norm_scaling,
            guess_pulse_type="RND",
            **optim_shared_kwargs)
    return norm_result
Beispiel #23
0
    def test_05_2_state_to_state_qobj(self):
        """
        control.pulseoptim: state-to-state transfer (Qobj)
        linear initial pulse used
        assert that goal is achieved
        """
        # 2 qubits with Ising interaction
        # some arbitary coupling constants
        alpha = [0.9, 0.7]
        beta = [0.8, 0.9]
        Sx = sigmax()
        Sz = sigmaz()
        H_d = (alpha[0] * tensor(Sx, identity(2)) +
               alpha[1] * tensor(identity(2), Sx) +
               beta[0] * tensor(Sz, identity(2)) +
               beta[1] * tensor(identity(2), Sz))
        H_c = [tensor(Sz, Sz)]

        q1_0 = q2_0 = Qobj([[1], [0]])
        q1_T = q2_T = Qobj([[0], [1]])

        psi_0 = tensor(q1_0, q2_0)
        psi_T = tensor(q1_T, q2_T)

        n_ts = 10
        evo_time = 18

        #Try with Qobj propagation
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            psi_0,
                                            psi_T,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            dyn_params={'oper_dtype': Qobj},
                                            gen_stats=True)
        assert_(result.goal_achieved,
                msg="State-to-state goal not achieved "
                "(Qobj propagation)"
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
    def test_01_5_unitary_hadamard_oo(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses (OO)
        assert that goal is achieved and pulseoptim method achieves
        same result as OO method
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        optim = cpo.create_pulse_optimizer(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        dyn_type='UNIT',
                        init_pulse_type='LIN',
                        gen_stats=True)
        dyn = optim.dynamics

        init_amps = optim.pulse_generator.gen_pulse().reshape([-1, 1])
        dyn.initialize_controls(init_amps)

        result_oo = optim.run_optimization()

        # Run the pulseoptim func
        result_po = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=True)

        assert_almost_equal(result_oo.fid_err, result_po.fid_err, decimal=10,
                            err_msg="OO and pulseoptim methods produce "
                                    "different results for Hadamard")
    def test_01_3_unitary_hadamard_tau(self):
        """
        control.pulseoptim: Hadamard gate with linear initial pulses (tau)
        assert that goal is achieved
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        # Run the optimisation
        #Try setting timeslots with tau array
        tau = np.arange(1.0, 10.0, 1.0)
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        tau=tau,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=False)
        assert_(result.goal_achieved, msg="Hadamard goal not achieved "
                                            "(tau as timeslots). "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
Beispiel #26
0
# Maximum (elapsed) time allowed in seconds
max_wall_time = 1600
# Minimum gradient (sum of gradients squared)
# as this tends to 0 -> local minima has been found
min_grad = 1e-20
p_type = 'CUSTOM'
for evo_time in evo_times:
    n_ts = int(float(evo_time / 0.222))
    result = cpo.optimize_pulse_unitary(H0,
                                        Hc,
                                        U0,
                                        u_targ,
                                        n_ts,
                                        evo_time,
                                        amp_lbound=0,
                                        amp_ubound=1,
                                        fid_err_targ=fid_err_targ,
                                        min_grad=min_grad,
                                        max_iter=max_iter,
                                        max_wall_time=max_wall_time,
                                        out_file_ext=None,
                                        init_pulse_type=p_type,
                                        log_level=log_level,
                                        gen_stats=True)
    result.stats.report()
    print("Final evolution\n{}\n".format(result.evo_full_final))
    print("********* Summary *****************")
    print("Initial fidelity error {}".format(result.initial_fid_err))
    print("Final fidelity error {}".format(result.fid_err))
    print("Final gradient normal {}".format(result.grad_norm_final))
    print("Terminated due to {}".format(result.termination_reason))
    print("Number of iterations {}".format(result.num_iter))
Beispiel #27
0
    def test_09_load_params(self):
        """
        control.pulseoptim: Hadamard gate (loading config from file)
        compare with result produced by pulseoptim method
        """
        H_d = sigmaz()
        H_c = sigmax()

        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        cfg = optimconfig.OptimConfig()
        cfg.param_fname = "Hadamard_params.ini"
        cfg.param_fpath = os.path.join(os.path.dirname(__file__),
                                       cfg.param_fname)
        cfg.pulse_type = "ZERO"
        loadparams.load_parameters(cfg.param_fpath, config=cfg)

        dyn = dynamics.DynamicsUnitary(cfg)
        dyn.target = U_targ
        dyn.initial = U_0
        dyn.drift_dyn_gen = H_d
        dyn.ctrl_dyn_gen = [H_c]
        loadparams.load_parameters(cfg.param_fpath, dynamics=dyn)
        dyn.init_timeslots()
        n_ts = dyn.num_tslots
        n_ctrls = dyn.num_ctrls

        pgen = pulsegen.create_pulse_gen(pulse_type=cfg.pulse_type, dyn=dyn)
        loadparams.load_parameters(cfg.param_fpath, pulsegen=pgen)

        tc = termcond.TerminationConditions()
        loadparams.load_parameters(cfg.param_fpath, term_conds=tc)

        if cfg.optim_method == 'BFGS':
            optim = optimizer.OptimizerBFGS(cfg, dyn)
        elif cfg.optim_method == 'FMIN_L_BFGS_B':
            optim = optimizer.OptimizerLBFGSB(cfg, dyn)
        elif cfg.optim_method is None:
            raise errors.UsageError("Optimisation algorithm must be specified "
                                    "via 'optim_method' parameter")
        else:
            optim = optimizer.Optimizer(cfg, dyn)
            optim.method = cfg.optim_method
        loadparams.load_parameters(cfg.param_fpath, optim=optim)

        sts = stats.Stats()
        dyn.stats = sts
        optim.stats = sts
        optim.config = cfg
        optim.dynamics = dyn
        optim.pulse_generator = pgen
        optim.termination_conditions = tc

        init_amps = np.zeros([n_ts, n_ctrls])
        for j in range(n_ctrls):
            init_amps[:, j] = pgen.gen_pulse()
        dyn.initialize_controls(init_amps)
        result = optim.run_optimization()

        result2 = cpo.optimize_pulse_unitary(H_d,
                                             list([H_c]),
                                             U_0,
                                             U_targ,
                                             6,
                                             6,
                                             fid_err_targ=1e-10,
                                             init_pulse_type='LIN',
                                             amp_lbound=-1.0,
                                             amp_ubound=1.0,
                                             gen_stats=True)

        assert_almost_equal(result.final_amps,
                            result2.final_amps,
                            decimal=5,
                            err_msg="Pulses do not match")
    def test_03_dumping(self):
        """
        control: data dumping
        Dump out processing data, check file counts
        """
        N_EXP_OPTIMDUMP_FILES = 10
        N_EXP_DYNDUMP_FILES = 49

        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 1000
        evo_time = 4

        dump_folder = str(uuid.uuid4())
        qtrl_dump_dir = os.path.expanduser(os.path.join('~', dump_folder))
        self.tmp_dirs.append(qtrl_dump_dir)
        optim_dump_dir = os.path.join(qtrl_dump_dir, 'optim')
        dyn_dump_dir = os.path.join(qtrl_dump_dir, 'dyn')
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-9,
                        init_pulse_type='LIN',
                        optim_params={'dumping':'FULL', 'dump_to_file':True,
                                    'dump_dir':optim_dump_dir},
                        dyn_params={'dumping':'FULL', 'dump_to_file':True,
                                    'dump_dir':dyn_dump_dir},
                        gen_stats=True)

        # check dumps were generated
        optim = result.optimizer
        dyn = optim.dynamics
        assert_(optim.dump is not None, msg='optimizer dump not created')
        assert_(dyn.dump is not None, msg='dynamics dump not created')

        # Count files that were output
        nfiles = len(os.listdir(optim.dump.dump_dir))
        assert_(nfiles == N_EXP_OPTIMDUMP_FILES,
                msg="{} optimizer dump files generated, {} expected".format(
                    nfiles, N_EXP_OPTIMDUMP_FILES))

        nfiles = len(os.listdir(dyn.dump.dump_dir))
        assert_(nfiles == N_EXP_DYNDUMP_FILES,
                msg="{} dynamics dump files generated, {} expected".format(
                    nfiles, N_EXP_DYNDUMP_FILES))

        # dump all to specific file stream
        fpath = os.path.expanduser(os.path.join('~', str(uuid.uuid4())))
        self.tmp_files.append(fpath)
        with open(fpath, 'wb') as f:
            optim.dump.writeout(f)

        assert_(os.stat(fpath).st_size > 0,
                msg="Nothing written to optimizer dump file")

        fpath = os.path.expanduser(os.path.join('~', str(uuid.uuid4())))
        self.tmp_files.append(fpath)
        with open(fpath, 'wb') as f:
            dyn.dump.writeout(f)
        assert_(os.stat(fpath).st_size > 0,
                msg="Nothing written to dynamics dump file")
    def test_12_time_dependent_ctrls(self):
        """
        control.pulseoptim: Hadamard gate with fixed and time varying ctrls
        assert that goal is achieved for both and that different control
        pulses are produced (only) when they should be.
        """
        # Hadamard
        H_0 = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 20
        evo_time = 10

        # Run the optimisations
        result_fixed = cpo.optimize_pulse_unitary(H_0, H_c, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_(result_fixed.goal_achieved,
                    msg="Fixed ctrls goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_fixed.termination_reason, result_fixed.fid_err))

        H_c_t = []
        for k in range(n_ts):
            H_c_t.append([sigmax()])
        result_tdcs = cpo.optimize_pulse_unitary(H_0, H_c_t, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_(result_tdcs.goal_achieved,
                msg="td same ctrl goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_tdcs.termination_reason, result_tdcs.fid_err))

        # Check fixed and same produced the same pulse
        assert_almost_equal(result_fixed.final_amps, result_tdcs.final_amps,
                            decimal=9,
                            err_msg="same and fixed ctrls result in "
                                    "different control pules")

        H_c_t = []
        for k in range(n_ts):
            if k % 3 == 0:
                H_c_t.append([sigmax()])
            else:
                H_c_t.append([identity(2)])
        result_tdcv = cpo.optimize_pulse_unitary(H_0, H_c_t, U_0, U_targ,
                        n_ts, evo_time,
                        fid_err_targ=1e-10,
                        init_pulse_type='LIN',
                        gen_stats=True)
        assert_(result_tdcv.goal_achieved,
                msg="true td ctrls goal not achieved. "
                    "Terminated due to: {}, with infidelity: {}".format(
                    result_tdcv.termination_reason, result_tdcv.fid_err))

        # Check that identity control tslots don't vary

        for k in range(n_ts):
            if k % 3 != 0:
                assert_almost_equal(result_tdcv.initial_amps[k, 0],
                                    result_tdcv.final_amps[k, 0],
                                    decimal=9,
                                    err_msg=("timeslot {} amps should remain "
                                            "fixed").format(k))
Beispiel #30
0
if __name__ == "__main__":
    Drift_Hamiltonian, Control_hamiltonian, Initial_unitary, Target_unitary, \
        num_timesteps, evolution_time, fidelity_error_required, max_iter, max_wall_time, \
            minimum_gradient, p_type = initialize_parameters()

    # Start timer
    start_time = time.time()

    # Run optimization
    result = cpo.optimize_pulse_unitary(Drift_Hamiltonian,
                                        Control_hamiltonian,
                                        Initial_unitary,
                                        Target_unitary,
                                        num_timesteps,
                                        evolution_time,
                                        fid_err_targ=fidelity_error_required,
                                        min_grad=minimum_gradient,
                                        max_iter=max_iter,
                                        max_wall_time=max_wall_time,
                                        init_pulse_type=p_type,
                                        log_level=log_level,
                                        gen_stats=True)

    # Output results
    result.stats.report()
    print("Final evolution\n{}\n".format(result.evo_full_final))
    print(result.termination_reason)
    print("Optimization duration: " + str(time.time() - start_time) +
          " seconds")

    plot = plt.figure()
Beispiel #31
0
    def test_03_dumping(self):
        """
        control: data dumping
        Dump out processing data, check file counts
        """
        self.setUp()
        N_EXP_OPTIMDUMP_FILES = 10
        N_EXP_DYNDUMP_FILES = 49

        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 1000
        evo_time = 4

        dump_folder = str(uuid.uuid4())
        qtrl_dump_dir = os.path.expanduser(os.path.join('~', dump_folder))
        self.tmp_dirs.append(qtrl_dump_dir)
        optim_dump_dir = os.path.join(qtrl_dump_dir, 'optim')
        dyn_dump_dir = os.path.join(qtrl_dump_dir, 'dyn')
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-9,
                                            init_pulse_type='LIN',
                                            optim_params={
                                                'dumping': 'FULL',
                                                'dump_to_file': True,
                                                'dump_dir': optim_dump_dir
                                            },
                                            dyn_params={
                                                'dumping': 'FULL',
                                                'dump_to_file': True,
                                                'dump_dir': dyn_dump_dir
                                            },
                                            gen_stats=True)

        # check dumps were generated
        optim = result.optimizer
        dyn = optim.dynamics
        assert_(optim.dump is not None, msg='optimizer dump not created')
        assert_(dyn.dump is not None, msg='dynamics dump not created')

        # Count files that were output
        nfiles = len(os.listdir(optim.dump.dump_dir))
        assert_(nfiles == N_EXP_OPTIMDUMP_FILES,
                msg="{} optimizer dump files generated, {} expected".format(
                    nfiles, N_EXP_OPTIMDUMP_FILES))

        nfiles = len(os.listdir(dyn.dump.dump_dir))
        assert_(nfiles == N_EXP_DYNDUMP_FILES,
                msg="{} dynamics dump files generated, {} expected".format(
                    nfiles, N_EXP_DYNDUMP_FILES))

        # dump all to specific file stream
        fpath = os.path.expanduser(os.path.join('~', str(uuid.uuid4())))
        self.tmp_files.append(fpath)
        with open(fpath, 'wb') as f:
            optim.dump.writeout(f)

        assert_(os.stat(fpath).st_size > 0,
                msg="Nothing written to optimizer dump file")

        fpath = os.path.expanduser(os.path.join('~', str(uuid.uuid4())))
        self.tmp_files.append(fpath)
        with open(fpath, 'wb') as f:
            dyn.dump.writeout(f)
        assert_(os.stat(fpath).st_size > 0,
                msg="Nothing written to dynamics dump file")
        self.tearDown()
Beispiel #32
0
    def test_1_unitary(self):
        """
        control.pulseoptim: Hadamard and QFT gate with linear initial pulses
        assert that goal is achieved and fidelity error is below threshold
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Run the optimisation
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            gen_stats=True)
        assert_(result.goal_achieved,
                msg="Hadamard goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
        assert_almost_equal(result.fid_err,
                            0.0,
                            decimal=10,
                            err_msg="Hadamard infidelity too high")

        #Try without stats
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            gen_stats=False)
        assert_(result.goal_achieved,
                msg="Hadamard goal not achieved "
                "(no stats). "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))

        #Try with Qobj propagation
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-10,
                                            init_pulse_type='LIN',
                                            dyn_params={'oper_dtype': Qobj},
                                            gen_stats=True)
        assert_(result.goal_achieved,
                msg="Hadamard goal not achieved "
                "(Qobj propagation). "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))

        # Check same result is achieved using the create objects method
        optim = cpo.create_pulse_optimizer(H_d,
                                           H_c,
                                           U_0,
                                           U_targ,
                                           n_ts,
                                           evo_time,
                                           fid_err_targ=1e-10,
                                           dyn_type='UNIT',
                                           init_pulse_type='LIN',
                                           gen_stats=True)
        dyn = optim.dynamics

        init_amps = optim.pulse_generator.gen_pulse().reshape([-1, 1])
        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="Unitary gradient outside tolerance")

        result2 = optim.run_optimization()
        assert_almost_equal(result.fid_err,
                            result2.fid_err,
                            decimal=10,
                            err_msg="Direct and indirect methods produce "
                            "different results for Hadamard")

        # QFT
        Sx = sigmax()
        Sy = sigmay()
        Sz = sigmaz()
        Si = 0.5 * identity(2)

        H_d = 0.5 * (tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz))
        H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)]
        #n_ctrls = len(H_c)
        U_0 = identity(4)
        # Target for the gate evolution - Quantum Fourier Transform gate
        U_targ = qft.qft(2)
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-9,
                                            init_pulse_type='LIN',
                                            gen_stats=True)

        assert_(result.goal_achieved,
                msg="QFT goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
        assert_almost_equal(result.fid_err,
                            0.0,
                            decimal=7,
                            err_msg="QFT infidelity too high")

        # check bounds
        result2 = cpo.optimize_pulse_unitary(H_d,
                                             H_c,
                                             U_0,
                                             U_targ,
                                             n_ts,
                                             evo_time,
                                             fid_err_targ=1e-9,
                                             amp_lbound=-1.0,
                                             amp_ubound=1.0,
                                             init_pulse_type='LIN',
                                             gen_stats=True)
        assert_((result2.final_amps >= -1.0).all()
                and (result2.final_amps <= 1.0).all(),
                msg="Amplitude bounds exceeded for QFT")
Beispiel #33
0
    def test_2_dumping_and_unitarity(self):
        """
        control: data dumping and unitarity checking
        Dump out processing data and use to check unitary evolution
        """
        N_EXP_OPTIMDUMP_FILES = 10
        N_EXP_DYNDUMP_FILES = 49

        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 1000
        evo_time = 4

        dump_folder = str(uuid.uuid4())
        qtrl_dump_dir = os.path.expanduser(os.path.join('~', dump_folder))
        self.tmp_dirs.append(qtrl_dump_dir)
        optim_dump_dir = os.path.join(qtrl_dump_dir, 'optim')
        dyn_dump_dir = os.path.join(qtrl_dump_dir, 'dyn')
        result = cpo.optimize_pulse_unitary(H_d,
                                            H_c,
                                            U_0,
                                            U_targ,
                                            n_ts,
                                            evo_time,
                                            fid_err_targ=1e-9,
                                            init_pulse_type='LIN',
                                            optim_params={
                                                'dumping': 'FULL',
                                                'dump_to_file': True,
                                                'dump_dir': optim_dump_dir
                                            },
                                            dyn_params={
                                                'dumping': 'FULL',
                                                'dump_to_file': True,
                                                'dump_dir': dyn_dump_dir
                                            },
                                            gen_stats=True)

        # check dumps were generated
        optim = result.optimizer
        dyn = optim.dynamics
        assert_(optim.dump is not None, msg='optimizer dump not created')
        assert_(dyn.dump is not None, msg='dynamics dump not created')

        # Count files that were output
        nfiles = len(os.listdir(optim.dump.dump_dir))
        assert_(nfiles == N_EXP_OPTIMDUMP_FILES,
                msg="{} optimizer dump files generated, {} expected".format(
                    nfiles, N_EXP_OPTIMDUMP_FILES))

        nfiles = len(os.listdir(dyn.dump.dump_dir))
        assert_(nfiles == N_EXP_DYNDUMP_FILES,
                msg="{} dynamics dump files generated, {} expected".format(
                    nfiles, N_EXP_DYNDUMP_FILES))

        # dump all to specific file stream
        fpath = os.path.expanduser(os.path.join('~', str(uuid.uuid4())))
        self.tmp_files.append(fpath)
        with open(fpath, 'wb') as f:
            optim.dump.writeout(f)

        assert_(os.stat(fpath).st_size > 0,
                msg="Nothing written to optimizer dump file")

        fpath = os.path.expanduser(os.path.join('~', str(uuid.uuid4())))
        self.tmp_files.append(fpath)
        with open(fpath, 'wb') as f:
            dyn.dump.writeout(f)
        assert_(os.stat(fpath).st_size > 0,
                msg="Nothing written to dynamics dump file")

        # Use the dump to check unitarity of all propagators and evo_ops
        dyn.unitarity_tol = 1e-14
        nu_prop = 0
        nu_fwd_evo = 0
        nu_onto_evo = 0
        for d in dyn.dump.evo_dumps:
            for k in range(dyn.num_tslots):
                if not dyn._is_unitary(d.prop[k]): nu_prop += 1
                if not dyn._is_unitary(d.fwd_evo[k]): nu_fwd_evo += 1
                if not dyn._is_unitary(d.onto_evo[k]): nu_onto_evo += 1
        assert_(nu_prop == 0,
                msg="{} propagators found to be non-unitary".format(nu_prop))
        assert_(
            nu_fwd_evo == 0,
            msg="{} fwd evo ops found to be non-unitary".format(nu_fwd_evo))
        assert_(
            nu_onto_evo == 0,
            msg="{} onto evo ops found to be non-unitary".format(nu_onto_evo))
Beispiel #34
0
# Setup
N = 1
H_d = sigmaz()
H_c = [sigmax()]

qc = QubitCircuit(N)
qc.add_gate("SNOT", 0)
hadamard = qc.propagators()[0]

U_targ = hadamard
U_0 = identity(U_targ.dims[0])
n_ts = 10
evo_time = 10

# Calculate amps with pulseoptim
qtrlresult = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time)
qtrl_amps = qtrlresult.final_amps[:, 0]

print("Fidelity error from optimal pulse:", qtrlresult.fid_err)

# My way of solving the in consistensy in get_amp:
# Modify time and amps a bit, so that it becomes
# new_tlist = [ 0, 1, 2, 3, 4, 5, 6...,10,11]
# new_amps =  [ 0,a0,a1,a2,a3,a4,a5...,a9, 0]
tau = int(evo_time / n_ts)
# Add a 1.0e-10 to conpensate the unstable round(x.5)
new_tlist = np.hstack([qtrlresult.time, [qtrlresult.time[-1] + tau]]) + 1.0e-10
new_amps = np.hstack([[0.], qtrl_amps, [0.]])

# calculate the refined time and amplitude with get_amp
dt = 0.001
Beispiel #35
0
    def test_unitary(self):
        """
        Optimise pulse for Hadamard and QFT gate with linear initial pulses
        assert that goal is achieved and fidelity error is below threshold
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 6
        
        # Run the optimisation
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-10, 
                        init_pulse_type='LIN', 
                        gen_stats=True)
        assert_(result.goal_achieved, msg="Hadamard goal not achieved")
        assert_almost_equal(result.fid_err, 0.0, decimal=10, 
                            err_msg="Hadamard infidelity too high")
                            
        #Try without stats
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-10, 
                        init_pulse_type='LIN', 
                        gen_stats=False)
        assert_(result.goal_achieved, msg="Hadamard goal not achieved "
                                            "(no stats)")
                                            
        #Try with Qobj propagation
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-10, 
                        init_pulse_type='LIN', 
                        dyn_params={'oper_dtype':Qobj},
                        gen_stats=True)
        assert_(result.goal_achieved, msg="Hadamard goal not achieved "
                                            "(Qobj propagation)")
        
        # Check same result is achieved using the create objects method
        optim = cpo.create_pulse_optimizer(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-10, 
                        dyn_type='UNIT', 
                        init_pulse_type='LIN', 
                        gen_stats=True)
        dyn = optim.dynamics

        init_amps = optim.pulse_generator.gen_pulse().reshape([-1, 1])
        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="Unitary gradient outside tolerance")

        result2 = optim.run_optimization()
        assert_almost_equal(result.fid_err, result2.fid_err, decimal=10, 
                            err_msg="Direct and indirect methods produce "
                                    "different results for Hadamard")
                                    
        # QFT
        Sx = sigmax()
        Sy = sigmay()
        Sz = sigmaz()
        Si = 0.5*identity(2)
        
        H_d = 0.5*(tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz))
        H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)]
        #n_ctrls = len(H_c)
        U_0 = identity(4)
        # Target for the gate evolution - Quantum Fourier Transform gate
        U_targ = qft.qft(2)
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-9, 
                        init_pulse_type='LIN', 
                        gen_stats=True)
                        
        assert_(result.goal_achieved, msg="QFT goal not achieved")
        assert_almost_equal(result.fid_err, 0.0, decimal=7, 
                            err_msg="QFT infidelity too high")
                            
        # check bounds
        result2 = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-9, 
                        amp_lbound=-1.0, amp_ubound=1.0,
                        init_pulse_type='LIN', 
                        gen_stats=True)
        assert_((result2.final_amps >= -1.0).all() and 
                    (result2.final_amps <= 1.0).all(), 
                    msg="Amplitude bounds exceeded for QFT")
f_ext = "{}_n_ts{}_ptype{}.txt".format(example_name, n_ts, p_type)

# Run the optimisation
print("\n***********************************")
print("Starting pulse optimisation")
result = cpo.optimize_pulse_unitary(
    H_d,
    H_c,
    psi_0,
    psi_T,
    n_ts,
    evo_time,
    fid_err_targ=fid_err_targ,
    max_iter=max_iter,
    max_wall_time=max_wall_time,
    #                dyn_params={'oper_dtype':Qobj},
    # comment in/out these next three lines for CRAB/GRAPE
    #                alg='CRAB',
    #                alg_params={'init_coeff_scaling':5.0, 'num_coeffs':5, 'guess_pulse_type':None},
    #                method_params={'xtol':1e-3},
    fid_params={'phase_option': 'PSU'},
    out_file_ext=f_ext,
    init_pulse_type=p_type,
    log_level=log_level,
    gen_stats=True)

print("\n***********************************")
print("Optimising complete. Stats follow:")
result.stats.report()
print("\nFinal evolution\n{}\n".format(result.evo_full_final))
Beispiel #37
0
    def test_12_time_dependent_ctrls(self):
        """
        control.pulseoptim: Hadamard gate with fixed and time varying ctrls
        assert that goal is achieved for both and that different control
        pulses are produced (only) when they should be.
        """
        # Hadamard
        H_0 = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 20
        evo_time = 10

        # Run the optimisations
        result_fixed = cpo.optimize_pulse_unitary(H_0,
                                                  H_c,
                                                  U_0,
                                                  U_targ,
                                                  n_ts,
                                                  evo_time,
                                                  fid_err_targ=1e-10,
                                                  init_pulse_type='LIN',
                                                  gen_stats=True)
        assert_(result_fixed.goal_achieved,
                msg="Fixed ctrls goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result_fixed.termination_reason, result_fixed.fid_err))

        H_c_t = []
        for k in range(n_ts):
            H_c_t.append([sigmax()])
        result_tdcs = cpo.optimize_pulse_unitary(H_0,
                                                 H_c_t,
                                                 U_0,
                                                 U_targ,
                                                 n_ts,
                                                 evo_time,
                                                 fid_err_targ=1e-10,
                                                 init_pulse_type='LIN',
                                                 gen_stats=True)
        assert_(result_tdcs.goal_achieved,
                msg="td same ctrl goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result_tdcs.termination_reason, result_tdcs.fid_err))

        # Check fixed and same produced the same pulse
        assert_almost_equal(result_fixed.final_amps,
                            result_tdcs.final_amps,
                            decimal=9,
                            err_msg="same and fixed ctrls result in "
                            "different control pules")

        H_c_t = []
        for k in range(n_ts):
            if k % 3 == 0:
                H_c_t.append([sigmax()])
            else:
                H_c_t.append([identity(2)])
        result_tdcv = cpo.optimize_pulse_unitary(H_0,
                                                 H_c_t,
                                                 U_0,
                                                 U_targ,
                                                 n_ts,
                                                 evo_time,
                                                 fid_err_targ=1e-10,
                                                 init_pulse_type='LIN',
                                                 gen_stats=True)
        assert_(result_tdcv.goal_achieved,
                msg="true td ctrls goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result_tdcv.termination_reason, result_tdcv.fid_err))

        # Check that identity control tslots don't vary

        for k in range(n_ts):
            if k % 3 != 0:
                assert_almost_equal(result_tdcv.initial_amps[k, 0],
                                    result_tdcv.final_amps[k, 0],
                                    decimal=9,
                                    err_msg=("timeslot {} amps should remain "
                                             "fixed").format(k))
    def load_circuit(self, qc, min_fid_err=np.inf, merge_gates=True,
                     setting_args=None, verbose=False, **kwargs):
        """
        Find the pulses realizing a given :class:`qutip.qip.Circuit` using
        `qutip.control.optimize_pulse_unitary`. Further parameter for
        for `qutip.control.optimize_pulse_unitary` needs to be given as
        keyword arguments. By default, it first merge all the gates
        into one unitary and then find the control pulses for it.
        It can be turned off and one can set different parameters
        for different gates. See examples for details.

        Examples
        --------
        # Same parameter for all the gates
        qc = QubitCircuit(N=1)
        qc.add_gate("SNOT", 0)

        num_tslots = 10
        evo_time = 10
        processor = OptPulseProcessor(N=1, drift=sigmaz(), ctrls=[sigmax()])
        # num_tslots and evo_time are two keyword arguments
        tlist, coeffs = processor.load_circuit(
            qc, num_tslots=num_tslots, evo_time=evo_time)

        # Different parameters for different gates
        qc = QubitCircuit(N=2)
        qc.add_gate("SNOT", 0)
        qc.add_gate("SWAP", targets=[0, 1])
        qc.add_gate('CNOT', controls=1, targets=[0])

        processor = OptPulseProcessor(N=2, drift=tensor([sigmaz()]*2))
        processor.add_ctrl(sigmax(), cyclic_permutation=True)
        processor.add_ctrl(sigmay(), cyclic_permutation=True)
        processor.add_ctrl(tensor([sigmay(), sigmay()]))
        setting_args = {"SNOT": {"num_tslots": 10, "evo_time": 1},
                        "SWAP": {"num_tslots": 30, "evo_time": 3},
                        "CNOT": {"num_tslots": 30, "evo_time": 3}}
        tlist, coeffs = processor.load_circuit(qc, setting_args=setting_args,
                                               merge_gates=False)

        Parameters
        ----------
        qc: :class:`qutip.QubitCircuit` or list of Qobj
            The quantum circuit to be translated.

        min_fid_err: float, optional
            The minimal fidelity tolerance, if the fidelity error of any
            gate decomposition is higher, a warning will be given.
            Default is infinite.

        merge_gates: boolean, optimal
            If True, merge all gate/Qobj into one Qobj and then
            find the optimal pulses for this unitary matrix. If False,
            find the optimal pulses for each gate/Qobj.

        setting_args: dict, optional
            Only considered if merge_gates is False.
            It is a dictionary containing keyword arguments
            for different gates.

            E.g:
            setting_args = {"SNOT": {"num_tslots": 10, "evo_time": 1},
                            "SWAP": {"num_tslots": 30, "evo_time": 3},
                            "CNOT": {"num_tslots": 30, "evo_time": 3}}

        verbose: boolean, optional
            If true, the information for each decomposed gate
            will be shown. Default is False.

        **kwargs
            keyword arguments for `qutip.control.optimize_pulse_unitary`

        Returns
        -------
        tlist: array_like
            A NumPy array specifies the time of each coefficient

        coeffs: array_like
            A 2d NumPy array of the shape (len(ctrls), len(tlist)-1). Each
            row corresponds to the control pulse sequence for
            one Hamiltonian.

        Notes
        -----
        len(tlist)-1=coeffs.shape[1] since tlist gives the beginning and the
        end of the pulses
        """
        if setting_args is None:
            setting_args = {}
        if isinstance(qc, QubitCircuit):
            props = qc.propagators()
            gates = [g.name for g in qc.gates]
        elif isinstance(qc, Iterable):
            props = qc
            gates = None  # using list of Qobj, no gates name
        else:
            raise ValueError(
                "qc should be a "
                "QubitCircuit or a list of Qobj")
        if merge_gates:  # merge all gates/Qobj into one Qobj
            props = [gate_sequence_product(props)]
            gates = None

        time_record = []  # a list for all the gates
        coeff_record = []
        last_time = 0.  # used in concatenation of tlist
        for prop_ind, U_targ in enumerate(props):
            U_0 = identity(U_targ.dims[0])

            # If qc is a QubitCircuit and setting_args is not empty,
            # we update the kwargs for each gate.
            # keyword arguments in setting_arg have priority
            if gates is not None and setting_args:
                kwargs.update(setting_args[gates[prop_ind]])

            result = cpo.optimize_pulse_unitary(
                self.drift, self.ctrls, U_0, U_targ, **kwargs)

            if result.fid_err > min_fid_err:
                warnings.warn(
                    "The fidelity error of gate {} is higher "
                    "than required limit. Use verbose=True to see"
                    "the more detailed information.".format(prop_ind))

            time_record.append(result.time[1:] + last_time)
            last_time += result.time[-1]
            coeff_record.append(result.final_amps.T)

            if verbose:
                print("********** Gate {} **********".format(prop_ind))
                print("Final fidelity error {}".format(result.fid_err))
                print("Final gradient normal {}".format(
                                                result.grad_norm_final))
                print("Terminated due to {}".format(result.termination_reason))
                print("Number of iterations {}".format(result.num_iter))
        self.tlist = np.hstack([[0.]] + time_record)
        self.coeffs = np.vstack([np.hstack(coeff_record)])
        return self.tlist, self.coeffs
Beispiel #39
0
    def test_load_params(self):
        """
        Optimise pulse for Hadamard gate by loading config from file
        compare with result produced by pulseoptim method
        """
        H_d = sigmaz()
        H_c = sigmax()
        
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        cfg = optimconfig.OptimConfig()
        cfg.param_fname = "Hadamard_params.ini"
        cfg.param_fpath = os.path.join(os.path.dirname(__file__), 
                                           cfg.param_fname)
        cfg.pulse_type = "ZERO"
        loadparams.load_parameters(cfg.param_fpath, config=cfg)

        dyn = dynamics.DynamicsUnitary(cfg)
        dyn.target = U_targ
        dyn.initial = U_0
        dyn.drift_dyn_gen = H_d
        dyn.ctrl_dyn_gen = [H_c]
        loadparams.load_parameters(cfg.param_fpath, dynamics=dyn)
        dyn.init_timeslots()      
        n_ts = dyn.num_tslots
        n_ctrls = dyn.num_ctrls
        
        pgen = pulsegen.create_pulse_gen(pulse_type=cfg.pulse_type, dyn=dyn)
        loadparams.load_parameters(cfg.param_fpath, pulsegen=pgen)
        
        tc = termcond.TerminationConditions()
        loadparams.load_parameters(cfg.param_fpath, term_conds=tc)
        
        if cfg.optim_method == 'BFGS':
            optim = optimizer.OptimizerBFGS(cfg, dyn)
        elif cfg.optim_method == 'FMIN_L_BFGS_B':
            optim = optimizer.OptimizerLBFGSB(cfg, dyn)
        elif cfg.optim_method is None:
            raise errors.UsageError("Optimisation algorithm must be specified "
                                    "via 'optim_method' parameter")
        else:
            optim = optimizer.Optimizer(cfg, dyn)
            optim.method = cfg.optim_method
        loadparams.load_parameters(cfg.param_fpath, optim=optim)
        
        sts = stats.Stats()
        dyn.stats = sts
        optim.stats = sts
        optim.config = cfg
        optim.dynamics = dyn
        optim.pulse_generator = pgen
        optim.termination_conditions = tc
        
        init_amps = np.zeros([n_ts, n_ctrls])
        for j in range(n_ctrls):
            init_amps[:, j] = pgen.gen_pulse()
        dyn.initialize_controls(init_amps)
        result = optim.run_optimization()
        
        result2 = cpo.optimize_pulse_unitary(H_d, list([H_c]), U_0, U_targ, 
                        6, 6, fid_err_targ=1e-10, 
                        init_pulse_type='LIN', 
                        amp_lbound=-1.0, amp_ubound=1.0,
                        gen_stats=True)
                        
        assert_almost_equal(result.final_amps, result2.final_amps, decimal=5, 
                            err_msg="Pulses do not match")
    def test_dumping_and_unitarity(self):
        """
        control: data dumping and unitarity checking
        Dump out processing data and use to check unitary evolution
        """
        N_EXP_OPTIMDUMP_FILES = 10
        N_EXP_DYNDUMP_FILES = 49
        
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 1000
        evo_time = 4
        
        dump_folder = str(uuid.uuid4())
        qtrl_dump_dir = os.path.expanduser(os.path.join('~', dump_folder))
        self.tmp_dirs.append(qtrl_dump_dir)
        optim_dump_dir = os.path.join(qtrl_dump_dir, 'optim')
        dyn_dump_dir = os.path.join(qtrl_dump_dir, 'dyn')
        result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-9, 
                        init_pulse_type='LIN', 
                        optim_params={'dumping':'FULL', 'dump_to_file':True, 
                                    'dump_dir':optim_dump_dir},
                        dyn_params={'dumping':'FULL', 'dump_to_file':True, 
                                    'dump_dir':dyn_dump_dir},
                        gen_stats=True)
        
        # check dumps were generated
        optim = result.optimizer
        dyn = optim.dynamics
        assert_(optim.dump is not None, msg='optimizer dump not created')
        assert_(dyn.dump is not None, msg='dynamics dump not created')
        
        # Count files that were output
        nfiles = len(os.listdir(optim.dump.dump_dir))
        assert_(nfiles == N_EXP_OPTIMDUMP_FILES, 
                msg="{} optimizer dump files generated, {} expected".format(
                    nfiles, N_EXP_OPTIMDUMP_FILES))
                    
        nfiles = len(os.listdir(dyn.dump.dump_dir))
        assert_(nfiles == N_EXP_DYNDUMP_FILES, 
                msg="{} dynamics dump files generated, {} expected".format(
                    nfiles, N_EXP_DYNDUMP_FILES))
                    
        # dump all to specific file stream
        fpath = os.path.expanduser(os.path.join('~', str(uuid.uuid4())))
        self.tmp_files.append(fpath)
        with open(fpath, 'wb') as f:
            optim.dump.writeout(f)
        
        assert_(os.stat(fpath).st_size > 0, msg="Nothing written to optimizer dump file")
        
        fpath = os.path.expanduser(os.path.join('~', str(uuid.uuid4())))
        self.tmp_files.append(fpath)
        with open(fpath, 'wb') as f:
            dyn.dump.writeout(f)
        assert_(os.stat(fpath).st_size > 0, msg="Nothing written to dynamics dump file")
        
        # Use the dump to check unitarity of all propagators and evo_ops
        dyn.unitarity_tol = 1e-14
        nu_prop = 0
        nu_fwd_evo = 0
        nu_onto_evo = 0
        for d in dyn.dump.evo_dumps:
            for k in range(dyn.num_tslots):
                if not dyn._is_unitary(d.prop[k]): nu_prop += 1
                if not dyn._is_unitary(d.fwd_evo[k]): nu_fwd_evo += 1
                if not dyn._is_unitary(d.onto_evo[k]): nu_onto_evo += 1
        assert_(nu_prop==0, 
                msg="{} propagators found to be non-unitary".format(nu_prop))
        assert_(nu_fwd_evo==0, 
                msg="{} fwd evo ops found to be non-unitary".format(
                                                                nu_fwd_evo))
        assert_(nu_onto_evo==0,
                msg="{} onto evo ops found to be non-unitary".format(
                                                                nu_onto_evo))
# pulse type alternatives: RND|ZERO|LIN|SINE|SQUARE|SAW|TRIANGLE|
p_type = 'LIN'
# *************************************************************
# File extension for output files

f_ext = "{}_n_ts{}_ptype{}.txt".format(example_name, n_ts, p_type)

# Run the optimisation
print("\n***********************************")
print("Starting pulse optimisation")
result = cpo.optimize_pulse_unitary(H_d, H_c, psi_0, psi_T, n_ts, evo_time, 
                fid_err_targ=fid_err_targ,
                max_iter=max_iter, max_wall_time=max_wall_time, 
#                dyn_params={'oper_dtype':Qobj},
                # comment in/out these next three lines for CRAB/GRAPE
#                alg='CRAB',
#                alg_params={'init_coeff_scaling':5.0, 'num_coeffs':5, 'guess_pulse_type':None},
#                method_params={'xtol':1e-3},
                fid_params={'phase_option':'PSU'},
                out_file_ext=f_ext, init_pulse_type=p_type, 
                log_level=log_level, gen_stats=True)


print("\n***********************************")
print("Optimising complete. Stats follow:")
result.stats.report()
print("\nFinal evolution\n{}\n".format(result.evo_full_final))

print("********* Summary *****************")
print("Initial fidelity error {}".format(result.initial_fid_err))
print("Final fidelity error {}".format(result.fid_err))
# Initial pulse type
# pulse type alternatives: RND|ZERO|LIN|SINE|SQUARE|SAW|TRIANGLE|
p_type = 'ZERO'
# *************************************************************
# File extension for output files

f_ext = "{}_n_ts{}_ptype{}.txt".format(example_name, n_ts, p_type)

# Run the optimisation
print("\n***********************************")
print("Starting pulse optimisation")
result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time, 
                fid_err_targ=fid_err_targ, min_grad=min_grad, 
                max_iter=max_iter, max_wall_time=max_wall_time, 
#                dyn_params={'oper_dtype':Qobj},
                #phase_option='SU',
                fid_params={'phase_option':'PSU'},
                out_file_ext=f_ext, init_pulse_type=p_type, 
                log_level=log_level, gen_stats=True)

print("\n***********************************")
print("Optimising complete. Stats follow:")
result.stats.report()
print("\nFinal evolution\n{}\n".format(result.evo_full_final))

print("********* Summary *****************")
print("Initial fidelity error {}".format(result.initial_fid_err))
print("Final fidelity error {}".format(result.fid_err))
print("Final gradient normal {}".format(result.grad_norm_final))
print("Terminated due to {}".format(result.termination_reason))
print("Number of iterations {}".format(result.num_iter))
Beispiel #43
0
# ***************************
f_ext = "{}_n_ts{}_ptype{}.txt".format(example_name, n_ts, p_type)

# Run the optimisation
print("\n***********************************")
print("Starting pulse optimisation")
result = cpo.optimize_pulse_unitary(
    H_d,
    ctrls,
    U_0,
    U_targ,
    n_ts,
    evo_time,
    fid_err_targ=fid_err_targ,
    min_grad=min_grad,
    max_iter=max_iter,
    max_wall_time=max_wall_time,
    #                dyn_params={'oper_dtype':Qobj},
    #phase_option='SU',
    fid_params={'phase_option': 'PSU'},
    out_file_ext=f_ext,
    init_pulse_type=p_type,
    log_level=log_level,
    gen_stats=True)

print("\n***********************************")
print("Optimising complete. Stats follow:")
result.stats.report()
print("\nFinal evolution\n{}\n".format(result.evo_full_final))

print("********* Summary *****************")
Beispiel #44
0
    def run_optimizer(self,
                      unitary,
                      qubit_targets,
                      *args,
                      fid_err_targ=1e-30,
                      max_iter=2000,
                      max_wall_time=120,
                      min_grad=1e-30,
                      alg='GRAPE',
                      zero_wq=True,
                      **kwargs):

        if self.zero_wq:
            for i in qubit_targets:
                self.config.hamiltonian['vars']['wq' + str(i)] = 0
        hamiltonian = convert_qutip_ham(self.config,
                                        qubit_targets,
                                        two_level=self.two_level)
        drift_hamiltonian = hamiltonian['H_d']
        control_hamiltonians = hamiltonian['H_c']

        if self.n_ts:
            n_ts = self.n_ts
        else:
            n_ts = 640
        if self.two_level:
            U_0 = Qobj(identity(2**len(qubit_targets)).full())
        else:
            U_0 = Qobj(identity(3**len(qubit_targets)).full())

        U_targ = unitary
        p_type = self.p_type
        dt = self.dt
        evo_time = dt * n_ts * 1e9
        if self.log_level == 'WARN':
            log_level = logging.WARN
        elif self.log_level == 'INFO':
            log_level = logging.INFO
        else:
            log_level = logging.WARN

        result = optimize_pulse_unitary(
            drift_hamiltonian,
            list(control_hamiltonians.values()),
            U_0,
            U_targ,
            n_ts,
            evo_time,
            fid_err_targ=fid_err_targ,
            min_grad=min_grad,
            max_iter=max_iter,
            max_wall_time=max_wall_time,
            out_file_ext=None,
            init_pulse_type=p_type,
            log_level=log_level,
            gen_stats=True,
            alg=alg,
            amp_lbound=-0.7,
            amp_ubound=0.7,
            phase_option='PSU',
            optim_method='fmin_l_bfgs_b',
            method_params={
                'max_metric_corr': 20,
                'accuracy_factor': 1e8
            },
            # dyn_type='UNIT',
            fid_params={'phase_option': 'PSU'},
            *args,
            **kwargs)
        amp_dictionary = results_amps_to_dict(result.final_amps,
                                              hamiltonian['H_c'].keys())
        return amp_dictionary, hamiltonian['H_c'].keys()