def single_hamiltonian(cav_dim, w_1, w_c, g_factor): """Return a QObj denoting a hamiltonian for one qubit coupled to a cavity.""" return (w_c * qt.tensor(qt.num(cav_dim), I) + 0.5 * w_1 * qt.tensor(qt.qeye(cav_dim), I) + g_factor * qt.tensor(qt.create(cav_dim), SMinus) + g_factor * qt.tensor(qt.destroy(cav_dim), SPlus))
def steady(N = 20): # number of basis states to consider n=num(N) a = destroy(N) H = a.dag() * a print H.eigenstates() #psi0 = basis(N, 10) # initial state kappa = 0.1 # coupling to oscillator c_op_list = [] n_th_a = 2 # temperature with average of 2 excitations rate = kappa * (1 + n_th_a) c_op_list.append(sqrt(rate) * a) # decay operators rate = kappa * n_th_a c_op_list.append(sqrt(rate) * a.dag()) # excitation operators final_state = steadystate(H, c_op_list) fexpt = expect(a.dag() * a, final_state) #tlist = linspace(0, 100, 100) #mcdata = mcsolve(H, psi0, tlist, c_op_list, [a.dag() * a], ntraj=100) #medata = mesolve(H, psi0, tlist, c_op_list, [a.dag() * a]) #plot(tlist, mcdata.expect[0], #plt.plot(tlist, medata.expect[0], lw=2) plt.axhline(y=fexpt, color='r', lw=1.5) # ss expt. value as horiz line (= 2) plt.ylim([0, 10]) plt.show()
def test_num(): "Number operator" n5 = num(5) assert_equal( np.allclose(n5.full(), np.diag([0 + 0j, 1 + 0j, 2 + 0j, 3 + 0j, 4 + 0j])), True)
def to_matrix(self, fd): n = num(fd) a = destroy(fd) ic = qeye(fd) sz = sigmaz() sm = sigmam() iq = qeye(2) ms = { "id": tensor(iq, ic), "a*ad" : tensor(iq, n), "a+hc" : tensor(iq, a), "sz" : tensor(sz, ic), "sm+hc" : tensor(sm, ic) } H0 = 0 H1s = [] for (p1, p2), v in self.coefs.items(): h = ms[p1] * ms[p2] try: term = float(v) * h if not term.isherm: term += term.dag() H0 += term except ValueError: H1s.append([h, v]) if not h.isherm: replacement = lambda m: '(-' + m.group() + ')' conj_v = re.sub('[1-9]+j', replacement, v) H1s.append([h.dag(), conj_v]) if H1s: return [H0] + H1s else: return H0
def testFloquetUnitary(self): """ Floquet: test unitary evolution of time-dependent two-level system """ delta = 1.0 * 2 * np.pi eps0 = 1.0 * 2 * np.pi A = 0.5 * 2 * np.pi omega = np.sqrt(delta ** 2 + eps0 ** 2) T = (2 * np.pi) / omega tlist = np.linspace(0.0, 2 * T, 101) psi0 = rand_ket(2) H0 = - eps0 / 2.0 * sigmaz() - delta / 2.0 * sigmax() H1 = A / 2.0 * sigmax() args = {'w': omega} H = [H0, [H1, lambda t, args: np.sin(args['w'] * t)]] e_ops = [num(2)] # solve schrodinger equation with floquet solver sol = fsesolve(H, psi0, tlist, e_ops, T, args) # compare with results from standard schrodinger equation sol_ref = mesolve(H, psi0, tlist, [], e_ops, args) assert_(max(abs(sol.expect[0] - sol_ref.expect[0])) < 1e-4)
def testMETDDecayAsPartFuncList(self): "mesolve: time-dependence as partial function list" me_error = 1e-5 N = 10 a = destroy(N) H = num(N) psi0 = basis(N, 9) tlist = np.linspace(0, 10, 100) c_ops = [[[a, partial(lambda t, args, k: np.sqrt(k * np.exp(-t)), k=kappa)]] for kappa in [0.05, 0.1, 0.2]] for idx, kappa in enumerate([0.05, 0.1, 0.2]): medata = mesolve(H, psi0, tlist, c_ops[idx], [H]) ref = 9.0 * np.exp(-kappa * (1.0 - np.exp(-tlist))) avg_diff = np.mean(abs(ref - medata.expect[0]) / ref) assert_(avg_diff < me_error)
def parse_states(self,results): steps = len(results) qubit_indices,cav_index = parse_dims(self.dims) cavity_sim = cav_index is not None if cavity_sim: n = qt.num(self.dims[cav_index]) bloch_vectors = np.zeros((steps,len(qubit_indices),3)) ns = np.zeros(steps) for i in range(steps): if results[i].type != 'oper': dm = qt.ket2dm(results[i]) else: dm = results[i] bloch_vectors[i] = [measure_qubit(dm.ptrace(int(j))) for j in qubit_indices] if cavity_sim: ns[i] = np.real((n*dm.ptrace(cav_index)).tr()) return bloch_vectors,ns
def testMETDDecayAsPartFuncList(self): "mesolve: time-dep. as partial function list with super as init cond" me_error = 1e-5 N = 10 a = destroy(N) H = num(N) psi0 = basis(N, 9) rho0vec = operator_to_vector(psi0 * psi0.dag()) E0 = sprepost(qeye(N), qeye(N)) tlist = np.linspace(0, 10, 100) c_ops = [[[a, partial(lambda t, args, k: np.sqrt(k * np.exp(-t)), k=kappa)]] for kappa in [0.05, 0.1, 0.2]] for idx, kappa in enumerate([0.05, 0.1, 0.2]): out1 = mesolve(H, psi0, tlist, c_ops[idx], []) out2 = mesolve(H, E0, tlist, c_ops[idx], []) fid = self.fidelitycheck(out1, out2, rho0vec) assert_(max(abs(1.0 - fid)) < me_error, True)
def test_SparseHermValsVecs(): """ Sparse eigs Hermitian """ # check using number operator N = num(10) spvals, spvecs = N.eigenstates(sparse=True) for k in range(10): # check that eigvals are in proper order assert_equal(abs(spvals[k] - k) <= 1e-13, True) # check that eigenvectors are right and in right order assert_equal(abs(expect(N, spvecs[k]) - spvals[k]) < 5e-14, True) # check ouput of only a few eigenvals/vecs spvals, spvecs = N.eigenstates(sparse=True, eigvals=7) assert_equal(len(spvals), 7) assert_equal(spvals[0] <= spvals[-1], True) for k in range(7): assert_equal(abs(spvals[k] - k) < 1e-12, True) spvals, spvecs = N.eigenstates(sparse=True, sort='high', eigvals=5) assert_equal(len(spvals), 5) assert_equal(spvals[0] >= spvals[-1], True) vals = np.arange(9, 4, -1) for k in range(5): # check that eigvals are ordered from high to low assert_equal(abs(spvals[k] - vals[k]) < 5e-14, True) assert_equal(abs(expect(N, spvecs[k]) - vals[k]) < 1e-14, True) # check using random Hermitian H = rand_herm(10) spvals, spvecs = H.eigenstates(sparse=True) # check that sorting is lowest eigval first assert_equal(spvals[0] <= spvals[-1], True) # check that spvals equal expect vals for k in range(10): assert_equal(abs(expect(H, spvecs[k]) - spvals[k]) < 5e-14, True) # check that ouput is real for Hermitian operator assert_equal(np.isreal(spvals[k]), True)
def SurfaceXYZ_q(XYZ): return qt.Qobj(C_v([xyz_c(xyz) for xyz in XYZ])) ################################################################################################################## dt = 0.0001 modes = 2 freq = 1 a = qt.destroy(modes) aX = qt.tensor(qt.destroy(modes), qt.identity(modes), qt.identity(modes)) nX = qt.tensor(qt.num(modes), qt.identity(modes), qt.identity(modes)) xX = qt.tensor((qt.destroy(modes) + qt.destroy(modes).dag()) / np.sqrt(2), qt.identity(modes), qt.identity(modes)) pX = qt.tensor( -1j * (qt.destroy(modes) - qt.destroy(modes).dag()) / np.sqrt(2), qt.identity(modes), qt.identity(modes)) aY = qt.tensor(qt.identity(modes), qt.destroy(modes), qt.identity(modes)) nY = qt.tensor(qt.identity(modes), qt.num(modes), qt.identity(modes)) xY = qt.tensor(qt.identity(modes), (qt.destroy(modes) + qt.destroy(modes).dag()) / np.sqrt(2), qt.identity(modes)) pY = qt.tensor( qt.identity(modes), -1j * (qt.destroy(modes) - qt.destroy(modes).dag()) / np.sqrt(2), qt.identity(modes))
def number_operator(self): return qt.num(self.dim)
def h_sho(dim): U = rand_unitary_haar(dim) H = U * (num(dim) + 0.5) * U.dag() H = H / np.linalg.norm(H.full(), ord=2) return H
def test_num_type(): "Operator CSR Type: num" op = num(5) assert_equal(isspmatrix_csr(op.data), True)
self.vtag.visible = self.show_tag for vtag in self.vtags: vtag.visible = self.show_tag_on_stars def field_state(self): XYZ = q_SurfaceXYZ(self.state) qubits = [SurfaceXYZ_q([xyz]) for xyz in XYZ] return symmeterize(qubits) dt = 0.0001 modes = 20 freq = 1 a = qt.destroy(modes) n = qt.num(modes) x = (a + a.dag()) / np.sqrt(2) p = -1j * (a - a.dag()) / np.sqrt(2) H = 2 * np.pi * freq * a.dag() * a state = qt.rand_ket(modes) vp.scene.height = 800 vp.scene.wdith = 800 sphere = vp.sphere(radius=0.5, opacity=0.7) x_axis = vp.arrow(pos=vp.vector(0, 0, 0), axis=vp.vector(1, 0, 0)) y_axis = vp.arrow(pos=vp.vector(0, 0, 0), axis=vp.vector(0, 1, 0)) y_axis = vp.arrow(pos=vp.vector(0, 0, 0), axis=vp.vector(0, 0, 1))
N=5 print charge(5) print tunneling(5) print Qobj(sp.eye(N, N, 1, dtype=complex, format='csr'), isherm=False) print Qobj(sp.spdiags(1, 1, N, N, format='csr'), isherm=False) #E_J = E_J_max*cos(pi*phi) # Josephson energy as function of Phi. #wT_vec = -E_J + sqrt(8.0*E_J*E_C)*(Nt_vec+0.5)-E_C*(6*Nt_vec**2+6*Nt_vec+3)/12.0 #N_gamma=1.0/(exp(hbar*w0/(k*T))-1.0) #print N_gamma #print 1/(exp(f0/1.0e6/21000.0/T)-1) #gamma=50.0e6 print num(9, -4) N=3 n=num(2*N+1, -N) print n print destroy(2*N+1, -N) def steady(N = 20): # number of basis states to consider n=num(N) a = destroy(N) H = a.dag() * a print H.eigenstates() #psi0 = basis(N, 10) # initial state kappa = 0.1 # coupling to oscillator c_op_list = [] n_th_a = 2 # temperature with average of 2 excitations
f_energies, np.linspace(0, T, 500 + 1), H, T, args, ) # solve the floquet-markov master equation output = qutip.fmmesolve(H, psi0, tlist, [qutip.sigmax()], [], [noise_spectrum], T, args) # calculate expectation values in the computational basis p_ex = np.zeros(tlist.shape, dtype=np.complex128) for idx, t in enumerate(tlist): f_modes_t = qutip.floquet_modes_t_lookup(f_modes_table_t, t, T) p_ex[idx] = qutip.expect(qutip.num(2), output.states[idx].transform(f_modes_t, True)) # For reference: calculate the same thing with mesolve output = qutip.mesolve(H, psi0, tlist, [np.sqrt(gamma1) * qutip.sigmax()], [qutip.num(2)], args) p_ex_ref = output.expect[0] # plot the results pyplot.plot(tlist, np.real(p_ex), 'r--', tlist, 1 - np.real(p_ex), 'b--') pyplot.plot(tlist, np.real(p_ex_ref), 'r', tlist, 1 - np.real(p_ex_ref), 'b') pyplot.xlabel('Time') pyplot.ylabel('Occupation probability') pyplot.legend( ("Floquet $P_1$", "Floquet $P_0$", "Lindblad $P_1$", "Lindblad $P_0$")) pyplot.show()
def black_box_hamiltonian(fs, ljs, fzpfs, cos_trunc=5, fock_trunc=8, individual=False, non_linear_potential=None): r""" :param fs: Linearized model, H_lin, normal mode frequencies in Hz, length N :param ljs: junction linerized inductances in Henries, length M :param fzpfs: Zero-point fluctutation of the junction fluxes for each mode across each junction, shape MxJ :return: Hamiltonian in units of Hz (i.e H / h) All in SI units. The ZPF fed in are the generalized, not reduced, flux. Description: Takes the linear mode frequencies, $\omega_m$, and the zero-point fluctuations, ZPFs, and builds the Hamiltonian matrix of $H_full$, assuming cos potential. """ n_modes = len(fs) njuncs = len(ljs) fs, ljs, fzpfs = map(np.array, (fs, ljs, fzpfs)) ejs = fluxQ**2 / ljs fjs = ejs / h fzpfs = np.transpose(fzpfs) # Take from MxJ to JxM assert np.isnan(fzpfs).any( ) == False, "Phi ZPF has NAN, this is NOT allowed! Fix me. \n%s" % fzpfs assert np.isnan( ljs).any() == False, "Ljs has NAN, this is NOT allowed! Fix me." assert np.isnan( fs).any() == False, "freqs has NAN, this is NOT allowed! Fix me." assert fzpfs.shape == ( njuncs, n_modes), "incorrect shape for zpf array, {} not {}".format( fzpfs.shape, (njuncs, n_modes)) assert fs.shape == (n_modes, ), "incorrect number of mode frequencies" assert ejs.shape == (njuncs, ), "incorrect number of qubit frequencies" def tensor_out(op, loc): "Make operator <op> tensored with identities at locations other than <loc>" op_list = [qutip.qeye(fock_trunc) for i in range(n_modes)] op_list[loc] = op return reduce(qutip.tensor, op_list) a = qutip.destroy(fock_trunc) ad = a.dag() n = qutip.num(fock_trunc) mode_fields = [tensor_out(a + ad, i) for i in range(n_modes)] mode_ns = [tensor_out(n, i) for i in range(n_modes)] def cos(x): return cos_approx(x, cos_trunc=cos_trunc) if non_linear_potential is None: non_linear_potential = cos linear_part = dot(fs, mode_ns) cos_interiors = [dot(fzpf_row / fluxQ, mode_fields) for fzpf_row in fzpfs] nonlinear_part = dot(-fjs, map(non_linear_potential, cos_interiors)) if individual: return linear_part, nonlinear_part else: return linear_part + nonlinear_part
out = out[0] return out def _case_id(case): op_part = 'qubit' if _unwrap(case.operator).dims[0][0] == 2 else 'basis' state_part = 'ket' if _unwrap(case.state).dims[1][0] == 1 else 'dm' return op_part + "-" + state_part # This is the minimal set of test cases, with a Fock system and a qubit system # both in ket form and dm form. The reference expectations are a 2D array # which would be found by broadcasting `operator` against `state` and applying # `qutip.expect` to the pairs. _dim = 5 _num, _a = qutip.num(_dim), qutip.destroy(_dim) _sx, _sz, _sp = qutip.sigmax(), qutip.sigmaz(), qutip.sigmap() _known_fock = _Case([_num, _a], [qutip.fock(_dim, n) for n in range(_dim)], np.array([np.arange(_dim), np.zeros(_dim)])) _known_qubit = _Case([_sx, _sz, _sp], [qutip.basis(2, 0), qutip.basis(2, 1)], np.array([[0, 0], [1, -1], [0, 0]])) _known_cases = [ _known_fock, _case_to_dm(_known_fock), _known_qubit, _case_to_dm(_known_qubit) ] class TestKnownExpectation: def pytest_generate_tests(self, metafunc):
def build_position_SHO(dim, power, zeta): if power == 1: op = sqrt(zeta / 2) * (create(dim) + destroy(dim)) elif power == 2: op = zeta / 2 * (create(dim)**2 + destroy(dim)**2 + 2 * num(dim) + 1) return op
def propagate(self, ancilla_dim, N, M): n = qt.num(ancilla_dim) return [(-1j * np.pi * k / (N * M) * n).expm() for k in range(len(self.kraus))]
import qutip as q import numpy as np from scipy import integrate as ig import matplotlib.pyplot as plt import decompose as dcp import scipy.optimize as opt import scipy.linalg as lin import scipy.misc as misc plt.rc('axes', labelsize=14) warnings = False N = 2 H = q.num(N, 1) #nss=0.5 #H = q.Qobj(np.diag([0,2,4])) def max_coherent(k): if (k == 0 or k > N): raise ValueError('Parameter k must satisfy 1 <= k <= N') state = q.basis(N, 0) for i in range(1, k): state += q.basis(N, i) return state * 1. / np.sqrt(k) def mixed_state(coeff, s): if (s < 0 or s > 1): raise ValueError('Parameter s must satisfy 0 <= k <= 1') identity = q.Qobj(
H0 = -delta / 2.0 * qutip.sigmax() - eps0 / 2.0 * qutip.sigmaz() H1 = A / 2.0 * qutip.sigmaz() args = {'w': omega} H = [H0, [H1, lambda t, args: np.sin(args['w'] * t)]] # find the floquet modes for the time-dependent hamiltonian f_modes_0, f_energies = qutip.floquet_modes(H, T, args) # decompose the inital state in the floquet modes f_coeff = qutip.floquet_state_decomposition(f_modes_0, f_energies, psi0) # calculate the wavefunctions using the from the floquet modes p_ex = np.zeros(len(tlist)) for n, t in enumerate(tlist): psi_t = qutip.floquet_wavefunction_t(f_modes_0, f_energies, f_coeff, t, H, T, args) p_ex[n] = qutip.expect(qutip.num(2), psi_t) # For reference: calculate the same thing with mesolve p_ex_ref = qutip.mesolve(H, psi0, tlist, [], [qutip.num(2)], args).expect[0] # plot the results pyplot.plot(tlist, np.real(p_ex), 'ro', tlist, 1 - np.real(p_ex), 'bo') pyplot.plot(tlist, np.real(p_ex_ref), 'r', tlist, 1 - np.real(p_ex_ref), 'b') pyplot.xlabel('Time') pyplot.ylabel('Occupation probability') pyplot.legend( ("Floquet $P_1$", "Floquet $P_0$", "Lindblad $P_1$", "Lindblad $P_0$")) pyplot.show()
def keyboard(self, event): key = event.key spin_ops = self.spin_operators() if key == "a": self.evolve(spin_ops['X'], inverse=True, dt=0.01) elif key == "d": self.evolve(spin_ops['X'], inverse=False, dt=0.01) elif key == "s": self.evolve(spin_ops['Z'], inverse=True, dt=0.01) elif key == "w": self.evolve(spin_ops['Z'], inverse=False, dt=0.01) elif key == "z": self.evolve(spin_ops['Y'], inverse=True, dt=0.01) elif key == "x": self.evolve(spin_ops['Y'], inverse=False, dt=0.01) elif key == "e": if self.evolving: self.evolving = False else: self.evolving = True elif key == "r": self.state = qt.rand_ket(self.n) elif key == "t": self.energy = qt.rand_herm(self.n) elif key == "y": aX = qt.tensor(qt.destroy(modes), qt.identity(modes), qt.identity(modes)) nX = qt.tensor(qt.num(modes), qt.identity(modes), qt.identity(modes)) xX = qt.tensor((aX + aX.dag()) / np.sqrt(2), qt.identity(modes), qt.identity(modes)) pX = qt.tensor(-1j * (aX - aX.dag()) / np.sqrt(2), qt.identity(modes), qt.identity(modes)) aY = qt.tensor(qt.identity(modes), qt.destroy(modes), qt.identity(modes)) nY = qt.tensor(qt.identity(modes), qt.num(modes), qt.identity(modes)) xY = qt.tensor(qt.identity(modes), (aY + aY.dag()) / np.sqrt(2), qt.identity(modes)) pY = qt.tensor(qt.identity(modes), -1j * (aY - aY.dag()) / np.sqrt(2), qt.identity(modes)) aZ = qt.tensor(qt.identity(modes), qt.identity(modes), qt.destroy(modes)) nZ = qt.tensor(qt.identity(modes), qt.identity(modes), qt.num(modes)) xZ = qt.tensor(qt.identity(modes), qt.identity(modes), (aZ + aZ.dag()) / np.sqrt(2)) pZ = qt.tensor(qt.identity(modes), qt.identity(modes), -1j * (aZ - aZ.dag()) / np.sqrt(2)) H = 2 * np.pi * freq * ((aX.dag() * aX + 0.5)+\ (aY.dag() * aY + 0.5)+\ (aZ.dag() * aZ + 0.5)) self.energy = H elif key == "[": self.dt += 0.001 elif key == "]": self.dt -= 0.001
def e_ops(t, psi): return expect(num(dim), psi) if not square_hamiltonian:
import qutip as qt import numpy as np import vpython as vp vp.scene.width = 1000 vp.scene.height = 800 dt = 0.001 n = 101 a = qt.destroy(n) Q = qt.position(n) QL, QV = Q.eigenstates() N = qt.num(n) NL, NV = N.eigenstates() H = N + 1 / 2 U = (-1j * dt * H).expm() def coherent(s): global n, a return np.exp(-s * np.conjugate(s) / 2) * (s * a.dag()).expm() * ( -np.conjugate(s) * a).expm() * qt.basis(n, 0) state = qt.basis(n, 0) amps = [state.overlap(v) for v in QV] vamps = [vp.arrow(pos=vp.vector(QL[i], 0, 0),\ axis=vp.vector(amps[i].real, amps[i].imag, 0)) for i in range(n)] vprobs = [vp.sphere(radius=0.1, color=vp.color.red,\ pos=vp.vector(QL[i], 1+3*(amps[i]*np.conjugate(amps[i])).real, 0))\ for i in range(n)] vexp = vp.sphere(color=vp.color.yellow, radius=0.3,\
def e_ops(t, psi): return expect(num(dim), psi) tlist = np.linspace(0, 20, 200)
def test_num(self): npt.assert_array_equal(num(self.N), qt.num(self.N))
def U_kerr(t, dim, params, **kwargs): H = ham_kerr(dim, params, **kwargs) return linalg.expm(-1j*H*t) def U_parity(t, dim, params): H = ham_parity(dim, params) return linalg.expm(-1j*H*t) ''' Calculations ''' if 0: # qutip diagonalization H = qt.num(dim) - 0.5*a*(qt.displace(dim,1j*x) + qt.displace(dim,-1j*x)) ev = H.eigenenergies() if 1: # plot fig, ax = plt.subplots() ax.plot(range(dim-1),ev[1:]-ev[:-1],'o') ax.plot(range(dim-1),ev[1:]-ev[:-1]) ax.set_xlim(0,4*x) if 0: # manual diagonalization H = ham(dim, params) ev, ek = linalg.eigh(H) if 1: # plot fig, ax = plt.subplots() ax.plot(range(dim-1),ev[1:]-ev[:-1],'o')