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")
Example #2
0
def _count_waves(system):
    optimizer = cpo.create_pulse_optimizer(system.system, system.controls,
                                           system.initial, system.target,
                                           **system.kwargs)
    pulse = optimizer.pulse_generator.gen_pulse()
    zero_crossings = pulse[0:-2] * pulse[1:-1] < 0
    return (sum(zero_crossings) + 1) // 2
Example #3
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 run_optimization(self):
        CPO = cpo.create_pulse_optimizer(2 * pi * self.Hdrift,
                                         [2 * pi * self.Hdrive1],
                                         self.Uinit,
                                         self.U_goal,
                                         self.n_tslot,
                                         self.pulse_time,
                                         amp_lbound=self.power_min,
                                         amp_ubound=self.power_max,
                                         fid_err_targ=self.fid_err_targ,
                                         min_grad=1e-10,
                                         alg="GRAPE",
                                         max_iter=500,
                                         max_wall_time=180,
                                         method_params=None,
                                         optim_method='fmin_l_bfgs_b',
                                         dyn_type='UNIT',
                                         dyn_params=None,
                                         prop_type='DEF',
                                         fid_type='DEF',
                                         fid_params={'phase_option': 'PSU'},
                                         init_pulse_type="RNDFOURIER",
                                         pulse_scaling=1.0,
                                         pulse_offset=0.0,
                                         ramping_pulse_type=None,
                                         ramping_pulse_params=None,
                                         log_level=30,
                                         gen_stats=False)

        CPO.dynamics.initialize_controls(self.pulse_shape)
        return CPO.run_optimization()
 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 #6
0
 def create_pulse_optimizer(self, fid_err_targ=1e-30, max_iter=2000, max_wall_time=120, min_grad=1e-30, log_level=logging.INFO):
     optim = cpo.create_pulse_optimizer(self.H_d, self.H_c, self.U_0, self.U_targ, self.n_ts, self.evo_time,
                                        amp_lbound=-.7, amp_ubound=.7,
                                        fid_err_targ=fid_err_targ, min_grad=min_grad,
                                        max_iter=max_iter, max_wall_time=max_wall_time,
                                        optim_method='fmin_l_bfgs_b',
                                        method_params={'max_metric_corr': 20,
                                                       'accuracy_factor': 1e8},
                                        dyn_type='UNIT',
                                        fid_params={'phase_option': 'PSU'},
                                        init_pulse_type=self.p_type,
                                        log_level=log_level, gen_stats=True, alg='GRAPE')
     return optim
Example #7
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 #8
0
    def calc_fid_err(self, params):
        D0, Q, AN, C_known, Bz, theta = params
        number_C_known = len(C_known)
        if number_C_known != 0:
            II_C_known = Qobj(qeye(2**number_C_known),
                              dims=[
                                  list(2 * ones(number_C_known)),
                                  list(2 * ones(number_C_known))
                              ])
            H0 = defH0(D0, Q, AN, C_known, Bz)
            Hdetuning = tensor(Szz, III, II_C_known)
            Hdrift = H0 - self.frequency_grape * Hdetuning
            Uinit = tensor(III, III, II_C_known)
            Hdrive1 = tensor(Hxdrive(1, 0, self.phi1, 0, self.theta), III,
                             II_C_known)
            Hdrive2 = tensor(Hxdrive(0, 1, 0, self.phi2, self.theta), III,
                             II_C_known)

        else:
            H0 = defH0(D0, Q, AN, C_known, Bz)
            Hdetuning = tensor(Szz, III)
            Hdrift = H0 - self.frequency_grape * Hdetuning
            Uinit = tensor(III, III)
            Hdrive1 = tensor(Hxdrive(1, 0, self.phi1, 0, self.theta), III)
            Hdrive2 = tensor(Hxdrive(0, 1, 0, self.phi2, self.theta), III)

        CPO = cpo.create_pulse_optimizer(2 * pi * Hdrift,
                                         [2 * pi * Hdrive1, 2 * pi * Hdrive2],
                                         Uinit,
                                         self.U_ideal,
                                         self.n_tslot,
                                         self.pulse_time,
                                         dyn_type='UNIT',
                                         dyn_params=None,
                                         prop_type='DEF',
                                         fid_type='DEF',
                                         fid_params={'phase_option': 'PSU'},
                                         pulse_scaling=1.0,
                                         pulse_offset=0.0,
                                         log_level=30,
                                         gen_stats=False)
        CPO.dynamics.initialize_controls(self.pulse_shape)
        #result = CPO._create_result()
        #CPO._add_common_result_attribs(result,0,1)
        fid_err = CPO.dynamics.fid_computer.get_fid_err()
        self.Uarb = CPO.dynamics.fwd_evo
        self.Uarb_last = CPO.dynamics.full_evo
        return CPO.dynamics.fid_computer.get_fid_err()
Example #9
0
 def calc_fid_err(self):
     CPO = cpo.create_pulse_optimizer(2*pi*self.Hdrift,[2*pi*self.Hdrive1,2*pi*self.Hdrive2],self.Uinit,self.U_ideal,self.n_tslot,self.pulse_time,
                                dyn_type='UNIT',
                                dyn_params=None,
                                prop_type='DEF',
                                fid_type='DEF',
                                fid_params={'phase_option': 'PSU'},
                                pulse_scaling=1.0,
                                pulse_offset = 0.0,
                                log_level = 30,
                                gen_stats=False)
     CPO.dynamics.initialize_controls(self.pulse_shape)
     fid_err = CPO.dynamics.fid_computer.get_fid_err()
     self.Uarb = CPO.dynamics.fwd_evo
     self.Uarb_last = CPO.dynamics.full_evo
     return 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_object_oriented_approach_and_gradient(self, system, propagation):
     """
     Test the object-oriented version of the optimiser, and ensure that the
     system truly appears to be at an extremum.
     """
     system = _merge_kwargs(system, propagation)
     base = _optimize_pulse(system)
     optimizer = cpo.create_pulse_optimizer(system.system, system.controls,
                                            system.initial, system.target,
                                            **system.kwargs)
     init_amps = np.array([optimizer.pulse_generator.gen_pulse()
                           for _ in system.controls]).T
     optimizer.dynamics.initialize_controls(init_amps)
     # Check the gradient numerically.
     func = optimizer.fid_err_func_wrapper
     grad = optimizer.fid_err_grad_wrapper
     loc = optimizer.dynamics.ctrl_amps.flatten()
     assert abs(scipy.optimize.check_grad(func, grad, loc)) < 1e-5,\
         "Gradient outside tolerance."
     result = optimizer.run_optimization()
     tol = system.kwargs['fid_err_targ']
     assert abs(result.fid_err-base.fid_err) < tol,\
         "Direct and indirect methods produce different results."
# This means that matrices that describe the dynamics are assumed to be
# general, i.e. the propagator can be calculated using:
# expm(combined_dynamics*dt)
#    prop_type='FRECHET'
# and the propagators and their gradients will be calculated using the
# Frechet method, i.e. an exact gradent
#    fid_type='TRACEDIFF'
# and that the fidelity error, i.e. distance from the target, is give
# by the trace of the difference between the target and evolved operators
optim = cpo.create_pulse_optimizer(drift,
                                   ctrls,
                                   initial,
                                   target_DP,
                                   n_ts,
                                   evo_time,
                                   fid_err_targ=fid_err_targ,
                                   min_grad=min_grad,
                                   max_iter=max_iter,
                                   max_wall_time=max_wall_time,
                                   init_pulse_type=p_type,
                                   log_level=log_level,
                                   gen_stats=True)

dyn = optim.dynamics
pgen = optim.pulse_generator
# **** CUSTOMISE this is where the custom fidelity is specified *****
dyn.fid_computer = FidCompCustom(dyn)

p_gen = optim.pulse_generator
init_amps = np.zeros([n_ts, n_ctrls])
for j in range(n_ctrls):
Example #13
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 #14
0
    def test_symplectic(self):
        """
        Optimise pulse for coupled oscillators with Symplectic dynamics
        assert that fidelity error is below threshold
        """
        g1 = 1.0
        g2 = 0.2
        A0 = Qobj(np.array([[1, 0, g1, 0], 
                           [0, 1, 0, g2], 
                           [g1, 0, 1, 0], 
                           [0, g2, 0, 1]]))
        A_rot = Qobj(np.array([
                            [1, 0, 0, 0],
                            [0, 1, 0, 0],
                            [0, 0, 0, 0],
                            [0, 0, 0, 0]
                            ]))
        
        A_sqz = Qobj(0.4*np.array([
                            [1, 0, 0, 0],
                            [0, -1, 0, 0],
                            [0, 0, 0, 0],
                            [0, 0, 0, 0]
                            ]))
                            
        A_c = [A_rot, A_sqz]
        n_ctrls = len(A_c)
        initial = identity(4)
        A_targ = Qobj(np.array([
                        [0, 0, 1, 0], 
                        [0, 0, 0, 1], 
                        [1, 0, 0, 0], 
                        [0, 1, 0, 0]
                        ]))
        Omg = Qobj(sympl.calc_omega(2))
        S_targ = (-A_targ*Omg*np.pi/2.0).expm()
    
        n_ts = 20
        evo_time = 10
        
        result = cpo.optimize_pulse(A0, A_c, initial, S_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-3, 
                        max_iter=200,
                        dyn_type='SYMPL',
                        init_pulse_type='ZERO', 
                        gen_stats=True)
        assert_(result.goal_achieved, msg="Symplectic goal not achieved")
        assert_almost_equal(result.fid_err, 0.0, decimal=2, 
                            err_msg="Symplectic infidelity too high")
        
        # Repeat with Qobj integration
        resultq = cpo.optimize_pulse(A0, A_c, initial, S_targ, 
                        n_ts, evo_time, 
                        fid_err_targ=1e-3, 
                        max_iter=200,
                        dyn_type='SYMPL',
                        init_pulse_type='ZERO', 
                        dyn_params={'oper_dtype':Qobj},
                        gen_stats=True)
        assert_(result.goal_achieved, msg="Symplectic goal not achieved "
                                        "(Qobj integration)")
        
        # Check same result is achieved using the create objects method
        optim = cpo.create_pulse_optimizer(A0, list(A_c), 
                        initial, S_targ,
                        n_ts, evo_time, 
                        fid_err_targ=1e-3, 
                        dyn_type='SYMPL',
                        init_pulse_type='ZERO', 
                        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=5,
                            err_msg="Frechet gradient outside tolerance "
                                    "(SYMPL)")

        result2 = optim.run_optimization()
        assert_almost_equal(result.fid_err, result2.fid_err, decimal=6, 
                            err_msg="Direct and indirect methods produce "
                                    "different results for Symplectic")
Example #15
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")
# File extension for output files

print("\n***********************************")
print("Creating optimiser objects")
optim = cpo.create_pulse_optimizer(
    H_d,
    H_c,
    U_0,
    U_targ,
    n_ts,
    evo_time,
    amp_lbound=-5.0,
    amp_ubound=5.0,
    fid_err_targ=fid_err_targ,
    min_grad=min_grad,
    max_iter=max_iter,
    max_wall_time=max_wall_time,
    optim_alg="LBFGSB",
    max_metric_corr=20,
    accuracy_factor=1e-2,
    dyn_type="UNIT",
    prop_type="DIAG",
    fid_type="UNIT",
    phase_option="PSU",
    init_pulse_type=p_type,
    log_level=log_level,
    gen_stats=True,
)

print("\n***********************************")
print("Configuring optimiser objects")
Example #17
0
# Fidelity error target
fid_err_targ = 1e-3
# Maximum iterations for the optisation algorithm
max_iter = 20000
# Maximum (elapsed) time allowed in seconds
max_wall_time = 300


##Set to None to suppress output files
f_ext = None#"{}_n_ts{}.txt".format(example_name, n_ts)

##Create the optimiser objects
optim = cpo.create_pulse_optimizer(H_d, H_c, U_0, U_targ, n_ts, evo_time, 
                fid_err_targ=fid_err_targ, 
                max_iter=max_iter, max_wall_time=max_wall_time,
                alg='CRAB', 
                dyn_type='UNIT', 
                prop_type='DIAG', 
                fid_type='UNIT', fid_params={'phase_option':'PSU'}, 
                log_level=log_level, gen_stats=True)
                

##Configure the pulses for each of the controls
dyn = optim.dynamics
# Control 1
crab_pgen = optim.pulse_generator[0]
# Start from a ramped pulse
guess_pgen = pulsegen.create_pulse_gen('LIN', dyn=dyn, 
                                           pulse_params={'scaling':3.0})
crab_pgen.guess_pulse = guess_pgen.gen_pulse()
crab_pgen.scaling = 0.0
# Add some higher frequency components
Example #18
0
    def test_07_symplectic(self):
        """
        control.pulseoptim: coupled oscillators (symplectic dynamics)
        assert that fidelity error is below threshold
        """
        g1 = 1.0
        g2 = 0.2
        A0 = Qobj(
            np.array([[1, 0, g1, 0], [0, 1, 0, g2], [g1, 0, 1, 0],
                      [0, g2, 0, 1]]))
        A_rot = Qobj(
            np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]))

        A_sqz = Qobj(0.4 * np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 0, 0],
                                     [0, 0, 0, 0]]))

        A_c = [A_rot, A_sqz]
        n_ctrls = len(A_c)
        initial = identity(4)
        A_targ = Qobj(
            np.array([[0, 0, 1, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0, 0]]))
        Omg = Qobj(sympl.calc_omega(2))
        S_targ = (-A_targ * Omg * np.pi / 2.0).expm()

        n_ts = 20
        evo_time = 10

        result = cpo.optimize_pulse(A0,
                                    A_c,
                                    initial,
                                    S_targ,
                                    n_ts,
                                    evo_time,
                                    fid_err_targ=1e-3,
                                    max_iter=200,
                                    dyn_type='SYMPL',
                                    init_pulse_type='ZERO',
                                    gen_stats=True)
        assert_(result.goal_achieved,
                msg="Symplectic goal not achieved. "
                "Terminated due to: {}, with infidelity: {}".format(
                    result.termination_reason, result.fid_err))
        assert_almost_equal(result.fid_err,
                            0.0,
                            decimal=2,
                            err_msg="Symplectic infidelity too high")

        # Repeat with Qobj integration
        resultq = cpo.optimize_pulse(A0,
                                     A_c,
                                     initial,
                                     S_targ,
                                     n_ts,
                                     evo_time,
                                     fid_err_targ=1e-3,
                                     max_iter=200,
                                     dyn_type='SYMPL',
                                     init_pulse_type='ZERO',
                                     dyn_params={'oper_dtype': Qobj},
                                     gen_stats=True)
        assert_(resultq.goal_achieved,
                msg="Symplectic goal not achieved "
                "(Qobj integration). "
                "Terminated due to: {}, with infidelity: {}".format(
                    resultq.termination_reason, result.fid_err))

        # Check same result is achieved using the create objects method
        optim = cpo.create_pulse_optimizer(A0,
                                           list(A_c),
                                           initial,
                                           S_targ,
                                           n_ts,
                                           evo_time,
                                           fid_err_targ=1e-3,
                                           dyn_type='SYMPL',
                                           init_pulse_type='ZERO',
                                           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=5,
                            err_msg="Frechet gradient outside tolerance "
                            "(SYMPL)")

        result2 = optim.run_optimization()
        assert_almost_equal(result.fid_err,
                            result2.fid_err,
                            decimal=6,
                            err_msg="Direct and indirect methods produce "
                            "different results for Symplectic")
Example #19
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 #20
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")
max_iter = 500  # Maximum iterations for the optisation algorithm
max_wall_time = 120  # Maximum (elapsed) time allowed in seconds
min_grad = 1e-20  # Minimum gradient (sum of gradients squared)
p_type = 'LIN'  # pulse type alternatives: RND|ZERO|LIN|SINE|SQUARE|SAW|TRIANGLE|

optim = cpo.create_pulse_optimizer(H_d,
                                   H_c,
                                   U_0,
                                   U_targ,
                                   n_ts,
                                   evo_time,
                                   amp_lbound=-5.0,
                                   amp_ubound=5.0,
                                   fid_err_targ=fid_err_targ,
                                   min_grad=min_grad,
                                   max_iter=max_iter,
                                   max_wall_time=max_wall_time,
                                   optim_method='fmin_l_bfgs_b',
                                   method_params={
                                       'max_metric_corr': 20,
                                       'accuracy_factor': 1e8
                                   },
                                   dyn_type='UNIT',
                                   fid_params={'phase_option': 'PSU'},
                                   init_pulse_type=p_type,
                                   log_level=log_level,
                                   gen_stats=True)

# **** get handles to the other objects ****
optim.test_out_files = 0
dyn = optim.dynamics
dyn.test_out_files = 0
# 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)

print("\n***********************************")
print("Creating optimiser objects")
optim = cpo.create_pulse_optimizer(H_d, list(H_c), U_0, U_targ, n_ts, evo_time, 
                amp_lbound=-10.0, amp_ubound=10.0, 
                fid_err_targ=fid_err_targ, min_grad=min_grad, 
                max_iter=max_iter, max_wall_time=max_wall_time, 
#                optim_method='LBFGSB', 
                method_params={'max_metric_corr':40, 'accuracy_factor':1e7,
                                'ftol':1e-7},
                optim_method='fmin_l_bfgs_b',
#                optim_method='l-bfgs-b',
                dyn_type='UNIT', 
                prop_type='DIAG', 
                fid_type='UNIT', fid_params={'phase_option':'SU'}, 
                init_pulse_type=p_type, pulse_scaling=1.0,
                log_level=log_level, gen_stats=True)

print("\n***********************************")
print("Configuring optimiser objects")
# **** Set some optimiser config parameters ****
optim.test_out_files = 0
dyn = optim.dynamics

print("Phase option: {}".format(dyn.fid_computer.phase_option))
print("\n***********************************")
print("Starting pulse optimisation")
# Note that this call will take the defaults
#    dyn_type='GEN_MAT'
# This means that matrices that describe the dynamics are assumed to be
# general, i.e. the propagator can be calculated using:
# expm(combined_dynamics*dt)
#    prop_type='FRECHET'
# and the propagators and their gradients will be calculated using the
# Frechet method, i.e. an exact gradent
#    fid_type='TRACEDIFF'
# and that the fidelity error, i.e. distance from the target, is give
# by the trace of the difference between the target and evolved operators 
optim = cpo.create_pulse_optimizer(drift, ctrls, initial, target_DP, 
                n_ts, evo_time, 
                fid_err_targ=fid_err_targ, min_grad=min_grad, 
                max_iter=max_iter, max_wall_time=max_wall_time, 
                init_pulse_type=p_type, 
                log_level=log_level, 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)

# Save initial amplitudes to a text file
pulsefile = "ctrl_amps_initial_" + f_ext
dyn.save_amps(pulsefile)
if (log_level <= logging.INFO):
optim = cpo.create_pulse_optimizer(
    H_d,
    list(H_c),
    U_0,
    U_targ,
    n_ts,
    evo_time,
    amp_lbound=-10.0,
    amp_ubound=10.0,
    fid_err_targ=fid_err_targ,
    min_grad=min_grad,
    max_iter=max_iter,
    max_wall_time=max_wall_time,
    #                optim_method='LBFGSB',
    method_params={
        'max_metric_corr': 10,
        'accuracy_factor': 1e-3,
        'ftol': 1e-15
    },
    optim_method='fmin_l_bfgs_b',
    optim_params={
        'dumping': 'FULL',
        'dump_to_file': False
    },
    #                optim_method='l-bfgs-b',
    dyn_type='UNIT',
    dyn_params={
        'dumping': 'SUMMARY',
        'dump_to_file': True,
        'dump_dir': "~/QFT-dyndump"
    },
    #                dyn_params={'oper_dtype':Qobj},
    #                prop_type='APPROX',
    #                fid_type='TDAPPROX',
    fid_params={'phase_option': 'PSU'},
    init_pulse_type=p_type,
    pulse_scaling=1.0,
    log_level=log_level,
    gen_stats=True)
Example #25
0
print("\n***********************************")
print("Creating optimiser objects")
optim = cpo.create_pulse_optimizer(
    H_d,
    list(H_c),
    U_0,
    U_targ,
    n_ts,
    evo_time,
    #                amp_lbound=-10.0, amp_ubound=10.0,
    fid_err_targ=fid_err_targ,
    min_grad=min_grad,
    max_iter=max_iter,
    max_wall_time=max_wall_time,
    #                optim_method='LBFGSB',
    #                method_params={'max_metric_corr':40, 'accuracy_factor':1e7,
    #                                'ftol':1e-7},
    #                optim_method='fmin_l_bfgs_b',
    #                optim_method='l-bfgs-b',
    dyn_type='UNIT',
    #                prop_type='DIAG',
    fid_type='UNIT',
    #                fid_params={'phase_option':'SU'},
    init_pulse_type=p_type,
    pulse_scaling=1.0,
    log_level=log_level,
    gen_stats=True)

print("\n***********************************")
print("Configuring optimiser objects")
# File extension for output files

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

print("\n***********************************")
print("Creating optimiser objects")
optim = cpo.create_pulse_optimizer(H_d, list(H_c), U_0, U_targ, n_ts, evo_time,
                amp_lbound=-10.0, amp_ubound=10.0,
                fid_err_targ=fid_err_targ, min_grad=min_grad,
                max_iter=max_iter, max_wall_time=max_wall_time,
#                optim_method='LBFGSB',
                method_params={'max_metric_corr':10, 'accuracy_factor':1e-3,
                                'ftol':1e-15},
                optim_method='fmin_l_bfgs_b',
                optim_params={'dumping':'FULL', 'dump_to_file':False},
#                optim_method='l-bfgs-b',
                dyn_type='UNIT',
                dyn_params={'dumping':'SUMMARY', 'dump_to_file':True,
                            'dump_dir':"~/QFT-dyndump"},
#                dyn_params={'oper_dtype':Qobj},
#                prop_type='APPROX',
#                fid_type='TDAPPROX',
                fid_params={'phase_option':'PSU'},
                init_pulse_type=p_type, pulse_scaling=1.0,
                log_level=log_level, gen_stats=True)

print("\n***********************************")
print("Configuring optimiser objects")
# **** Set some optimiser config parameters ****
optim.test_out_files = 0
dyn = optim.dynamics
def my_opt(drift,
           ctrls,
           initial,
           target,
           num_tslots=None,
           evo_time=None,
           tau=None,
           amp_lbound=None,
           amp_ubound=None,
           fid_err_targ=1e-10,
           min_grad=1e-10,
           max_iter=500,
           max_wall_time=180,
           alg='GRAPE',
           alg_params=None,
           optim_params=None,
           optim_method='DEF',
           method_params=None,
           optim_alg=None,
           max_metric_corr=None,
           accuracy_factor=None,
           dyn_type='GEN_MAT',
           dyn_params=None,
           prop_type='DEF',
           prop_params=None,
           fid_type='DEF',
           fid_params=None,
           phase_option=None,
           fid_err_scale_factor=None,
           tslot_type='DEF',
           tslot_params=None,
           amp_update_mode=None,
           init_pulse_type='DEF',
           init_pulse_params=None,
           pulse_scaling=1.0,
           pulse_offset=0.0,
           ramping_pulse_type=None,
           ramping_pulse_params=None,
           log_level=logging.NOTSET,
           out_file_ext=None,
           gen_stats=False,
           init_pulse=None):

    optim = cpo.create_pulse_optimizer(
        drift,
        ctrls,
        initial,
        target,
        num_tslots=num_tslots,
        evo_time=evo_time,
        tau=tau,
        amp_lbound=amp_lbound,
        amp_ubound=amp_ubound,
        fid_err_targ=fid_err_targ,
        min_grad=min_grad,
        max_iter=max_iter,
        max_wall_time=max_wall_time,
        alg=alg,
        alg_params=alg_params,
        optim_params=optim_params,
        optim_method=optim_method,
        method_params=method_params,
        dyn_type=dyn_type,
        dyn_params=dyn_params,
        prop_type=prop_type,
        prop_params=prop_params,
        fid_type=fid_type,
        fid_params=fid_params,
        init_pulse_type=init_pulse_type,
        init_pulse_params=init_pulse_params,
        pulse_scaling=pulse_scaling,
        pulse_offset=pulse_offset,
        ramping_pulse_type=ramping_pulse_type,
        ramping_pulse_params=ramping_pulse_params,
        log_level=log_level,
        gen_stats=gen_stats)

    dyn = optim.dynamics

    dyn.init_timeslots()
    # Generate initial pulses for each control
    init_amps = np.zeros([dyn.num_tslots, dyn.num_ctrls])

    pgen = optim.pulse_generator
    for j in range(dyn.num_ctrls):
        init_amps[:, j] = init_pulse[:, j]

    # Initialise the starting amplitudes
    dyn.initialize_controls(init_amps)

    if log_level <= logging.INFO:
        msg = "System configuration:\n"
        dg_name = "dynamics generator"
        if dyn_type == 'UNIT':
            dg_name = "Hamiltonian"
        if dyn.time_depend_drift:
            msg += "Initial drift {}:\n".format(dg_name)
            msg += str(dyn.drift_dyn_gen[0])
        else:
            msg += "Drift {}:\n".format(dg_name)
            msg += str(dyn.drift_dyn_gen)
        for j in range(dyn.num_ctrls):
            msg += "\nControl {} {}:\n".format(j + 1, dg_name)
            msg += str(dyn.ctrl_dyn_gen[j])
        msg += "\nInitial state / operator:\n"
        msg += str(dyn.initial)
        msg += "\nTarget state / operator:\n"
        msg += str(dyn.target)
        logger.info(msg)

    if out_file_ext is not None:
        # Save initial amplitudes to a text file
        pulsefile = "ctrl_amps_initial_" + out_file_ext
        dyn.save_amps(pulsefile)
        if log_level <= logging.INFO:
            logger.info("Initial amplitudes output to file: " + pulsefile)

    # Start the optimisation
    result = optim.run_optimization()

    if out_file_ext is not None:
        # Save final amplitudes to a text file
        pulsefile = "ctrl_amps_final_" + out_file_ext
        dyn.save_amps(pulsefile)
        if log_level <= logging.INFO:
            logger.info("Final amplitudes output to file: " + pulsefile)

    return result