def gen_basis_vectors(n, dims, choice): vectors = [] basic_states = [] bits = int(math.log(n, 2)) #for i in range(n): #state=qt.basis(n,i) #fock_states.append(state) q = rabbit(bits, [], 0) basic_states.append(q) q = rabbit(bits, [1], 0) basic_states.append(q) q = rabbit(bits, [n - 1], 0) basic_states.append(q) indexvec = [] for i in range(bits): indexvec.append(i) q = rabbit(bits, indexvec, 1) basic_states.append(q) test_opt1 = [ basic_states[0], basic_states[1], basic_states[2], basic_states[3] ] test_opt2 = [ basic_states[0], basic_states[1], basic_states[2], basic_states[3], basic_states[-1] + basic_states[1] ] if choice == 1: #Basis states vectors = basic_states q = qt.Qobj(np.ones(n)) q = q.unit() vectors.append(q) vectors.append(state) #there is no two for now elif choice == 2: vectors = basic_states elif choice == 3: #Hadamard option 1 h = tensor_fix(qt.hadamard_transform(bits)) for state in basic_states: state_n = h * state state_n = state_n.unit() vectors.append(state_n) elif choice == 4: #QFT option 1 quft = tensor_fix(qft.qft(bits)) for state in basic_states: state_n = quft * state state_n = state_n.unit() vectors.append(state_n) elif choice == 5: #Hadamard option 2 h = tensor_fix(qt.hadamard_transform(bits)) for state in basic_states: state_n = h * state state_n = state_n.unit() vectors.append(state_n) elif choice == 6: #QFT option 2 quft = tensor_fix(qft.qft(bits)) for state in basic_states: state_n = quft * state state_n = state_n.unit() vectors.append(state_n) vectors.append(state_n) return vectors
def gen_basis_vectors(n,dims,choice): vectors=[] fock_states=[] bits=int(math.log(n,2)) q=rabbit(bits,[],0) basic_states.append(q) q=rabbit(bits,[1],0) basic_states.append(q) q=rabbit(bits,[n-1],0) basic_states.append(q) indexvec=[] for i in range(bits): indexvec.append(i) q=rabbit(bits,indexvec,1) basic_states.append(q) if choice == 1: #Unused psuedo-Basis states vectors = basis_states q=qt.Qobj(np.ones(n)) q=q.unit() vectors.append(q) vectors.append(state) elif choice ==2: #true basis states vectors=basic_states elif choice == 3: #Hadamard option 1 h=tensor_fix(qt.hadamard_transform(bits)) for state in basic_states: state_n=h*state state_n=state_n.unit() vectors.append(state_n) elif choice == 4: #QFT option 1 quft=tensor_fix(qft.qft(bits)) for state in basis_states: state_n=quft*state state_n=state_n.unit() vectors.append(state_n) elif choice == 5: #Hadamard option 2 h=tensor_fix(qt.hadamard_transform(bits)) for state in basis_states: state_n=h*state state_n=state_n.unit() vectors.append(state_n) elif choice == 6: #QFT option 2 quft=tensor_fix(qft.qft(bits)) for state in basis_states: state_n=quft*state state_n=state_n.unit() vectors.append(state_n) vectors.append(state_n) return vectors
def test_02_2_qft_bounds(self): """ control.pulseoptim: QFT gate with linear initial pulses (bounds) assert that amplitudes remain in bounds """ Sx = sigmax() Sy = sigmay() Sz = sigmaz() Si = 0.5*identity(2) H_d = 0.5*(tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz)) H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)] U_0 = identity(4) # Target for the gate evolution - Quantum Fourier Transform gate U_targ = qft.qft(2) n_ts = 10 evo_time = 10 result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time, fid_err_targ=1e-9, amp_lbound=-1.0, amp_ubound=1.0, init_pulse_type='LIN', gen_stats=True) assert_((result.final_amps >= -1.0).all() and (result.final_amps <= 1.0).all(), msg="Amplitude bounds exceeded for QFT")
def test_02_2_qft_bounds(self): """ control.pulseoptim: QFT gate with linear initial pulses (bounds) assert that amplitudes remain in bounds """ Sx = sigmax() Sy = sigmay() Sz = sigmaz() Si = 0.5 * identity(2) H_d = 0.5 * (tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz)) H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)] U_0 = identity(4) # Target for the gate evolution - Quantum Fourier Transform gate U_targ = qft.qft(2) n_ts = 10 evo_time = 10 result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time, fid_err_targ=1e-9, amp_lbound=-1.0, amp_ubound=1.0, init_pulse_type='LIN', gen_stats=True) assert_((result.final_amps >= -1.0).all() and (result.final_amps <= 1.0).all(), msg="Amplitude bounds exceeded for QFT")
def testQFTComparison(self): """ qft: compare qft and product of qft steps """ for N in range(1, 5): U1 = qft(N) U2 = gate_sequence_product(qft_steps(N)) assert_((U1 - U2).norm() < 1e-12)
def test_02_1_qft(self): """ control.pulseoptim: QFT gate with linear initial pulses assert that goal is achieved and fidelity error is below threshold """ Sx = sigmax() Sy = sigmay() Sz = sigmaz() Si = 0.5 * identity(2) H_d = 0.5 * (tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz)) H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)] U_0 = identity(4) # Target for the gate evolution - Quantum Fourier Transform gate U_targ = qft.qft(2) n_ts = 10 evo_time = 10 result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time, fid_err_targ=1e-9, init_pulse_type='LIN', gen_stats=True) assert_(result.goal_achieved, msg="QFT goal not achieved. " "Terminated due to: {}, with infidelity: {}".format( result.termination_reason, result.fid_err)) assert_almost_equal(result.fid_err, 0.0, decimal=7, err_msg="QFT infidelity too high") # check bounds result2 = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time, fid_err_targ=1e-9, amp_lbound=-1.0, amp_ubound=1.0, init_pulse_type='LIN', gen_stats=True) assert_((result2.final_amps >= -1.0).all() and (result2.final_amps <= 1.0).all(), msg="Amplitude bounds exceeded for QFT")
def execute(self, v): N = v.shape[0] n = int(math.log(N, 2)) F = qft(n) F = F.full( ) # To change the shape and distribution in order to be able to operate F = qutip.Qobj(F) result = (F * v).full() np.around(result, 5, result) r = qutip.Qobj(result) self.memory_spent = get_mem_used() return r
def test_02_1_qft(self): """ control.pulseoptim: QFT gate with linear initial pulses assert that goal is achieved and fidelity error is below threshold """ Sx = sigmax() Sy = sigmay() Sz = sigmaz() Si = 0.5*identity(2) H_d = 0.5*(tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz)) H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)] U_0 = identity(4) # Target for the gate evolution - Quantum Fourier Transform gate U_targ = qft.qft(2) n_ts = 10 evo_time = 10 result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time, fid_err_targ=1e-9, init_pulse_type='LIN', gen_stats=True) assert_(result.goal_achieved, msg="QFT goal not achieved. " "Terminated due to: {}, with infidelity: {}".format( result.termination_reason, result.fid_err)) assert_almost_equal(result.fid_err, 0.0, decimal=7, err_msg="QFT infidelity too high") # check bounds result2 = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time, fid_err_targ=1e-9, amp_lbound=-1.0, amp_ubound=1.0, init_pulse_type='LIN', gen_stats=True) assert_((result2.final_amps >= -1.0).all() and (result2.final_amps <= 1.0).all(), msg="Amplitude bounds exceeded for QFT")
def test (self): print("Testing " + self.implementation + "\n\n") from qutip.qip.algorithms.qft import qft for n in range (c_min_q_t, c_max_q_t): print("\t- {0:2d} qubits".format(n)) #v = ket(0, n) v = random_ket (n) f1 = qft(n) f1 = f1.full() # To change the shape and distribution in order to be able to operate f1 = qutip.Qobj(f1) f1v = (f1 * v).full() np.around (f1v, 5, f1v) f1v = qutip.Qobj(f1v) f2v = self.execute(v) if (f1v != f2v): print ("Error with the operation for {0:2} qubit(s). Expected result and obstained result doesn't match".format(n)) if (c_verbose): print ("\n\n\t-Input:\n{0}\n\n\t-Expected:\n{1}\n\n\t-Obtained:\n{2}".format(v, f1v, f2v)) if c_raise: N = 2**n for j in range (N): if f1v[j,0] != f2v[j,0]: print ("posicion {0} tiene valor {1} pero se esperaba {2}".format(j, f1v[j,0], f2v[j,0])) return True else: print("\t\t\t-> Succeded") return False
# Drift Hamiltonian H_d = 0.5 * (tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz)) print("drift {}".format(H_d)) # The (four) control Hamiltonians H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)] j = 0 for c in H_c: j += 1 print("ctrl {} \n{}".format(j, c)) n_ctrls = len(H_c) # start point for the gate evolution U_0 = tensor(identity(2), identity(2)) print("U_0 {}".format(U_0)) # Target for the gate evolution - Quantum Fourier Transform gate U_targ = (qft.qft(2)).tidyup() #U_targ.dims = U_0.dims print("target {}".format(U_targ)) print("Check unitary (should be I) {}".format(U_targ.dag() * U_targ)) # ***** Define time evolution parameters ***** # Number of time slots n_ts = 10 # Time allowed for the evolution evo_time = 10 # ***** Define the termination conditions ***** # Fidelity error target fid_err_targ = 1e-14 # Maximum iterations for the optisation algorithm
controls=[_sx], initial=_si, target=_hadamard, kwargs=_hadamard_kwargs) # Quantum Fourier transform. _qft_system = 0.5 * sum(qutip.tensor(op, op) for op in (_sx, _sy, _sz)) _qft_controls = [0.5*qutip.tensor(_sx, _si), 0.5*qutip.tensor(_sy, _si), 0.5*qutip.tensor(_si, _sx), 0.5*qutip.tensor(_si, _sy)] _qft_kwargs = {'num_tslots': 10, 'evo_time': 10, 'gen_stats': True, 'init_pulse_type': 'LIN', 'fid_err_targ': 1e-9, 'dyn_type': 'UNIT'} qft = _System(system=_qft_system, controls=_qft_controls, initial=qutip.identity([2, 2]), target=qft.qft(2), kwargs=_qft_kwargs) # Coupling constants are completely arbitrary. _ising_system = (0.9*qutip.tensor(_sx, _si) + 0.7*qutip.tensor(_si, _sx) + 0.8*qutip.tensor(_sz, _si) + 0.9*qutip.tensor(_si, _sz)) _ising_kwargs = {'num_tslots': 10, 'evo_time': 18, 'init_pulse_type': 'LIN', 'fid_err_targ': 1e-10, 'dyn_type': 'UNIT'} ising = _System(system=_ising_system, controls=[qutip.tensor(_sz, _sz)], initial=qutip.basis([2, 2], [0, 0]), target=qutip.basis([2, 2], [1, 1]), kwargs=_ising_kwargs) # Louivillian amplitude-damping channel system. _l_adc_system = 0.1 * (2*qutip.tensor(_sm, _sp.dag())
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_name = 'QFT' ## Defining the physics Sx = sigmax() Sy = sigmay() Sz = sigmaz() Si = 0.5*identity(2) # Drift Hamiltonian H_d = 0.5*(tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz)) # The (four) control Hamiltonians H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)] n_ctrls = len(H_c) # start point for the gate evolution U_0 = identity(4) # Target for the gate evolution - Quantum Fourier Transform gate U_targ = qft.qft(2) ## Defining the time evolution parameters # Number of time slots n_ts = 200 # Time allowed for the evolution evo_time = 10 ##Set the conditions which will cause the pulse optimisation to terminate # 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
def qft_operator(self, N): n = int(math.log(N, 2)) F = qft(n) F = F.full() np.around(F, c_round_dist, F) return qutip.Qobj(F)
def test_myIQFT_operator_correct(self): nqubits = 4 benchIQFT = qft(nqubits) myIQFT = operator_IQFT(nqubits, False) np.testing.assert_array_almost_equal(benchIQFT, myIQFT)
# **************************************************************** # Define the physics of the problem Sx = sigmax() Sy = sigmay() Sz = sigmaz() Si = 0.5 * identity(2) # Drift Hamiltonian H_d = 0.5 * (tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz)) # The (four) control Hamiltonians H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)] n_ctrls = len(H_c) # start point for the gate evolution U_0 = identity(4) # Target for the gate evolution - Quantum Fourier Transform gate U_targ = qft.qft(2) # ***** Define time evolution parameters ***** # Duration of each timeslot dt = 0.05 # List of evolution times to try evo_times = [1, 3, 10] n_evo_times = len(evo_times) evo_time = evo_times[0] n_ts = int(float(evo_time) / dt) # Empty list that will hold the results for each evolution time results = list() # ***** Define the termination conditions ***** # Fidelity error target fid_err_targ = 1e-10
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")
# Drift Hamiltonian H_d = 0.5*(tensor(Sx, Sx) + tensor(Sy, Sy) + tensor(Sz, Sz)) print("drift {}".format(H_d)) # The (four) control Hamiltonians H_c = [tensor(Sx, Si), tensor(Sy, Si), tensor(Si, Sx), tensor(Si, Sy)] j = 0 for c in H_c: j += 1 print("ctrl {} \n{}".format(j, c)) n_ctrls = len(H_c) # start point for the gate evolution U_0 = tensor(identity(2), identity(2)) print("U_0 {}".format(U_0)) # Target for the gate evolution - Quantum Fourier Transform gate U_targ = (qft.qft(2)).tidyup() #U_targ.dims = U_0.dims print("target {}".format(U_targ)) print("Check unitary (should be I) {}".format(U_targ.dag()*U_targ)) # ***** Define time evolution parameters ***** # Number of time slots n_ts = 10 # Time allowed for the evolution evo_time = 10 # ***** Define the termination conditions ***** # Fidelity error target fid_err_targ = 1e-14 # Maximum iterations for the optisation algorithm
def QFT_pulse(N: int = 4, tau: float = 1): pulses = [T_I_pulse(N, tau)] for n in range(N-1): pulses.append(H_k_pulse(n, N, tau)) pulses.append(P_n_pulse(n+1, N, tau)) pulses.append(H_k_pulse(N-1, N, tau)) pulses.append(T_F_pulse(N, tau)) return ff.concatenate(pulses, calc_pulse_correlation_FF=False) # %% Get a 4-qubit QFT and plot the filter function omega = np.logspace(-2, 2, 500) N = 4 QFT = QFT_pulse(N) # Check the pulse produces the correct propagator after swapping the qubits swaps = [qip.operations.swap(N, [i, j]).full() for i, j in zip(range(N//2), range(N-1, N//2-1, -1))] prop = ff.util.mdot(swaps) @ QFT.total_propagator qt.matrix_histogram_complex(prop) print('Correct action: ', ff.util.oper_equiv(prop, qt_qft.qft(N), eps=1e-14)) fig, ax, _ = plotting.plot_filter_function(QFT, omega) # Move the legend to the side because of many entries ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)