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
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")
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))
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")
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")
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))
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
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_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_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")
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")
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")
def test_09_load_params(self): """ control.pulseoptim: Hadamard gate (loading config from file) compare with result produced by pulseoptim method """ H_d = sigmaz() H_c = sigmax() U_0 = identity(2) U_targ = hadamard_transform(1) cfg = optimconfig.OptimConfig() cfg.param_fname = "Hadamard_params.ini" cfg.param_fpath = os.path.join(os.path.dirname(__file__), cfg.param_fname) cfg.pulse_type = "ZERO" loadparams.load_parameters(cfg.param_fpath, config=cfg) dyn = dynamics.DynamicsUnitary(cfg) dyn.target = U_targ dyn.initial = U_0 dyn.drift_dyn_gen = H_d dyn.ctrl_dyn_gen = [H_c] loadparams.load_parameters(cfg.param_fpath, dynamics=dyn) dyn.init_timeslots() n_ts = dyn.num_tslots n_ctrls = dyn.num_ctrls pgen = pulsegen.create_pulse_gen(pulse_type=cfg.pulse_type, dyn=dyn) loadparams.load_parameters(cfg.param_fpath, pulsegen=pgen) tc = termcond.TerminationConditions() loadparams.load_parameters(cfg.param_fpath, term_conds=tc) if cfg.optim_method == 'BFGS': optim = optimizer.OptimizerBFGS(cfg, dyn) elif cfg.optim_method == 'FMIN_L_BFGS_B': optim = optimizer.OptimizerLBFGSB(cfg, dyn) elif cfg.optim_method is None: raise errors.UsageError("Optimisation algorithm must be specified " "via 'optim_method' parameter") else: optim = optimizer.Optimizer(cfg, dyn) optim.method = cfg.optim_method loadparams.load_parameters(cfg.param_fpath, optim=optim) sts = stats.Stats() dyn.stats = sts optim.stats = sts optim.config = cfg optim.dynamics = dyn optim.pulse_generator = pgen optim.termination_conditions = tc init_amps = np.zeros([n_ts, n_ctrls]) for j in range(n_ctrls): init_amps[:, j] = pgen.gen_pulse() dyn.initialize_controls(init_amps) result = optim.run_optimization() result2 = cpo.optimize_pulse_unitary(H_d, list([H_c]), U_0, U_targ, 6, 6, fid_err_targ=1e-10, init_pulse_type='LIN', amp_lbound=-1.0, amp_ubound=1.0, gen_stats=True) assert_almost_equal(result.final_amps, result2.final_amps, decimal=5, err_msg="Pulses do not match")
def test_03_dumping(self): """ control: data dumping Dump out processing data, check file counts """ 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()
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
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))
# **************************************************************** # 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
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")
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