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 count_waves(n_ts, evo_time, ptype, freq=None, num_waves=None):
     
     # Any dyn config will do 
     #Hadamard
     H_d = sigmaz()
     H_c = [sigmax()]
     U_0 = identity(2)
     U_targ = hadamard_transform(1)
     
     pulse_params = {}
     if freq is not None:
         pulse_params['freq'] = freq
     if num_waves is not None:
         pulse_params['num_waves'] = num_waves
     
     optim = cpo.create_pulse_optimizer(H_d, H_c, U_0, U_targ, 
                                 n_ts, evo_time, 
                                 dyn_type='UNIT', 
                                 init_pulse_type=ptype,
                                 init_pulse_params=pulse_params,
                                 gen_stats=False)
     pgen = optim.pulse_generator
     pulse = pgen.gen_pulse()
     
     # count number of waves
     zero_cross = pulse[0:-2]*pulse[1:-1] < 0
     
     return (sum(zero_cross) + 1) / 2
Example #3
0
    def test_crab(self):
        """
        Optimise pulse for Hadamard gate using CRAB algorithm
        Apply guess and ramping pulse
        assert that goal is achieved and fidelity error is below threshold
        assert that starting amplitude is zero
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 12
        evo_time = 10
        
        # Run the optimisation
        result = cpo.opt_pulse_crab_unitary(H_d, H_c, U_0, U_targ, 
                n_ts, evo_time, 
                fid_err_targ=1e-5, 
                alg_params={'crab_pulse_params':{'randomize_coeffs':False, 
                                                 'randomize_freqs':False}},
                init_coeff_scaling=0.5,
                guess_pulse_type='GAUSSIAN', 
                guess_pulse_params={'variance':0.1*evo_time},
                guess_pulse_scaling=1.0, guess_pulse_offset=1.0,
                amp_lbound=None, amp_ubound=None,
                ramping_pulse_type='GAUSSIAN_EDGE', 
                ramping_pulse_params={'decay_time':evo_time/100.0},
                gen_stats=True)
        assert_(result.goal_achieved, msg="Hadamard goal not achieved")
        assert_almost_equal(result.fid_err, 0.0, decimal=3, 
                            err_msg="Hadamard infidelity too high")
        assert_almost_equal(result.final_amps[0, 0], 0.0, decimal=3, 
                            err_msg="lead in amplitude not zero")
Example #4
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))
Example #5
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))
    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")
Example #7
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_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")
Example #9
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")
Example #10
0
        def count_waves(n_ts, evo_time, ptype, freq=None, num_waves=None):

            # Any dyn config will do
            #Hadamard
            H_d = sigmaz()
            H_c = [sigmax()]
            U_0 = identity(2)
            U_targ = hadamard_transform(1)

            pulse_params = {}
            if freq is not None:
                pulse_params['freq'] = freq
            if num_waves is not None:
                pulse_params['num_waves'] = num_waves

            optim = cpo.create_pulse_optimizer(H_d,
                                               H_c,
                                               U_0,
                                               U_targ,
                                               n_ts,
                                               evo_time,
                                               dyn_type='UNIT',
                                               init_pulse_type=ptype,
                                               init_pulse_params=pulse_params,
                                               gen_stats=False)
            pgen = optim.pulse_generator
            pulse = pgen.gen_pulse()

            # count number of waves
            zero_cross = pulse[0:-2] * pulse[1:-1] < 0

            return (sum(zero_cross) + 1) / 2
    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_01_6_unitary_hadamard_grad(self):
        """
        control.pulseoptim: Hadamard gate gradient check
        assert that gradient approx and exact gradient match in tolerance
        """
        # Hadamard
        H_d = sigmaz()
        H_c = [sigmax()]
        U_0 = identity(2)
        U_targ = hadamard_transform(1)

        n_ts = 10
        evo_time = 10

        # Create the optim objects
        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=6,
                            err_msg="Unitary gradient outside tolerance")
    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))
Example #14
0
def initialize_parameters():
    '''
    Initialize all relevant parameters required to run control pulse optimizer
    '''
    # Defining components for initial and target states
    Drift_Hamiltonian = sigmaz()
    Control_hamiltonian = [sigmax()]
    Initial_unitary = identity(2)
    Target_unitary = hadamard_transform(1)

    # Define time evolution parameters
    num_timesteps = 10
    evolution_time = 10

    # Pulse optimization termination conditions
    fidelity_error_required = 1e-10
    max_iter = 200
    max_wall_time = 120

    # Minimum gradient. As this tends to 0 -> local minima has been found
    minimum_gradient = 1e-20

    # pulse type alternatives: RND|ZERO|LIN|SINE|SQUARE|SAW|TRIANGLE|
    p_type = 'SINE'

    return Drift_Hamiltonian, Control_hamiltonian, Initial_unitary, Target_unitary, \
        num_timesteps, evolution_time, fidelity_error_required, max_iter, max_wall_time, minimum_gradient, p_type
Example #15
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")
Example #16
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 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 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))
Example #20
0
    def test_lindbladian(self):
        """
        Optimise pulse for amplitude damping channel with Lindbladian dyn
        assert that fidelity error is below threshold
        """

        Sx = sigmax()
        Sz = sigmaz()
        Si = identity(2)
        
        Sd = Qobj(np.array([[0, 1], [0, 0]]))
        Sm = Qobj(np.array([[0, 0], [1, 0]]))
        Sd_m = Qobj(np.array([[1, 0], [0, 0]]))
        
        gamma = 0.1
        L0_Ad = gamma*(2*tensor(Sm, Sd.trans()) - 
                    (tensor(Sd_m, Si) + tensor(Si, Sd_m.trans())))
        LC_x = -1j*(tensor(Sx, Si) - tensor(Si, Sx))
        LC_z = -1j*(tensor(Sz, Si) - tensor(Si, Sz))
        
        drift = L0_Ad
        ctrls = [LC_z, LC_x]
        n_ctrls = len(ctrls)
        initial = tensor(Si, Si)
        had_gate = hadamard_transform(1)
        target_DP = tensor(had_gate, had_gate)

        n_ts = 10
        evo_time = 5
        
        result = cpo.optimize_pulse(drift, ctrls, initial, target_DP, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-3, 
                        max_iter=200,
                        init_pulse_type='LIN', 
                        gen_stats=True)
        assert_(result.fid_err < 0.1, 
                msg="Fidelity higher than expected")
                
        # Repeat with Qobj propagation
        result = cpo.optimize_pulse(drift, ctrls, initial, target_DP, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-3, 
                        max_iter=200,
                        init_pulse_type='LIN', 
                        dyn_params={'oper_dtype':Qobj},
                        gen_stats=True)
        assert_(result.fid_err < 0.1, 
                msg="Fidelity higher than expected (Qobj propagation)")
                
        # Check same result is achieved using the create objects method
        optim = cpo.create_pulse_optimizer(drift, ctrls, 
                        initial, target_DP,
                        n_ts, evo_time, 
                        fid_err_targ=1e-3, 
                        init_pulse_type='LIN', 
                        gen_stats=True)
        dyn = optim.dynamics

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

        # Check the exact gradient
        func = optim.fid_err_func_wrapper
        grad = optim.fid_err_grad_wrapper
        x0 = dyn.ctrl_amps.flatten()
        grad_diff = check_grad(func, grad, x0)
        assert_almost_equal(grad_diff, 0.0, decimal=7,
                            err_msg="Frechet gradient outside tolerance")

        result2 = optim.run_optimization()
        assert_almost_equal(result.fid_err, result2.fid_err, decimal=3, 
                            err_msg="Direct and indirect methods produce "
                                    "different results for ADC")
Example #21
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_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 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")
Example #24
0
    def test_06_lindbladian(self):
        """
        control.pulseoptim: amplitude damping channel
        Lindbladian dynamics
        assert that fidelity error is below threshold
        """

        Sx = sigmax()
        Sz = sigmaz()
        Si = identity(2)

        Sd = Qobj(np.array([[0, 1], [0, 0]]))
        Sm = Qobj(np.array([[0, 0], [1, 0]]))
        Sd_m = Qobj(np.array([[1, 0], [0, 0]]))

        gamma = 0.1
        L0_Ad = gamma * (2 * tensor(Sm, Sd.trans()) -
                         (tensor(Sd_m, Si) + tensor(Si, Sd_m.trans())))
        LC_x = -1j * (tensor(Sx, Si) - tensor(Si, Sx))
        LC_z = -1j * (tensor(Sz, Si) - tensor(Si, Sz))

        drift = L0_Ad
        ctrls = [LC_z, LC_x]
        n_ctrls = len(ctrls)
        initial = tensor(Si, Si)
        had_gate = hadamard_transform(1)
        target_DP = tensor(had_gate, had_gate)

        n_ts = 10
        evo_time = 5

        result = cpo.optimize_pulse(drift,
                                    ctrls,
                                    initial,
                                    target_DP,
                                    n_ts,
                                    evo_time,
                                    fid_err_targ=1e-3,
                                    max_iter=200,
                                    init_pulse_type='LIN',
                                    gen_stats=True)
        assert_(result.fid_err < 0.1, msg="Fidelity higher than expected")

        # Repeat with Qobj propagation
        result = cpo.optimize_pulse(drift,
                                    ctrls,
                                    initial,
                                    target_DP,
                                    n_ts,
                                    evo_time,
                                    fid_err_targ=1e-3,
                                    max_iter=200,
                                    init_pulse_type='LIN',
                                    dyn_params={'oper_dtype': Qobj},
                                    gen_stats=True)
        assert_(result.fid_err < 0.1,
                msg="Fidelity higher than expected (Qobj propagation)")

        # Check same result is achieved using the create objects method
        optim = cpo.create_pulse_optimizer(drift,
                                           ctrls,
                                           initial,
                                           target_DP,
                                           n_ts,
                                           evo_time,
                                           fid_err_targ=1e-3,
                                           init_pulse_type='LIN',
                                           gen_stats=True)
        dyn = optim.dynamics

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

        # Check the exact gradient
        func = optim.fid_err_func_wrapper
        grad = optim.fid_err_grad_wrapper
        x0 = dyn.ctrl_amps.flatten()
        grad_diff = check_grad(func, grad, x0)
        assert_almost_equal(grad_diff,
                            0.0,
                            decimal=7,
                            err_msg="Frechet gradient outside tolerance")

        result2 = optim.run_optimization()
        assert_almost_equal(result.fid_err,
                            result2.fid_err,
                            decimal=3,
                            err_msg="Direct and indirect methods produce "
                            "different results for ADC")
Example #25
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")
Example #26
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()
Example #27
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))
#sigma Y control
LC_y = -1j*(tensor(Sy, Si) - tensor(Si, Sy.trans()))
#sigma Z control
LC_z = -1j*(tensor(Sz, Si) - tensor(Si, Sz))

#Drift
drift = L0_Ad
#Controls
ctrls = [LC_z, LC_x]
# Number of ctrls
n_ctrls = len(ctrls)

initial = identity(4)
#Target
#Hadamard gate
had_gate = hadamard_transform(1)
target_DP = tensor(had_gate, had_gate)

# ***** Define time evolution parameters *****
# Number of time slots
n_ts = 10
# Time allowed for the evolution
evo_time = 5

# ***** Define the termination conditions *****
# Fidelity error target
fid_err_targ = 1e-3
# Maximum iterations for the optisation algorithm
max_iter = 500
# Maximum (elapsed) time allowed in seconds
max_wall_time = 30
Example #29
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")
nSpins = 1
#Sx = np.array([[0, 1], [1, 0]], dtype=complex)
#Sy = np.array([[0, -1j], [1j, 0]], dtype=complex)
#Sz = np.array([[1, 0], [0, -1]], dtype=complex)
#Si = mat.eye(2)/2

H_d = sigmaz()
H_c = [sigmax()]
# Number of ctrls
n_ctrls = len(H_c)

U_0 = identity(2**nSpins)
# Hadamard gate
#U_targ = Qobj(np.array([[1,1],[1,-1]], dtype=complex)/np.sqrt(2))
U_targ = hadamard_transform(nSpins)
# ***** Define time evolution parameters *****
# Number of time slots
n_ts = 12
# Time allowed for the evolution
evo_time = 10

# ***** Define the termination conditions *****
# Fidelity error target
fid_err_targ = 1e-5
# Maximum iterations for the optisation algorithm
max_iter = 500
# Maximum (elapsed) time allowed in seconds
max_wall_time = 60
p_type = 'DEF'
    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))
Example #32
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))
# ****************************************************************
# Define the physics of the problem

nSpins = 1

H_d = sigmaz()
H_c = [sigmax()]
# Number of ctrls
n_ctrls = len(H_c)

U_0 = identity(2**nSpins)
# Hadamard gate
#U_targ = Qobj(np.array([[1,1],[1,-1]], dtype=complex)/np.sqrt(2))
# Hadamard is determinant -1, so need prefactor phase for SU fidelity
U_targ = 1.0j*hadamard_transform(nSpins)
# ***** Define time evolution parameters *****
# Number of time slots
n_ts = 100
# Time allowed for the evolution
evo_time = 6

# ***** Define the termination conditions *****
# Fidelity error target
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
Example #34
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")
Example #35
0
log_level = logging.INFO

# ****************************************************************
# Define the physics of the problem

nSpins = 1

H_0 = sigmaz()
H_c = [sigmax()]
# Number of ctrls
n_ctrls = len(H_c)

U_0 = identity(2**nSpins)
# Hadamard gate
#U_targ = Qobj(np.array([[1,1],[1,-1]], dtype=complex)/np.sqrt(2))
U_targ = hadamard_transform(nSpins)
# ***** Define time evolution parameters *****
# Number of time slots
n_ts = 24
# Time allowed for the evolution
evo_time = 6

# ***** Define the termination conditions *****
# Fidelity error target
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
#sigma Y control
LC_y = -1j * (tensor(Sy, Si) - tensor(Si, Sy.trans()))
#sigma Z control
LC_z = -1j * (tensor(Sz, Si) - tensor(Si, Sz))

#Drift
drift = L0_Ad
#Controls
ctrls = [LC_z, LC_x]
# Number of ctrls
n_ctrls = len(ctrls)

initial = identity(4)
#Target
#Hadamard gate
had_gate = hadamard_transform(1)
target_DP = tensor(had_gate, had_gate)

# ***** Define time evolution parameters *****
# Number of time slots
n_ts = 20
# Time allowed for the evolution
evo_time = 2

# ***** Define the termination conditions *****
# Fidelity error target
fid_err_targ = 1e-3
# Maximum iterations for the optisation algorithm
max_iter = 200
# Maximum (elapsed) time allowed in seconds
max_wall_time = 30