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 Hamiltonian_toymodel(theta, phi): ## Defining Constants omega = 1.4 * 10**6 m_b = 5.7883818066*10**-5 par=m_b*2.417990504024*10**11 # s-1/mT a1 = np.array([-.0989, -.0989, 1.7569]) * par # /mT a2 = np.array([0.0,0.0,1.0812]) * par H_a_zeeman_nt = omega * (Sx * mt.sin(theta) * mt.cos(phi) + Sy * mt.sin(theta) * mt. sin(phi) + Sz * mt.cos(theta)) Ha_zeeman = qt.tensor(H_a_zeeman_nt, qt.identity(3)) H_a_hfi = a1[0] * qt.tensor(Sx, I2_x) + a1[1] * qt.tensor(Sy, I2_y) + a1[2] * qt.tensor(Sz, I2_z) H_a = Ha_zeeman + H_a_hfi H_a_eigen, H_a_eigenstates = H_a.eigenstates() H_b_zeeman_nt = omega * (Sx * mt.sin(theta) * mt.cos(phi) + Sy * mt.sin(theta) * mt. sin(phi) + Sz * mt.cos(theta)) Hb_zeeman = qt.tensor(H_b_zeeman_nt, qt.identity(3)) H_b_hfi = a2[0] * qt.tensor(Sx, I2_x) + a2[1] * qt.tensor(Sy, I2_y) + a2[2] * qt.tensor(Sz, I2_z) H_b = Hb_zeeman + H_b_hfi H_b_eigen, H_b_eigenstates = H_b.eigenstates() return (H_a_eigen, H_a_eigenstates, H_b_eigen, H_b_eigenstates)
def test_enr_destory_full(): "Excitation-number-restricted state-space: full state space" a1, a2 = enr_destroy([4, 4], 4**2) b1, b2 = tensor(destroy(4), identity(4)), tensor(identity(4), destroy(4)) assert_(a1 == b1) assert_(a2 == b2)
def testJCZeroTemperature(): """ brmesolve: Jaynes-Cummings model, zero temperature """ N = 10 a = tensor(destroy(N), identity(2)) sm = tensor(identity(N), destroy(2)) psi0 = ket2dm(tensor(basis(N, 1), basis(2, 0))) a_ops = [(a + a.dag())] e_ops = [a.dag() * a, sm.dag() * sm] w0 = 1.0 * 2 * np.pi g = 0.05 * 2 * np.pi kappa = 0.05 times = np.linspace(0, 2 * 2 * np.pi / g, 1000) c_ops = [np.sqrt(kappa) * a] H = w0 * a.dag() * a + w0 * sm.dag() * sm + \ g * (a + a.dag()) * (sm + sm.dag()) res_me = mesolve(H, psi0, times, c_ops, e_ops) res_brme = brmesolve(H, psi0, times, a_ops, e_ops, spectra_cb=[lambda w: kappa * (w >= 0)]) for idx, e in enumerate(e_ops): diff = abs(res_me.expect[idx] - res_brme.expect[idx]).max() assert_(diff < 5e-2) # accept 5% error
def test_state_to_state(self): """ control.pulseoptim: state-to-state transfer linear initial pulse used assert that goal is achieved """ # 2 qubits with Ising interaction # some arbitary coupling constants alpha = [0.9, 0.7] beta = [0.8, 0.9] Sx = sigmax() Sz = sigmaz() H_d = (alpha[0]*tensor(Sx,identity(2)) + alpha[1]*tensor(identity(2),Sx) + beta[0]*tensor(Sz,identity(2)) + beta[1]*tensor(identity(2),Sz)) H_c = [tensor(Sz,Sz)] q1_0 = q2_0 = Qobj([[1], [0]]) q1_T = q2_T = Qobj([[0], [1]]) psi_0 = tensor(q1_0, q2_0) psi_T = tensor(q1_T, q2_T) n_ts = 10 evo_time = 18 # Run the optimisation result = cpo.optimize_pulse_unitary(H_d, H_c, psi_0, psi_T, n_ts, evo_time, fid_err_targ=1e-10, init_pulse_type='LIN', gen_stats=True) assert_(result.goal_achieved, msg="State-to-state goal not achieved. " "Terminated due to: {}, with infidelity: {}".format( result.termination_reason, result.fid_err)) assert_almost_equal(result.fid_err, 0.0, decimal=10, err_msg="Hadamard infidelity too high") #Try with Qobj propagation result = cpo.optimize_pulse_unitary(H_d, H_c, psi_0, psi_T, n_ts, evo_time, fid_err_targ=1e-10, init_pulse_type='LIN', dyn_params={'oper_dtype':Qobj}, gen_stats=True) assert_(result.goal_achieved, msg="State-to-state goal not achieved " "(Qobj propagation)" "Terminated due to: {}, with infidelity: {}".format( result.termination_reason, result.fid_err))
def test_01_2_unitary_hadamard_no_stats(self): """ control.pulseoptim: Hadamard gate with linear initial pulses (no stats) assert that goal is achieved """ # Hadamard H_d = sigmaz() H_c = [sigmax()] U_0 = identity(2) U_targ = hadamard_transform(1) n_ts = 10 evo_time = 10 # Run the optimisation #Try without stats result = cpo.optimize_pulse_unitary(H_d, H_c, U_0, U_targ, n_ts, evo_time, fid_err_targ=1e-10, init_pulse_type='LIN', gen_stats=False) assert_(result.goal_achieved, msg="Hadamard goal not achieved " "(no stats). " "Terminated due to: {}, with infidelity: {}".format( result.termination_reason, result.fid_err))
def _pseudo_inverse_dense(L, rhoss, method='direct', **pseudo_args): """ Internal function for computing the pseudo inverse of an Liouvillian using dense matrix methods. See pseudo_inverse for details. """ if method == 'direct': rho_vec = np.transpose(mat2vec(rhoss.full())) tr_mat = tensor([identity(n) for n in L.dims[0][0]]) tr_vec = np.transpose(mat2vec(tr_mat.full())) N = np.prod(L.dims[0][0]) I = np.identity(N * N) P = np.kron(np.transpose(rho_vec), tr_vec) Q = I - P LIQ = np.linalg.solve(L.full(), Q) R = np.dot(Q, LIQ) return Qobj(R, dims=L.dims) elif method == 'numpy': return Qobj(np.linalg.pinv(L.full()), dims=L.dims) elif method == 'scipy': return Qobj(la.pinv(L.full()), dims=L.dims) elif method == 'scipy2': return Qobj(la.pinv2(L.full()), dims=L.dims) else: raise ValueError("Unsupported method '%s'. Use 'direct' or 'numpy'" % method)
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_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_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_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 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 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 genstate(s): """helper function to obtain the correct initialization""" newstr = s.replace("+","0") newstr = newstr.replace("-","1") print(newstr) state = qt.ket(newstr) if s[0] == "+" or s[0]=="-": operator=qt.hadamard_transform() else: operator=qt.identity(2) for i in range(1,len(s),1): if s[i] == "+" or s[i]=="-": #apply hadamard operator = qt.tensor([operator,qt.hadamard_transform()]) else: operator = qt.tensor([operator,qt.identity(2)]) return operator * state
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 jc_integrate(self, N, wc, wa, g, kappa, gamma, pump, psi0, use_rwa, tlist): # Hamiltonian a = tensor(destroy(N), identity(2)) sm = tensor(identity(N), destroy(2)) if use_rwa: # use the rotating wave approxiation H = wc * a.dag() * a + wa * sm.dag() * sm + g * ( a.dag() * sm + a * sm.dag()) else: H = wc * a.dag() * a + wa * sm.dag() * sm + g * ( a.dag() + a) * (sm + sm.dag()) # collapse operators c_op_list = [] n_th_a = 0.0 # zero temperature rate = kappa * (1 + n_th_a) c_op_list.append(np.sqrt(rate) * a) rate = kappa * n_th_a if rate > 0.0: c_op_list.append(np.sqrt(rate) * a.dag()) rate = gamma if rate > 0.0: c_op_list.append(np.sqrt(rate) * sm) rate = pump if rate > 0.0: c_op_list.append(np.sqrt(rate) * sm.dag()) # evolve and calculate expectation values output = mesolve( H, psi0, tlist, c_op_list, [a.dag() * a, sm.dag() * sm]) expt_list = output.expect[0], output.expect[1] return expt_list[0], expt_list[1]
def Singlet_yield(theta, rate) : (Ha_eigen_theta,H_a_eigenstates, Hb_eigen_theta, H_b_eigenstates) = Hamiltonian_toymodel(theta,0) Sx_aq = qt.tensor(Sx, qt.identity(3)).transform(H_a_eigenstates) Sy_aq = qt.tensor(Sy, qt.identity(3)).transform(H_a_eigenstates) Sz_aq = qt.tensor(Sz, qt.identity(3)).transform(H_a_eigenstates) Sx_bq = qt.tensor(Sx, qt.identity(3)).transform(H_b_eigenstates) Sy_bq = qt.tensor(Sy, qt.identity(3)).transform(H_b_eigenstates) Sz_bq = qt.tensor(Sz, qt.identity(3)).transform(H_b_eigenstates) Sx_a = Sx_aq.data Sy_a = Sy_aq.data Sz_a = Sz_aq.data Sx_b = Sx_bq.data Sy_b = Sy_bq.data Sz_b = Sz_bq.data S_a = np.array([Sx_a, Sy_a, Sz_a]) S_b = np.array([Sx_b, Sy_b, Sz_b]) g_a1 = 0.0 for p in range(0,3): for q in range(0,3): (rolpA,colpA) = S_a[p].nonzero() (rolqA,colqA) = S_a[q].nonzero() (rolpB,colpB) = S_b[p].nonzero() (rolqB,colqB) = S_b[q].nonzero() A = list(set(zip(rolpA, colpA)).intersection(zip(rolqA, colqA))) # Techniques to iterate over sparse matrices B = list(set(zip(rolpB, colpB)).intersection(zip(rolqB, colqB))) # Taking Intersction over non-zero values #print((10.0*p + q)/100) for n,m in A: #print (str(n/576.0*100.0)) for r,s in B: wa_mn = Ha_eigen_theta[m] - Ha_eigen_theta[n] # Frequencies as deined in timmel et. al. 1998 wb_rs = Hb_eigen_theta[r] - Hb_eigen_theta[s] g_a1 += S_a[p][n, m]*S_a[q][m, n]*S_b[p][r,s]*S_b[q][s, r]* (rate**2/(rate**2 + (wa_mn - wb_rs)**2)) singletyield = (g_a1/9.0) + .25 return singletyield
def jc_steadystate(self, N, wc, wa, g, kappa, gamma, pump, psi0, use_rwa, tlist): # Hamiltonian a = tensor(destroy(N), identity(2)) sm = tensor(identity(N), destroy(2)) if use_rwa: # use the rotating wave approxiation H = wc * a.dag( ) * a + wa * sm.dag() * sm + g * (a.dag() * sm + a * sm.dag()) else: H = wc * a.dag() * a + wa * sm.dag() * sm + g * ( a.dag() + a) * (sm + sm.dag()) # collapse operators c_op_list = [] n_th_a = 0.0 # zero temperature rate = kappa * (1 + n_th_a) c_op_list.append(np.sqrt(rate) * a) rate = kappa * n_th_a if rate > 0.0: c_op_list.append(np.sqrt(rate) * a.dag()) rate = gamma if rate > 0.0: c_op_list.append(np.sqrt(rate) * sm) rate = pump if rate > 0.0: c_op_list.append(np.sqrt(rate) * sm.dag()) # find the steady state rho_ss = steadystate(H, c_op_list) return expect(a.dag() * a, rho_ss), expect(sm.dag() * sm, rho_ss)
def _pseudo_inverse_sparse(L, rhoss, method='splu', **pseudo_args): """ Internal function for computing the pseudo inverse of an Liouvillian using sparse matrix methods. See pseudo_inverse for details. """ N = np.prod(L.dims[0][0]) rhoss_vec = operator_to_vector(rhoss) tr_op = tensor([identity(n) for n in L.dims[0][0]]) tr_op_vec = operator_to_vector(tr_op) P = sp.kron(rhoss_vec.data, tr_op_vec.data.T, format='csr') I = sp.eye(N*N, N*N, format='csr') Q = I - P if pseudo_args['use_rcm']: perm = reverse_cuthill_mckee(L.data) A = sp_permute(L.data, perm, perm, 'csr') Q = sp_permute(Q, perm, perm, 'csr') else: if not settings.has_mkl: A = L.data.tocsc() A.sort_indices() if method == 'splu': if settings.has_mkl: LIQ = mkl_spsolve(A,Q.toarray()) else: lu = sp.linalg.splu(A, permc_spec=pseudo_args['permc_spec'], diag_pivot_thresh=pseudo_args['diag_pivot_thresh'], options=dict(ILU_MILU=pseudo_args['ILU_MILU'])) LIQ = lu.solve(Q.toarray()) elif method == 'spilu': lu = sp.linalg.spilu(A, permc_spec=pseudo_args['permc_spec'], fill_factor=pseudo_args['fill_factor'], drop_tol=pseudo_args['drop_tol']) LIQ = lu.solve(Q.toarray()) else: raise ValueError("unsupported method '%s'" % method) R = sp.csr_matrix(Q * LIQ) if pseudo_args['use_rcm']: rev_perm = np.argsort(perm) R = sp_permute(R, rev_perm, rev_perm, 'csr') return Qobj(R, dims=L.dims)
def _pseudo_inverse_sparse(L, rhoss, method='splu', use_umfpack=False, use_rcm=False): """ Internal function for computing the pseudo inverse of an Liouvillian using sparse matrix methods. See pseudo_inverse for details. """ N = np.prod(L.dims[0][0]) rhoss_vec = operator_to_vector(rhoss) tr_op = tensor([identity(n) for n in L.dims[0][0]]) tr_op_vec = operator_to_vector(tr_op) P = sp.kron(rhoss_vec.data, tr_op_vec.data.T, format='csc') I = sp.eye(N*N, N*N, format='csc') Q = I - P if use_rcm: perm = reverse_cuthill_mckee(L.data) A = sp_permute(L.data, perm, perm, 'csc').tocsc() Q = sp_permute(Q, perm, perm, 'csc') permc_spec = 'NATURAL' else: A = L.data.tocsc() A.sort_indices() permc_spec = 'COLAMD' if method == 'spsolve': sp.linalg.use_solver(assumeSortedIndices=True, useUmfpack=use_umfpack) LIQ = sp.linalg.spsolve(A, Q) elif method == 'splu': lu = sp.linalg.splu(A, permc_spec=permc_spec) LIQ = lu.solve(Q.toarray()) elif method == 'spilu': lu = sp.linalg.spilu(A, permc_spec=permc_spec, fill_factor=10, drop_tol=1e-8) LIQ = lu.solve(Q.toarray()) else: raise ValueError("unsupported method '%s'" % method) R = sp.csc_matrix(Q * LIQ) if use_rcm: rev_perm = np.argsort(perm) R = sp_permute(R, rev_perm, rev_perm, 'csc') return Qobj(R, dims=L.dims)
def jc_integrate(self, N, wc, wa, g, kappa, gamma, pump, psi0, use_rwa, tlist): # Hamiltonian a = tensor(destroy(N), identity(2)) sm = tensor(identity(N), destroy(2)) # Identity super-operator E0 = sprepost(tensor(qeye(N), qeye(2)), tensor(qeye(N), qeye(2))) if use_rwa: # use the rotating wave approxiation H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() * sm + a * sm.dag()) else: H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() + a) * (sm + sm.dag()) # collapse operators c_op_list = [] n_th_a = 0.0 # zero temperature rate = kappa * (1 + n_th_a) c_op_list.append(np.sqrt(rate) * a) rate = kappa * n_th_a if rate > 0.0: c_op_list.append(np.sqrt(rate) * a.dag()) rate = gamma if rate > 0.0: c_op_list.append(np.sqrt(rate) * sm) rate = pump if rate > 0.0: c_op_list.append(np.sqrt(rate) * sm.dag()) # evolve and calculate expectation values output1 = mesolve(H, psi0, tlist, c_op_list, []) output2 = mesolve(H, E0, tlist, c_op_list, []) return output1, output2
def test_05_1_state_to_state(self): """ control.pulseoptim: state-to-state transfer linear initial pulse used assert that goal is achieved """ # 2 qubits with Ising interaction # some arbitary coupling constants alpha = [0.9, 0.7] beta = [0.8, 0.9] Sx = sigmax() Sz = sigmaz() H_d = (alpha[0]*tensor(Sx,identity(2)) + alpha[1]*tensor(identity(2),Sx) + beta[0]*tensor(Sz,identity(2)) + beta[1]*tensor(identity(2),Sz)) H_c = [tensor(Sz,Sz)] q1_0 = q2_0 = Qobj([[1], [0]]) q1_T = q2_T = Qobj([[0], [1]]) psi_0 = tensor(q1_0, q2_0) psi_T = tensor(q1_T, q2_T) n_ts = 10 evo_time = 18 # Run the optimisation result = cpo.optimize_pulse_unitary(H_d, H_c, psi_0, psi_T, n_ts, evo_time, fid_err_targ=1e-10, init_pulse_type='LIN', gen_stats=True) assert_(result.goal_achieved, msg="State-to-state goal not achieved. " "Terminated due to: {}, with infidelity: {}".format( result.termination_reason, result.fid_err)) assert_almost_equal(result.fid_err, 0.0, decimal=10, err_msg="Hadamard infidelity too high")
def test_05_2_state_to_state_qobj(self): """ control.pulseoptim: state-to-state transfer (Qobj) linear initial pulse used assert that goal is achieved """ # 2 qubits with Ising interaction # some arbitary coupling constants alpha = [0.9, 0.7] beta = [0.8, 0.9] Sx = sigmax() Sz = sigmaz() H_d = (alpha[0]*tensor(Sx,identity(2)) + alpha[1]*tensor(identity(2),Sx) + beta[0]*tensor(Sz,identity(2)) + beta[1]*tensor(identity(2),Sz)) H_c = [tensor(Sz,Sz)] q1_0 = q2_0 = Qobj([[1], [0]]) q1_T = q2_T = Qobj([[0], [1]]) psi_0 = tensor(q1_0, q2_0) psi_T = tensor(q1_T, q2_T) n_ts = 10 evo_time = 18 #Try with Qobj propagation result = cpo.optimize_pulse_unitary(H_d, H_c, psi_0, psi_T, n_ts, evo_time, fid_err_targ=1e-10, init_pulse_type='LIN', dyn_params={'oper_dtype':Qobj}, gen_stats=True) assert_(result.goal_achieved, msg="State-to-state goal not achieved " "(Qobj propagation)" "Terminated due to: {}, with infidelity: {}".format( result.termination_reason, result.fid_err))
def test_id_evolution(self): """ Test for identity evolution """ N = 1 proc = Processor(N=N) init_state = rand_ket(2) tlist = [0., 1., 2.] proc.add_pulse(Pulse(identity(2), 0, tlist, False)) result = proc.run_state(init_state, options=SolverOptions(store_final_state=True)) global_phase = init_state[0, 0] / result.final_state[0, 0] assert_allclose(global_phase * result.final_state.full(), init_state.full())
def test_user_gate(self): """ User defined gate for QubitCircuit """ def customer_gate1(arg_values): mat = np.zeros((4, 4), dtype=np.complex128) mat[0, 0] = mat[1, 1] = 1. mat[2:4, 2:4] = gates.rx(arg_values).full() return Qobj(mat, dims=[[2, 2], [2, 2]]) def customer_gate2(): mat = np.array([[1., 0], [0., 1.j]]) return Qobj(mat, dims=[[2], [2]]) qc = QubitCircuit(3) qc.user_gates = {"CTRLRX": customer_gate1, "T1": customer_gate2} qc.add_gate("CTRLRX", targets=[1, 2], arg_value=np.pi / 2) qc.add_gate("T1", targets=[1]) props = qc.propagators() result1 = tensor(identity(2), customer_gate1(np.pi / 2)) np.testing.assert_allclose(props[0].full(), result1.full()) result2 = tensor(identity(2), customer_gate2(), identity(2)) np.testing.assert_allclose(props[1].full(), result2.full())
def take_pov(state, from_pov, to_pov, G, basis=None, return_map=False): if from_pov == to_pov: return state n = len(state.dims[0]) d = state.dims[0][0] basis = basis if type(basis) != type(None) else [ qt.basis(d, i) for i in range(d) ] g_inv = lambda i: G(i).dag() * basis[0] O = construct_swap(from_pov, to_pov, state.dims[0])*\ sum([qt.tensor(*[qt.identity(d) if j == from_pov \ else g_inv(i)*basis[i].dag() if j == to_pov \ else G(i).dag() for j in range(n)]) for i in range(d)]) return O if return_map else O * state
def _uncoupled_css(N, a, b): """ Generate the density matrix of the CSS state in the full 2^N dimensional Hilbert space. The CSS states are non-entangled states given by |a, b> = \Prod_i (a|1>_i + b|0>_i). Parameters ---------- N: int The number of two-level systems. a: complex The coefficient of the |1_i> state. b: complex The coefficient of the |0_i> state. Returns ------- css: :class: qutip.Qobj The density matrix for the CSS state in the full Hilbert space. """ N = int(N) # 1. Define i_th factorized density matrix in the uncoupled basis rho_i = np.zeros((2, 2), dtype=complex) rho_i[0, 0] = a * np.conj(a) rho_i[1, 1] = b * np.conj(b) rho_i[0, 1] = a * np.conj(a) rho_i[1, 0] = b * np.conj(b) rho_i = Qobj(rho_i) rho = [0 for i in range(N)] rho[0] = rho_i # 2. Place single-two-level-system density matrices in total Hilbert space for k in range(N - 1): rho[0] = tensor(rho[0], identity(2)) # 3. Cyclic sequence to create all N factorized density matrices # |CSS>_i<CSS|_i a = [i for i in range(N)] b = [[a[i - i2] for i in range(N)] for i2 in range(N)] # 4. Create all other N-1 factorized density matrices # |+><+| = Prod_(i=1)^N |CSS>_i<CSS|_i for i in range(1, N): rho[i] = rho[0].permute(b[i]) identity_i = Qobj(np.eye(2**N), dims=rho[0].dims, shape=rho[0].shape) rho_tot = identity_i for i in range(0, N): rho_tot = rho_tot * rho[i] return rho_tot
def GetIdentity(N): """ Receive the number of qubits and return the Identity matrix for its Hilbert space This is necessary because we want to keep the tensorial composition form Parameters: N : (Number of qubits - int) Return: A qutip object representing a Identity matrix (2^N X 2^N) """ I = np.zeros(N, dtype=object) for i in range(N): I[i] = qt.identity(2) I = qt.tensor(I) return I
def _uncoupled_css(N, a, b): """ Generate the density matrix of the CSS state in the full 2^N dimensional Hilbert space. The CSS states are non-entangled states given by :math:`|a, b\\rangle = \\prod_i (a|1\\rangle_i + b|0\\rangle_i)`. Parameters ---------- N: int The number of two-level systems. a: complex The coefficient of the :math:`|1_i\rangle` state. b: complex The coefficient of the :math:`|0_i\rangle` state. Returns ------- css: :class: qutip.Qobj The density matrix for the CSS state in the full Hilbert space. """ N = int(N) # 1. Define i_th factorized density matrix in the uncoupled basis rho_i = np.zeros((2, 2), dtype=complex) rho_i[0, 0] = a * np.conj(a) rho_i[1, 1] = b * np.conj(b) rho_i[0, 1] = a * np.conj(a) rho_i[1, 0] = b * np.conj(b) rho_i = Qobj(rho_i) rho = [0 for i in range(N)] rho[0] = rho_i # 2. Place single-two-level-system density matrices in total Hilbert space for k in range(N - 1): rho[0] = tensor(rho[0], identity(2)) # 3. Cyclic sequence to create all N factorized density matrices # |CSS>_i<CSS|_i a = [i for i in range(N)] b = [[a[i - i2] for i in range(N)] for i2 in range(N)] # 4. Create all other N-1 factorized density matrices # |+><+| = Prod_(i=1)^N |CSS>_i<CSS|_i for i in range(1, N): rho[i] = rho[0].permute(b[i]) identity_i = Qobj(np.eye(2**N), dims=rho[0].dims, shape=rho[0].shape) rho_tot = identity_i for i in range(0, N): rho_tot = rho_tot * rho[i] return rho_tot
def __init__(self, dm, pos): self.dm = dm.copy() self.pos = pos self.n = dm.shape[0] self.osc_n = int(np.sqrt(self.n)) self.dm.dims = [[self.osc_n, self.osc_n], [self.osc_n, self.osc_n]] X = qt.position(self.osc_n) L, V = X.eigenstates() self.projectors = [ [qt.tensor(v1 * v1.dag(), v2 * v2.dag()) for v2 in V] for v1 in V ] probs = [[(self.dm * p).tr().real for p in row] for row in self.projectors] spaced = L / max(L) self.vpts = [[vp.sphere(pos=self.pos+vp.vector(spaced[i], spaced[j], 0),\ radius=0.5*probs[i][j],#0.7/self.n,\ opacity=probs[i][j])\ for j in range(self.osc_n)] for i in range(self.osc_n)] self.vexp = vp.sphere(pos=self.pos+vp.vector(qt.expect(qt.tensor(X, qt.identity(self.osc_n)), self.dm).real/max(L),\ qt.expect(qt.tensor(qt.identity(self.osc_n), X), self.dm).real/max(L),\ 0),\ radius=0.1, color=vp.color.yellow, opacity=0.9)
def init_comp(self): """ Initialise the object after the configuration has been made, before the optimisation starts. """ # Convenient to have extra attributes calculated once, # this is best place to put them dyn = self.parent #and now the new code self.full_dim = np.product(self.sub_dims) self.dimensional_norm = self.full_dim self.oper_dims = [self.sub_dims, self.sub_dims] # Simply the local targets with the relevent number of identities # tensored before and after it. # We only ever need the .dag() of this, so only storing that. self.large_local_targs_dag = [] for sub_sys in range(self.num_sub_sys): large_local_targ = [] for k in range(sub_sys): large_local_targ.append(identity(self.sub_dims[k])) large_local_targ.append(self.U_local_targs[sub_sys]) for k in range(sub_sys + 1, self.num_sub_sys): large_local_targ.append(identity(self.sub_dims[k])) large_local_targ = reduce(tensor, large_local_targ) if dyn.oper_dtype == Qobj: self.large_local_targs_dag.append(large_local_targ.dag()) else: self.large_local_targs_dag.append( large_local_targ.dag().full()) # Calculate the permutation matrices for the partial trace self.ptrace_perms = {} for sub_sys in range(self.num_sub_sys): self.ptrace_perms[sub_sys] = calc_perm(self.oper_dims, sub_sys)
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 create_projectors(): # Create all the different projectors that are required for the measurement I = qt.identity(2) zero = qt.basis(2, 0) one = qt.basis(2, 1) proj1 = qt.Qobj([ [1, 0], # single qubit projector unto 0 subspace [0, 0] ]) proj2 = qt.Qobj([ [0, 0], # single qubit projector unto 1 subspace [0, 1] ]) # Create projectors for all measurement steps projector1 = qt.tensor(I, I, I, I, proj1, I) # Projector unto 0 for first measurement projector2 = qt.tensor(I, I, I, I, proj2, I) # Projector unto 1 for first measurement projector3 = qt.tensor(I, I, I, I, I, proj1) # Projector unto 0 for second measurement projector4 = qt.tensor(I, I, I, I, I, proj2) # Projector unto 1 for second measurement projector5 = qt.tensor(proj1, I, I, I) # Projector unto 0 for third measurement projector6 = qt.tensor(proj2, I, I, I) # Projector unto 1 for third measurement projector7 = qt.tensor(I, I, proj1, I) # Projector unto 0 for fourth measurement projector8 = qt.tensor(I, I, proj2, I) # Projector unto 1 for fourth measurement # Create projector unto codespace logicalzero = qt.ket2dm( qt.tensor(zero, zero, zero, zero) + qt.tensor(one, one, one, one)).unit() logicalone = qt.ket2dm( qt.tensor(zero, zero, one, one) + qt.tensor(one, one, zero, zero)).unit() projector9 = logicalone + logicalzero # Collect all projectors projectors = [ projector1, projector2, projector3, projector4, projector5, projector6, projector7, projector8, projector9 ] return projectors
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 qtp_identity_product(op, index, L): import qutip as qtp ret = None for i in range(L): if i == index: this_op = op else: this_op = qtp.identity(2) if ret is None: ret = this_op else: ret = qtp.tensor(this_op, ret) return ret
def __init__(self, config, subsystem_list, p_type='GAUSSIAN', two_level=False): self.zero_vars = ['wq0'] self.omegad_mult = False self.two_level = two_level self.p_type = p_type self.subsystem_list = subsystem_list self.derotate = False self.config = config self.H_d, self.H_c = get_hamiltonians(self.config, self.subsystem_list, self.zero_vars) self.U_0 = identity(3 ** len(subsystem_list)) self.n_ctrls = len(self.H_c) self.f_ext = None self.notes = '' if two_level: self.make_two_level()
def test_recovery_two_qubit_rb(self): cliffords = [0, 1, 50] nr_seeds = 50 for cl in cliffords: for _ in range(nr_seeds): cl_seq = rb.randomized_benchmarking_sequence_new( cl, number_of_qubits=2, max_clifford_idx=11520, interleaving_cl=None, desired_net_cl=0) for decomp in ['HZ', 'XY']: tqc.gate_decomposition = \ rb.get_clifford_decomposition(decomp) pulse_tuples_list_all = [] for i, idx in enumerate(cl_seq): pulse_tuples_list = \ tqc.TwoQubitClifford(idx).gate_decomposition pulse_tuples_list_all += pulse_tuples_list gproduct = qtp.tensor(qtp.identity(2), qtp.identity(2)) for i, cl_tup in enumerate(pulse_tuples_list_all): if cl_tup[0] == 'CZ': gproduct = self.standard_pulses[ cl_tup[0]] * gproduct else: eye_2qb = [qtp.identity(2), qtp.identity(2)] eye_2qb[int(cl_tup[1][-1])] = self.standard_pulses[ cl_tup[0]] gproduct = qtp.tensor(eye_2qb) * gproduct x = gproduct.full() / gproduct.full()[0][0] self.assertTrue( np.all((np.allclose(np.real(x), np.eye(4)), np.allclose(np.imag(x), np.zeros(4)))))
def upgrade_operator(self, child, operator, inverse, dt): i = self.children.index(child) self.state.dims = self.pure_answer.dims[:] upgraded = None if i == 0: upgraded = operator else: upgraded = qt.identity(self.state.dims[0][0]) for j in range(1, len(self.state.dims[0])): if j == i: upgraded = qt.tensor(upgraded, operator) else: upgraded = qt.tensor(upgraded, qt.identity(self.state.dims[0][j])) if self.parent != None: self.upgrade_operator(self, upgraded, inverse=inverse, dt=dt) else: unitary = (-2*math.pi*im()*dt*upgraded).expm() #self.state = unitary*self.state old_dims = self.pure_answer.dims[:] self.pure_answer.dims = self.state.dims self.pure_answer = unitary*self.pure_answer self.pure_answer.dims = old_dims for i in range(len(self.children)): self.children[i].propagate(self.state.ptrace(i))
def get_qutip_operator(model): blist = [] for i, ph1 in enumerate(model.ph_list): basis = [qutip.identity(2)] for j, ph2 in enumerate(model.ph_list): if j == i: state = qutip.destroy(ph1.n_phys_dim) else: state = qutip.identity(ph2.n_phys_dim) basis.append(state) blist.append(qutip.tensor(basis)) ph_iden = [qutip.identity(ph.n_phys_dim) for ph in model.ph_list] sigma_x = qutip.tensor([qutip.sigmax()] + ph_iden) sigma_z = qutip.tensor([qutip.sigmaz()] + ph_iden) terms = [model.delta * sigma_x, model.epsilon * sigma_z] for i, ph in enumerate(model.ph_list): g = ph.coupling_constant terms.append(ph.omega[0] * blist[i].dag() * blist[i]) terms.append(ph.omega[0] * g * sigma_z * (blist[i].dag() + blist[i])) H = sum(terms) return H, sigma_x, sigma_z
def _set_up_controls(self): """ Generate the Hamiltonians for the cavity-qed model and save them in the attribute `ctrls`. Parameters ---------- num_qubits: int The number of qubits in the system. """ controls = {} num_qubits = self.num_qubits num_levels = self.num_levels # single qubit terms for m in range(num_qubits): controls["sx" + str(m)] = (2 * np.pi * sigmax(), [m + 1]) for m in range(num_qubits): controls["sz" + str(m)] = (2 * np.pi * sigmaz(), [m + 1]) # coupling terms a = tensor( [destroy(num_levels)] + [identity(2) for n in range(num_qubits)] ) for n in range(num_qubits): # FIXME expanded? sm = tensor( [identity(num_levels)] + [ destroy(2) if m == n else identity(2) for m in range(num_qubits) ] ) controls["g" + str(n)] = ( 2 * np.pi * a.dag() * sm + 2 * np.pi * a * sm.dag(), list(range(num_qubits + 1)), ) return controls
def dephasing_single_qubit(rho,p,c): # apply dephasing to c'th qubit with parameter p of state rho # Create Kraus operators A_0 = np.sqrt(1-p)*qt.identity(2) A_1 = np.sqrt(p)*qt.Qobj([[1,0], [0,-1]]) # Collect Kraus operators kraus_terms = [A_0,A_1] # Apply Kraus operators to state rho rho_new = [] for ii in range(0,len(kraus_terms)): rho_new.append(apply_gate(rho,kraus_terms[ii],[c])) return sum(rho_new)
def eliminate_auxillary_modes(self, U): """ Eliminate the auxillary modes like the cavity modes in cqed. """ psi_proj = tensor( [basis(self.num_levels, 0)] + [identity(2) for n in range(self.num_qubits)] ) result = psi_proj.dag() * U * psi_proj # In qutip 5 multiplication of matrices # with dims [[1, 2], [2, 2]] and [[2, 2], [1, 2]] # will give a result of # dims [[1, 2], [1, 2]] instead of [[2], [2]]. if result.dims[0][0] == 1: result = result.ptrace(list(range(len(self.dims)))[1:]) return result
def pauli_basis(n): paulis = [qt.identity(2), qt.sigmax(), qt.sigmay(), qt.sigmaz()] names = ["".join(s) for s in product(["I", "X", "Y", "Z"], repeat=n)] P = [qt.tensor(*s) for s in product(paulis, repeat=n)] d = dict(zip(names, P)) sizes = dict([(name, name.count("I")) for name in names]) snames = sorted(zip(names, list(range(len(names)))), key=lambda x: x[0].count("I"), reverse=True) P2 = [P[sn[1]] for sn in snames] names2 = [sn[0] for sn in snames] starts = [0] now = names2[0].count("I") for i in range(len(names2)): if names2[i].count("I") != now: starts.append(i) now = names2[i].count("I") return names2, P2, d, dict(zip(list(range(len(starts))), starts))
def total_spin(self): old_dims = list(self.state.dims) n = collapser(self.dimensionality) self.state.dims = [[n], [n]] T = qutip.identity(n) X, Y, Z = qutip.jmat((n - 1.) / 2.) t = qutip.expect(T, self.state) x = qutip.expect(X, self.state) y = qutip.expect(Y, self.state) z = qutip.expect(Z, self.state) spin = np.array([t, x, y, z]) magnitude = np.linalg.norm(spin) if magnitude != 0: spin = spin / magnitude self.state.dims = old_dims return spin.tolist()
def embed(ops, L, indices): """ embeds local operators O at sites <indices> into the hilbert space of an L-site chain""" d = ops[0].dims[0][0] if len(ops[0].dims[0]) > 1: raise ValueError("operator O has tensor product structure") if len(ops) != len(indices): raise ValueError("number of ops does not match number of indices") ids = [qt.identity(d) for __ in range(L)] for i in range(len(ops)): o, site = ops[i], indices[i] if o.dims != ops[0].dims: raise ValueError("operator inputs have different dimension") ids[site] = o return qt.tensor(ids)
def _pseudo_inverse_dense(L, rhoss, w=None, **pseudo_args): """ Internal function for computing the pseudo inverse of an Liouvillian using dense matrix methods. See pseudo_inverse for details. """ rho_vec = np.transpose(mat2vec(rhoss.full())) tr_mat = tensor([identity(n) for n in L.dims[0][0]]) tr_vec = np.transpose(mat2vec(tr_mat.full())) N = np.prod(L.dims[0][0]) I = np.identity(N * N) P = np.kron(np.transpose(rho_vec), tr_vec) Q = I - P if w is None: L = L else: L = 1.0j*w*spre(tr_mat)+L if pseudo_args['method'] == 'direct': try: LIQ = np.linalg.solve(L.full(), Q) except: LIQ = np.linalg.lstsq(L.full(), Q)[0] R = np.dot(Q, LIQ) return Qobj(R, dims=L.dims) elif pseudo_args['method'] == 'numpy': return Qobj(np.dot(Q, np.dot(np.linalg.pinv(L.full()), Q)), dims=L.dims) elif pseudo_args['method'] == 'scipy': # return Qobj(la.pinv(L.full()), dims=L.dims) return Qobj(np.dot(Q, np.dot(la.pinv(L.full()), Q)), dims=L.dims) elif pseudo_args['method'] == 'scipy2': # return Qobj(la.pinv2(L.full()), dims=L.dims) return Qobj(np.dot(Q, np.dot(la.pinv2(L.full()), Q)), dims=L.dims) else: raise ValueError("Unsupported method '%s'. Use 'direct' or 'numpy'" % method)
def from_majorana_basis(op, m): op = op.full().T[0] N = len(m) c = 0 terms = [] for n in range(N + 1): if n == 0: terms.append(op[c] * qt.identity(m[0].shape[0])) terms[-1].dims = m[0].dims c += 1 else: for pr in combinations(list(range(N)), n): s = reduce(lambda x, y: x * y, [m[p] for p in pr]) terms.append(op[c] * s) terms[-1].dims = m[0].dims c += 1 return sum(terms)
def test_coherent_noise(self): """ Test for pulse genration with coherent noise. """ coeff = np.array([0.1, 0.2, 0.3, 0.4]) tlist = np.array([0., 1., 2., 3.]) ham = sigmaz() pulse1 = Pulse(ham, 1, tlist, coeff) # Add coherent noise with the same tlist pulse1.add_coherent_noise(sigmay(), 0, tlist, coeff) assert_allclose( pulse1.get_ideal_qobjevo(2)(0).full(), tensor(identity(2), sigmaz()).full() * 0.1) assert_(len(pulse1.coherent_noise) == 1) noise_qu, c_ops = pulse1.get_noisy_qobjevo(2) assert_allclose(c_ops, []) assert_allclose(pulse1.get_full_tlist(), np.array([0., 1., 2., 3.]))
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 create_dataset(n_samples): """Create dataset. Parameters: n_samples(int): Number of samples Output: _states(list): States associated with each set of measurements. _measurements(list): Measurements. _labels(list): Label associated with each set of measurements. """ _states = [] _labels = [] _measurements = [] #Basis Measured name_basis = ['I', 'X', 'Y', 'Z'] basis = [qutip.identity(2), qutip.sigmax(),qutip.sigmay(),qutip.sigmaz()] for _ in range(n_samples): density = qutip.rand_dm(4, density=0.75, dims=[[2,2],[2,2]]) #Partial Transpose density_partial_T = qutip.partial_transpose(density, [0,1]) #Labels: 1 if entangled 0 if separable (PPT Criterion) if (density_partial_T.eigenenergies() < 0).any(): _labels.append(1) else: _labels.append(-1) _states.append(density) val_measurements = measurement(density_matrix=density, base=basis, name_base=name_basis) _measurements.append(val_measurements) return _states, _measurements, _labels
def upgradeOperator(operator, i): operator = qutip.Qobj(operator) total_operator = None if i == 0: total_operator = qutip.tensor(operator, qutip.identity(2), qutip.identity(2)) elif i == 1: total_operator = qutip.tensor(qutip.identity(2), operator, qutip.identity(2)) elif i == 2: total_operator = qutip.tensor(qutip.identity(2), qutip.identity(2), operator) return total_operator.full()
def get_2site_std(): """ How to produce the standard data of the test_2site method """ import qutip import numpy as np from matplotlib import pyplot as plt ph_levels = 2 init_state = qutip.tensor(qutip.basis(2, 1), qutip.basis(2, 0), qutip.basis(ph_levels, 0), qutip.basis(ph_levels, 0)) c1 = qutip.tensor([qutip.destroy(2), qutip.identity(ph_levels), qutip.identity(2), qutip.identity(ph_levels)]) c2 = qutip.tensor([qutip.identity(2), qutip.identity(ph_levels), qutip.destroy(2), qutip.identity(ph_levels)]) b1 = qutip.tensor([qutip.identity(2), qutip.destroy(ph_levels), qutip.identity(2), qutip.identity(ph_levels)]) b2 = qutip.tensor([qutip.identity(2), qutip.identity(ph_levels), qutip.identity(2), qutip.destroy(ph_levels)]) J = 1 omega = 1 g = -0.707 lam = g ** 2 * omega H = J * c1.dag() * c2 + J * c1 * c2.dag() + lam * c1.dag() * c1 + lam * c2.dag() * c2 + omega * b1.dag() * b1 + omega * b2.dag() * b2 + omega * g * c1.dag() * c1 * ( b1.dag() + b1) + omega * g * c2.dag() * c2 * (b2.dag() + b2) projectors = [b1, b2] result = qutip.mesolve(H, init_state, np.linspace(0, 20, 101), c_ops=projectors, e_ops=[c1.dag() * c1, c2.dag() * c2, b1.dag() * b1, b2.dag() * b2, H]) qutip.plot_expectation_values(result) plt.show()
def partial_trace_kraus(keep, dims): r""" Constructs the Kraus map corresponding to the partial trace. Takes `keep` which is a single index or list of indices denoting subsystems to keep, and a list `dims` of dimensions of the overall tensor product Hilbert space. For illustration, to trace over the $i^{th}$ subsystem of $n$, one would construct Kraus operators: $$ \hat{K}_{i} = I^{\otimes i - 1} \otimes \langle i \mid \otimes I^{\otimes n - i}$$. """ if type(keep) == int: keep = [keep] trace_over = [i for i in range(len(dims)) if i not in keep] indices = [{trace_over[0]:t} for t in range(dims[trace_over[0]])] for i in trace_over[1:]: new_indices = [] for t in range(dims[i]): new_indices.extend([{**j, **{i: t}} for j in indices]) indices = new_indices return [qt.tensor(*[qt.identity(d) if i in keep else qt.basis(d, index[i]).dag() for i, d in enumerate(dims)]) for index in indices]
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 testLiouvillianImplem(self): """ Superoperator: Randomized comparison of standard and reference Liouvillian functions. """ N1 = 3 N2 = 4 N3 = 5 a1 = tensor(rand_dm(N1, density=0.75), identity(N2), identity(N3)) a2 = tensor(identity(N1), rand_dm(N2, density=0.75), identity(N3)) a3 = tensor(identity(N1), identity(N2), rand_dm(N3, density=0.75)) H = a1.dag() * a1 + a2.dag() * a2 + a3.dag() * a3 c_ops = [np.sqrt(0.01) * a1, np.sqrt(0.025) * a2, np.sqrt(0.05) * a3] L1 = liouvillian(H, c_ops) L2 = liouvillian_ref(H, c_ops) assert_((L1 - L2).norm('max') < 1e-8)
from qutip import Qobj, identity, sigmax, sigmay, sigmaz, tensor import qutip.logging_utils as logging logger = logging.get_logger() #QuTiP control modules import qutip.control.pulseoptim as cpo import qutip.control.pulsegen as pulsegen from qutip.qip.algorithms import qft example_name = 'QFT-dump' log_level=logging.INFO # **************************************************************** # 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)) 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))
def test_qeye_type(): "Operator CSR Type: qeye/identity" op = qeye(5) assert_equal(isspmatrix_csr(op.data), True) op = identity(5) assert_equal(isspmatrix_csr(op.data), True)
def __init__(self, N, correct_global_phase=True, Nres=None, deltamax=None, epsmax=None, w0=None, eps=None, delta=None, g=None): """ Parameters ---------- Nres: Integer The number of energy levels in the resonator. deltamax: Integer/List The sigma-x coefficient for each of the qubits in the system. epsmax: Integer/List The sigma-z coefficient for each of the qubits in the system. wo: Integer The base frequency of the resonator. eps: Integer/List The epsilon for each of the qubits in the system. delta: Integer/List The epsilon for each of the qubits in the system. g: Integer/List The interaction strength for each of the qubit with the resonator. """ super(DispersivecQED, self).__init__(N, correct_global_phase) # user definable if Nres is None: self.Nres = 10 else: self.Nres = Nres if deltamax is None: self.sx_coeff = np.array([1.0 * 2 * np.pi] * N) elif not isinstance(deltamax, list): self.sx_coeff = np.array([deltamax * 2 * np.pi] * N) else: self.sx_coeff = np.array(deltamax) if epsmax is None: self.sz_coeff = np.array([9.5 * 2 * np.pi] * N) elif not isinstance(epsmax, list): self.sz_coeff = np.array([epsmax * 2 * np.pi] * N) else: self.sz_coeff = np.array(epsmax) if w0 is None: self.w0 = 10 * 2 * np.pi else: self.w0 = w0 if eps is None: self.eps = np.array([9.5 * 2 * np.pi] * N) elif not isinstance(eps, list): self.eps = np.array([eps * 2 * np.pi] * N) else: self.eps = np.array(eps) if delta is None: self.delta = np.array([0.0 * 2 * np.pi] * N) elif not isinstance(delta, list): self.delta = np.array([delta * 2 * np.pi] * N) else: self.delta = np.array(delta) if g is None: self.g = np.array([0.01 * 2 * np.pi] * N) elif not isinstance(g, list): self.g = np.array([g * 2 * np.pi] * N) else: self.g = np.array(g) # computed self.wq = np.sqrt(self.eps ** 2 + self.delta ** 2) self.Delta = self.wq - self.w0 # rwa/dispersive regime tests if any(self.g / (self.w0 - self.wq) > 0.05): warnings.warn("Not in the dispersive regime") if any((self.w0 - self.wq) / (self.w0 + self.wq) > 0.05): warnings.warn( "The rotating-wave approximation might not be valid.") self.sx_ops = [tensor([identity(self.Nres)] + [sigmax() if m == n else identity(2) for n in range(N)]) for m in range(N)] self.sz_ops = [tensor([identity(self.Nres)] + [sigmaz() if m == n else identity(2) for n in range(N)]) for m in range(N)] self.a = tensor([destroy(self.Nres)] + [identity(2) for n in range(N)]) self.cavityqubit_ops = [] for n in range(N): sm = tensor([identity(self.Nres)] + [destroy(2) if m == n else identity(2) for m in range(N)]) self.cavityqubit_ops.append(self.a.dag() * sm + self.a * sm.dag()) self.psi_proj = tensor([basis(self.Nres, 0)] + [identity(2) for n in range(N)])