def test_diagHamiltonian2(): """ Diagonalization of composite systems """ H1 = scipy.rand() * sigmax() + scipy.rand() * sigmay() +\ scipy.rand() * sigmaz() H2 = scipy.rand() * sigmax() + scipy.rand() * sigmay() +\ scipy.rand() * sigmaz() H = tensor(H1, H2) evals, ekets = H.eigenstates() for n in range(len(evals)): # assert that max(H * ket - e * ket) is small assert_equal(amax( abs((H * ekets[n] - evals[n] * ekets[n]).full())) < 1e-10, True) N1 = 10 N2 = 2 a1 = tensor(destroy(N1), qeye(N2)) a2 = tensor(qeye(N1), destroy(N2)) H = scipy.rand() * a1.dag() * a1 + scipy.rand() * a2.dag() * a2 + \ scipy.rand() * (a1 + a1.dag()) * (a2 + a2.dag()) evals, ekets = H.eigenstates() for n in range(len(evals)): # assert that max(H * ket - e * ket) is small assert_equal(amax( abs((H * ekets[n] - evals[n] * ekets[n]).full())) < 1e-10, True)
def carrier_flop(rho0, W, eta, delta, theta, phi, c_op_list = [], return_op_list = []): ''' Return values of atom and motion populations during carrier Rabi flop for rotation angles theta. Calls numerical solution of master equation. @ var rho0: initial density matrix @ var W: bare Rabi frequency @ var eta: Lamb-Dicke parameter @ var delta: detuning between atom and motion @ var theta: list of Rabi rotation angles (i.e. theta, or g*time) @ var phi: phase of the input laser pulse @ var c_op_list: list of collapse operators for the master equation treatment @ var return_op_list: list of population operators the values of which will be returned returns: time, populations of motional mode and atom ''' N = shape(rho0.data)[0]/2 # assume N Fock states and two atom states a = tensor(destroy(N), qeye(2)) Wc = qeye(N) Wc.data = csr_matrix( qeye(N).data.dot( np.diag(rabi_coupling(N,0,eta) ) ) ) sm = tensor( Wc, destroy(2)) # use the rotating wave approxiation H = delta * a.dag() * a + \ (1./2.)* W * (sm.dag()*exp(1j*phi) + sm*exp(-1j*phi)) if hasattr(theta, '__len__'): if len(theta)>1: # I need to be able to pass a list of length zero and not get an error time = theta/W else: time = theta/W output = mesolve(H, rho0, time, c_op_list, return_op_list) return time, output
def compute(N, wc, wa, glist, use_rwa): # Pre-compute operators for the hamiltonian a = tensor(destroy(N), qeye(2)) sm = tensor(qeye(N), destroy(2)) nc = a.dag() * a na = sm.dag() * sm idx = 0 na_expt = zeros(shape(glist)) nc_expt = zeros(shape(glist)) for g in glist: # recalculate the hamiltonian for each value of g if use_rwa: H = wc * nc + wa * na + g * (a.dag() * sm + a * sm.dag()) else: H = wc * nc + wa * na + g * (a.dag() + a) * (sm + sm.dag()) # find the groundstate of the composite system evals, ekets = H.eigenstates() psi_gnd = ekets[0] na_expt[idx] = expect(na, psi_gnd) nc_expt[idx] = expect(nc, psi_gnd) idx += 1 return nc_expt, na_expt, ket2dm(psi_gnd)
def rsb_flop(rho0, W, eta, delta, theta, phi, c_op_list = [], return_op_list = []): ''' Return values of atom and motion populations during red sideband Rabi flop for rotation angles theta. Calls numerical solution of master equation for the Jaynes-Cummings Hamiltonian. @ var rho0: initial density matrix @ var W: bare Rabi frequency @ var delta: detuning between atom and motion @ var theta: list of Rabi rotation angle (i.e. theta, or g*time) @ var phi: phase of the input laser pulse @ var c_op_list: list of collapse operators for the master equation treatment @ var return_op_list: list of population operators the values of which will be returned returns: time, populations of motional mode and atom ''' N = shape(rho0.data)[0]/2 # assume N Fock states and two atom states a = tensor(destroy(N), qeye(2)) sm = tensor( qeye(N), destroy(2)) Wrsb = destroy(N) one_then_zero = ([float(x<1) for x in range(N)]) Wrsb.data = csr_matrix( destroy(N).data.dot( np.diag( rabi_coupling(N,-1,eta) / np.sqrt(one_then_zero+np.linspace(0,N-1,N)) ) ) ) Arsb = tensor(Wrsb, qeye(2)) # use the rotating wave approxiation # Note that the regular a, a.dag() is used for the time evolution of the oscillator # Arsb is the destruction operator including the state dependent coupling strength H = delta * a.dag() * a + \ (1./2.) * W * (Arsb.dag() * sm * exp(1j*phi) + Arsb * sm.dag() * exp(-1j*phi)) if hasattr(theta, '__len__'): if len(theta)>1: # I need to be able to pass a list of length zero and not get an error time = theta/(eta*W) else: time = theta/(eta*W) output = mesolve(H, rho0, time, c_op_list, return_op_list) return time, output
def collapse_operators(N, n_th_a, gamma_motion, gamma_motion_phi, gamma_atom): '''Collapse operators for the master equation of a single atom and a harmonic oscillator @ var N: size of the harmonic oscillator Hilbert space @ var n_th: temperature of the noise bath in quanta @ var gamma_motion: heating rate of the motion @ var gamma_motion_phi: dephasing rate of the motion @ var gamma_atom: decay rate of the atom returns: list of collapse operators for master equation solution of atom + harmonic oscillator ''' a = tensor(destroy(N), qeye(2)) sm = tensor(qeye(N), destroy(2)) c_op_list = [] rate = gamma_motion * (1 + n_th_a) if rate > 0.0: c_op_list.append(sqrt(rate) * a) rate = gamma_motion * n_th_a if rate > 0.0: c_op_list.append(sqrt(rate) * a.dag()) rate = gamma_motion_phi if rate > 0.0: c_op_list.append(sqrt(rate) * a.dag() * a) rate = gamma_atom if rate > 0.0: c_op_list.append(sqrt(rate) * sm) return c_op_list
def test_spectrum_espi_legacy(): """ correlation: legacy spectrum from es and pi methods """ # use JC model N = 4 wc = wa = 1.0 * 2 * np.pi g = 0.1 * 2 * np.pi kappa = 0.75 gamma = 0.25 n_th = 0.01 a = tensor(destroy(N), qeye(2)) sm = tensor(qeye(N), destroy(2)) H = wc * a.dag() * a + wa * sm.dag() * sm + \ g * (a.dag() * sm + a * sm.dag()) c_ops = [np.sqrt(kappa * (1 + n_th)) * a, np.sqrt(kappa * n_th) * a.dag(), np.sqrt(gamma) * sm] wlist = 2 * np.pi * np.linspace(0.5, 1.5, 100) with warnings.catch_warnings(): warnings.simplefilter("ignore") spec1 = spectrum_ss(H, wlist, c_ops, a.dag(), a) spec2 = spectrum_pi(H, wlist, c_ops, a.dag(), a) assert_(max(abs(spec1 - spec2)) < 1e-3)
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_spectrum_esfft(): """ correlation: comparing spectrum from es and fft methods """ # use JC model N = 4 wc = wa = 1.0 * 2 * np.pi g = 0.1 * 2 * np.pi kappa = 0.75 gamma = 0.25 n_th = 0.01 a = tensor(destroy(N), qeye(2)) sm = tensor(qeye(N), destroy(2)) H = wc * a.dag() * a + wa * sm.dag() * sm + \ g * (a.dag() * sm + a * sm.dag()) c_ops = [np.sqrt(kappa * (1 + n_th)) * a, np.sqrt(kappa * n_th) * a.dag(), np.sqrt(gamma) * sm] with warnings.catch_warnings(): warnings.simplefilter("ignore") tlist = np.linspace(0, 100, 2500) corr = correlation_ss(H, tlist, c_ops, a.dag(), a) wlist1, spec1 = spectrum_correlation_fft(tlist, corr) spec2 = spectrum_ss(H, wlist1, c_ops, a.dag(), a) assert_(max(abs(spec1 - spec2)) < 1e-3)
def test_spectrum_espi(): """ correlation: comparing spectrum from es and pi methods """ # use JC model N = 4 wc = wa = 1.0 * 2 * np.pi g = 0.1 * 2 * np.pi kappa = 0.75 gamma = 0.25 n_th = 0.01 a = tensor(destroy(N), qeye(2)) sm = tensor(qeye(N), destroy(2)) H = wc * a.dag() * a + wa * sm.dag() * sm + \ g * (a.dag() * sm + a * sm.dag()) c_ops = [np.sqrt(kappa * (1 + n_th)) * a, np.sqrt(kappa * n_th) * a.dag(), np.sqrt(gamma) * sm] wlist = 2 * pi * np.linspace(0.5, 1.5, 100) spec1 = spectrum(H, wlist, c_ops, a.dag(), a, solver='es') spec2 = spectrum(H, wlist, c_ops, a.dag(), a, solver='pi') assert_(max(abs(spec1 - spec2)) < 1e-3)
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 __init__(self): N = 3 self.t1 = QobjEvo([qeye(N)*(1.+0.1j),[create(N)*(1.-0.1j),f]]) self.t2 = QobjEvo([destroy(N)*(1.-0.2j)]) self.t3 = QobjEvo([[destroy(N)*create(N)*(1.+0.2j),f]]) self.q1 = qeye(N)*(1.+0.3j) self.q2 = destroy(N)*(1.-0.3j) self.q3 = destroy(N)*create(N)*(1.+0.4j)
def population_operators(N): '''Population operators for the master equation @ var N: size of the oscillator Hilbert space returns: list of population operators for the harmonic oscillator and the atom ''' a = tensor(destroy(N), qeye(2)) sm = tensor( qeye(N), destroy(2)) return [a.dag()*a, sm.dag()*sm]
def test_destroy(): "Destruction operator" b4 = basis(5, 4) d5 = destroy(5) test1 = d5 * b4 assert_equal(np.allclose(test1.full(), 2.0 * basis(5, 3).full()), True) d3 = destroy(3) matrix3 = np.array([[0.00000000 + 0.j, 1.00000000 + 0.j, 0.00000000 + 0.j], [0.00000000 + 0.j, 0.00000000 + 0.j, 1.41421356 + 0.j], [0.00000000 + 0.j, 0.00000000 + 0.j, 0.00000000 + 0.j]]) assert_equal(np.allclose(matrix3, d3.full()), True)
def full_hamiltonian(cav_dim, w_1, w_2, w_c, g_1, g_2): """Return a QObj denoting the full Hamiltonian including cavity and two qubits""" a = qt.destroy(cav_dim) num = a.dag() * a return ( g_1 * qt.tensor(qt.create(cav_dim), SMinus, I) + g_1 * qt.tensor(qt.destroy(cav_dim), SPlus, I) + g_2 * qt.tensor(qt.create(cav_dim), I, SMinus) + g_2 * qt.tensor(qt.destroy(cav_dim), I, SPlus) + w_c * qt.tensor(num, I, I) + 0.5 * w_1 * qt.tensor(qt.qeye(cav_dim), SZ, I) + 0.5 * w_2 * qt.tensor(qt.qeye(cav_dim), I, SZ))
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 __init__(self, N_field_levels, coupling=None, N_qubits=1): # basic parameters self.N_field_levels = N_field_levels self.N_qubits = N_qubits if coupling is None: self.g = 0 else: self.g = coupling # bare operators self.idcavity = qt.qeye(self.N_field_levels) self.idqubit = qt.qeye(2) self.a_bare = qt.destroy(self.N_field_levels) self.sm_bare = qt.sigmam() self.sz_bare = qt.sigmaz() self.sx_bare = qt.sigmax() self.sy_bare = qt.sigmay() # 1 atom 1 cavity operators self.jc_a = qt.tensor(self.a_bare, self.idqubit) self.jc_sm = qt.tensor(self.idcavity, self.sm_bare) self.jc_sx = qt.tensor(self.idcavity, self.sx_bare) self.jc_sy = qt.tensor(self.idcavity, self.sy_bare) self.jc_sz = qt.tensor(self.idcavity, self.sz_bare)
def test_ssesolve_heterodyne(): "Stochastic: ssesolve: heterodyne, time-dependent H" tol = 0.01 N = 4 gamma = 0.25 ntraj = 25 nsubsteps = 100 a = destroy(N) H = [[a.dag() * a,f]] psi0 = coherent(N, 0.5) sc_ops = [np.sqrt(gamma) * a, np.sqrt(gamma) * a*0.5] e_ops = [a.dag() * a, a + a.dag(), (-1j)*(a - a.dag())] times = np.linspace(0, 2.5, 50) res_ref = mesolve(H, psi0, times, sc_ops, e_ops, args={"a":2}) res = ssesolve(H, psi0, times, sc_ops, e_ops, ntraj=ntraj, nsubsteps=nsubsteps, method='heterodyne', store_measurement=True, map_func=parallel_map, args={"a":2}) assert_(all([np.mean(abs(res.expect[idx] - res_ref.expect[idx])) < tol for idx in range(len(e_ops))])) assert_(len(res.measurement) == ntraj) assert_(all([m.shape == (len(times), len(sc_ops), 2) for m in res.measurement]))
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_mc_dtypes2(): "Monte-carlo: check for correct dtypes (average_states=False)" # set system parameters kappa = 2.0 # mirror coupling gamma = 0.2 # spontaneous emission rate g = 1 # atom/cavity coupling strength wc = 0 # cavity frequency w0 = 0 # atom frequency wl = 0 # driving frequency E = 0.5 # driving amplitude N = 5 # number of cavity energy levels (0->3 Fock states) tlist = np.linspace(0, 10, 5) # times for expectation values # construct Hamiltonian ida = qeye(N) idatom = qeye(2) a = tensor(destroy(N), idatom) sm = tensor(ida, sigmam()) H = (w0 - wl) * sm.dag() * sm + (wc - wl) * a.dag() * a + \ 1j * g * (a.dag() * sm - sm.dag() * a) + E * (a.dag() + a) # collapse operators C1 = np.sqrt(2 * kappa) * a C2 = np.sqrt(gamma) * sm C1dC1 = C1.dag() * C1 C2dC2 = C2.dag() * C2 # intial state psi0 = tensor(basis(N, 0), basis(2, 1)) opts = Options(average_expect=False) data = mcsolve( H, psi0, tlist, [C1, C2], [C1dC1, C2dC2, a], ntraj=5, options=opts) assert_equal(isinstance(data.expect[0][0][1], float), True) assert_equal(isinstance(data.expect[0][1][1], float), True) assert_equal(isinstance(data.expect[0][2][1], complex), 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 test_ssesolve_homodyne(): "Stochastic: smesolve: homodyne" tol = 0.01 N = 4 gamma = 0.25 ntraj = 25 nsubsteps = 100 a = destroy(N) H = a.dag() * a psi0 = coherent(N, 0.5) sc_ops = [np.sqrt(gamma) * a] e_ops = [a.dag() * a, a + a.dag(), (-1j) * (a - a.dag())] times = np.linspace(0, 2.5, 50) res_ref = mesolve(H, psi0, times, sc_ops, e_ops) res = smesolve( H, psi0, times, [], sc_ops, e_ops, ntraj=ntraj, nsubsteps=nsubsteps, method="homodyne", store_measurement=True, map_func=parallel_map, ) assert_(all([np.mean(abs(res.expect[idx] - res_ref.expect[idx])) < tol for idx in range(len(e_ops))])) assert_(len(res.measurement) == ntraj) assert_(all([m.shape == (len(times), len(sc_ops)) for m in res.measurement]))
def test_smesolve_photocurrent(): "Stochastic: photocurrent_mesolve" tol = 0.01 N = 4 gamma = 0.25 ntraj = 20 nsubsteps = 100 a = destroy(N) H = [[a.dag() * a,f]] psi0 = coherent(N, 0.5) sc_ops = [np.sqrt(gamma) * a, np.sqrt(gamma) * a * 0.5] e_ops = [a.dag() * a, a + a.dag(), (-1j)*(a - a.dag())] times = np.linspace(0, 1.0, 21) res_ref = mesolve(H, psi0, times, sc_ops, e_ops, args={"a":2}) res = photocurrent_mesolve(H, psi0, times, [], sc_ops, e_ops, args={"a":2}, ntraj=ntraj, nsubsteps=nsubsteps, store_measurement=True, map_func=parallel_map) assert_(all([np.mean(abs(res.expect[idx] - res_ref.expect[idx])) < tol for idx in range(len(e_ops))])) assert_(len(res.measurement) == ntraj) assert_(all([m.shape == (len(times), len(sc_ops)) for m in res.measurement]))
def testHOFiniteTemperature(self): "brmesolve: harmonic oscillator, finite temperature" N = 10 w0 = 1.0 * 2 * np.pi g = 0.05 * w0 kappa = 0.15 times = np.linspace(0, 25, 1000) a = destroy(N) H = w0 * a.dag() * a + g * (a + a.dag()) psi0 = ket2dm((basis(N, 4) + basis(N, 2) + basis(N, 0)).unit()) n_th = 1.5 w_th = w0/np.log(1 + 1/n_th) def S_w(w): if w >= 0: return (n_th + 1) * kappa else: return (n_th + 1) * kappa * np.exp(w / w_th) c_ops = [np.sqrt(kappa * (n_th + 1)) * a, np.sqrt(kappa * n_th) * a.dag()] a_ops = [a + a.dag()] e_ops = [a.dag() * a, a + a.dag()] res_me = mesolve(H, psi0, times, c_ops, e_ops) res_brme = brmesolve(H, psi0, times, a_ops, e_ops, [S_w]) for idx, e in enumerate(e_ops): diff = abs(res_me.expect[idx] - res_brme.expect[idx]).max() assert_(diff < 1e-2)
def test_ho_lgmres(): "Steady state: Thermal HO - iterative-lgmres solver" # thermal steadystate of an oscillator: compare numerics with analytical # formula a = destroy(40) H = 0.5 * 2 * np.pi * a.dag() * a gamma1 = 0.05 wth_vec = np.linspace(0.1, 3, 20) p_ss = np.zeros(np.shape(wth_vec)) for idx, wth in enumerate(wth_vec): n_th = 1.0 / (np.exp(1.0 / wth) - 1) # bath temperature c_op_list = [] rate = gamma1 * (1 + n_th) c_op_list.append(np.sqrt(rate) * a) rate = gamma1 * n_th c_op_list.append(np.sqrt(rate) * a.dag()) rho_ss = steadystate(H, c_op_list, method='iterative-lgmres') p_ss[idx] = np.real(expect(a.dag() * a, rho_ss)) p_ss_analytic = 1.0 / (np.exp(1.0 / wth_vec) - 1) delta = sum(abs(p_ss_analytic - p_ss)) assert_equal(delta < 1e-3, True)
def test_qubit_power(): "Steady state: Thermal qubit - power solver" # thermal steadystate of a qubit: compare numerics with analytical formula sz = sigmaz() sm = destroy(2) H = 0.5 * 2 * np.pi * sz gamma1 = 0.05 wth_vec = np.linspace(0.1, 3, 20) p_ss = np.zeros(np.shape(wth_vec)) for idx, wth in enumerate(wth_vec): n_th = 1.0 / (np.exp(1.0 / wth) - 1) # bath temperature c_op_list = [] rate = gamma1 * (1 + n_th) c_op_list.append(np.sqrt(rate) * sm) rate = gamma1 * n_th c_op_list.append(np.sqrt(rate) * sm.dag()) rho_ss = steadystate(H, c_op_list, method='power') p_ss[idx] = expect(sm.dag() * sm, rho_ss) p_ss_analytic = np.exp(-1.0 / wth_vec) / (1 + np.exp(-1.0 / wth_vec)) delta = sum(abs(p_ss_analytic - p_ss)) assert_equal(delta < 1e-5, True)
def testHOZeroTemperature(): """ brmesolve: harmonic oscillator, zero temperature """ N = 10 w0 = 1.0 * 2 * np.pi g = 0.05 * w0 kappa = 0.15 times = np.linspace(0, 25, 1000) a = destroy(N) H = w0 * a.dag() * a + g * (a + a.dag()) psi0 = ket2dm((basis(N, 4) + basis(N, 2) + basis(N, 0)).unit()) c_ops = [np.sqrt(kappa) * a] a_ops = [a + a.dag()] e_ops = [a.dag() * a, a + a.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 < 1e-2)
def test_fn_list_td_corr(): """ correlation: comparing TLS emission correlations (fn-list td format) """ # calculate emission zero-delay second order correlation, g2(0), for TLS # with following parameters: # gamma = 1, omega = 2, tp = 0.5 # Then: g2(0)~0.57 sm = destroy(2) args = {"t_off": 1, "tp": 0.5} H = [[2 * (sm+sm.dag()), lambda t, args: np.exp(-(t-args["t_off"])**2 / (2*args["tp"]**2))]] tlist = linspace(0, 5, 50) corr = correlation_3op_2t(H, fock(2, 0), tlist, tlist, [sm], sm.dag(), sm.dag() * sm, sm, args=args) # integrate w/ 2D trapezoidal rule dt = (tlist[-1]-tlist[0]) / (np.shape(tlist)[0]-1) s1 = corr[0, 0] + corr[-1, 0] + corr[0, -1] + corr[-1, -1] s2 = sum(corr[1:-1, 0]) + sum(corr[1:-1, -1]) + \ sum(corr[0, 1:-1]) + sum(corr[-1, 1:-1]) s3 = sum(corr[1:-1, 1:-1]) exp_n_in = np.trapz( mesolve( H, fock(2, 0), tlist, [sm], [sm.dag()*sm], args=args ).expect[0], tlist ) # factor of 2 from negative time correlations g20 = abs( sum(0.5*dt**2*(s1 + 2*s2 + 4*s3)) / exp_n_in**2 ) assert_(abs(g20-0.57) < 1e-1)
def testHOFiniteTemperatureStates(): """ brmesolve: harmonic oscillator, finite temperature, states """ N = 10 w0 = 1.0 * 2 * np.pi g = 0.05 * w0 kappa = 0.25 times = np.linspace(0, 25, 1000) a = destroy(N) H = w0 * a.dag() * a + g * (a + a.dag()) psi0 = ket2dm((basis(N, 4) + basis(N, 2) + basis(N, 0)).unit()) n_th = 1.5 w_th = w0/np.log(1 + 1/n_th) def S_w(w): if w >= 0: return (n_th + 1) * kappa else: return (n_th + 1) * kappa * np.exp(w / w_th) c_ops = [np.sqrt(kappa * (n_th + 1)) * a, np.sqrt(kappa * n_th) * a.dag()] a_ops = [a + a.dag()] e_ops = [] res_me = mesolve(H, psi0, times, c_ops, e_ops) res_brme = brmesolve(H, psi0, times, a_ops, e_ops, [S_w]) n_me = expect(a.dag() * a, res_me.states) n_brme = expect(a.dag() * a, res_brme.states) diff = abs(n_me - n_brme).max() assert_(diff < 1e-2)
def cavity_loss(Q, freq, T, dims): kappa = Q/freq qubit_indices,cav_index = parse_dims(dims) cav_dim = dims[cav_index] n_therm = get_n_therm(freq, T) ops = [0]*len(dims) ops[cav_index] = qt.destroy(cav_dim) ops = [qt.qeye(2) if op == 0 else op for op in ops] return np.sqrt(kappa * (1+n_therm) / 2) * qt.tensor(ops)
def full_approx(cav_dim, w_1, w_2, w_c, g_factor): a = qt.destroy(cav_dim) num = a.dag() * a return ( g_factor * qt.tensor(qt.qeye(cav_dim), SMinus, SPlus) + g_factor * qt.tensor(qt.qeye(cav_dim), SPlus, SMinus) + w_c * qt.tensor(num, I, I) + 0.5 * w_1 * qt.tensor(qt.qeye(cav_dim), SZ, I) + 0.5 * w_2 * qt.tensor(qt.qeye(cav_dim), I, SZ))
def setup(N): op = (qt.destroy(N) + qt.create(N)) psi = qt.Qobj(np.ones(N, complex) / (N**(1 / 2))) return op, psi
wait() """ --------------- </Operators> --------------- """ # Qubit Operators (2 level system) print("Sigma x:\n", sigmax()) print("Sigma y:\n", sigmay()) print("Sigma z:\n", sigmaz()) wait() # Harmonic Oscillator Operators print( "Annihilation Operator with {N} fock states (dimensions) in the hilbert space:\n" .format(N=8), destroy(N=8)) print() print( "Creation Operator with {N} dimensions in the hilbert space:".format(N=8)) print(create(N=8)) # which is the same as destroy(8).dag() print() print( "Check if creation operator = annihiliation operator's complex conjugate: ", destroy(N=8).dag() == create(N=8)) wait() # You can create the position operator from the annihilation operator annihilation_operator = destroy(N=8)
for k in range(8 * orbital_number - 1): aLeft = qt.tensor(aLeft, I) aRight = qt.tensor(aRight, I) # 1st orbital LUpK = ops[0] LDoK = ops[1] RUpK = ops[2] RDoK = ops[3] # 2nd orbital LUpKp = ops[4] LDoKp = ops[5] RUpKp = ops[6] RDoKp = ops[7] aLeft = qt.tensor(aLeft, qt.destroy(3)) aRight = qt.tensor(aRight, III) aLeft = qt.tensor(aLeft, III) aRight = qt.tensor(aRight, qt.destroy(3)) nL = LUpK.dag() * LUpK + LDoK.dag() * LDoK + LUpKp.dag() * LUpKp + LDoKp.dag( ) * LDoKp nR = RUpK.dag() * RUpK + RDoK.dag() * RDoK + RUpKp.dag() * RUpKp + RDoKp.dag( ) * RDoKp nUp = LUpK.dag() * LUpK + LUpKp.dag() * LUpKp + RUpK.dag() * RUpK + RUpKp.dag( ) * RUpKp nDo = LDoK.dag() * LDoK + LDoKp.dag() * LDoKp + RDoK.dag() * RDoK + RDoKp.dag( ) * RDoKp nPhL = aLeft.dag() * aLeft nPhR = aRight.dag() * aRight
def test_squeezing(): squeeze = qutip.squeeze(4, 0.1 + 0.1j) a = qutip.destroy(4) squeezing = qutip.squeezing(a, a, 0.1 + 0.1j) assert squeeze == squeezing
def test_smesolve_homodyne_methods(): "Stochastic: smesolve: homodyne methods with single jump operator" def arccoth(x): return 0.5 * np.log((1. + x) / (x - 1.)) th = 0.1 # Interaction parameter alpha = np.cos(th) beta = np.sin(th) gamma = 1. N = 30 # number of Fock states Id = qeye(N) a = destroy(N) s = 0.5 * ((alpha + beta) * a + (alpha - beta) * a.dag()) x = (a + a.dag()) * 2**-0.5 H = Id c_op = [gamma**0.5 * a] sc_op = [s] e_op = [x, x * x] rho0 = fock_dm(N, 0) # initial vacuum state T = 3. # final time # number of time steps for which we save the expectation values N_store = 121 Nsub = 10 tlist = np.linspace(0, T, N_store) ddt = (tlist[1] - tlist[0]) #### Analytic solution y0 = 0.5 A = (gamma**2 + alpha**2 * (beta**2 + 4 * gamma) - 2 * alpha * beta * gamma)**0.5 B = arccoth((-4 * alpha**2 * y0 + alpha * beta - gamma) / A) y_an = (alpha * beta - gamma + A / np.tanh(0.5 * A * tlist - B)) / (4 * alpha**2) list_methods_tol = [['euler-maruyama', 2e-2], ['pc-euler', 2e-3], ['pc-euler-2', 2e-3], ['platen', 1e-3], ['milstein', 1e-3], ['milstein-imp', 1e-3], ['rouchon', 1e-3], ['taylor1.5', 1e-4], ['taylor1.5-imp', 1e-4], ['explicit1.5', 1e-4], ['taylor2.0', 1e-4]] for n_method in list_methods_tol: sol = smesolve(H, rho0, tlist, c_op, sc_op, e_op, nsubsteps=Nsub, method='homodyne', solver=n_method[0]) sol2 = smesolve(H, rho0, tlist, c_op, sc_op, e_op, store_measurement=0, nsubsteps=Nsub, method='homodyne', solver=n_method[0], noise=sol.noise) sol3 = smesolve(H, rho0, tlist, c_op, sc_op, e_op, nsubsteps=Nsub * 5, method='homodyne', solver=n_method[0], tol=1e-8) err = 1/T * np.sum(np.abs(y_an - \ (sol.expect[1]-sol.expect[0]*sol.expect[0].conj())))*ddt err3 = 1/T * np.sum(np.abs(y_an - \ (sol3.expect[1]-sol3.expect[0]*sol3.expect[0].conj())))*ddt print(n_method[0], ': deviation =', err, ', tol =', n_method[1]) assert_(err < n_method[1]) # 5* more substep should decrease the error assert_(err3 < err) # just to check that noise is not affected by smesolve assert_(np.all(sol.noise == sol2.noise)) assert_(np.all(sol.expect[0] == sol2.expect[0])) sol = smesolve(H, rho0, tlist[:2], c_op, sc_op, e_op, noise=10, ntraj=2, nsubsteps=Nsub, method='homodyne', solver='euler', store_measurement=1) sol2 = smesolve(H, rho0, tlist[:2], c_op, sc_op, e_op, noise=10, ntraj=2, nsubsteps=Nsub, method='homodyne', solver='euler', store_measurement=0) sol3 = smesolve(H, rho0, tlist[:2], c_op, sc_op, e_op, noise=11, ntraj=2, nsubsteps=Nsub, method='homodyne', solver='euler') # sol and sol2 have the same seed, sol3 differ. assert_(np.all(sol.noise == sol2.noise)) assert_(np.all(sol.noise != sol3.noise)) assert_(not np.all(sol.measurement[0] == 0. + 0j)) assert_(np.all(sol2.measurement[0] == 0. + 0j)) sol = smesolve(H, rho0, tlist[:2], c_op, sc_op, e_op, noise=np.array([1, 2]), ntraj=2, nsubsteps=Nsub, method='homodyne', solver='euler') sol2 = smesolve(H, rho0, tlist[:2], c_op, sc_op, e_op, noise=np.array([2, 1]), ntraj=2, nsubsteps=Nsub, method='homodyne', solver='euler') # sol and sol2 have the seed of traj 1 and 2 reversed. assert_(np.all(sol.noise[0, :, :, :] == sol2.noise[1, :, :, :])) assert_(np.all(sol.noise[1, :, :, :] == sol2.noise[0, :, :, :]))
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):
import numpy as np import matplotlib.pyplot as plt import qutip N = 25 taus = np.linspace(0, 25.0, 200) a = qutip.destroy(N) H = 2 * np.pi * a.dag() * a kappa = 0.25 n_th = 2.0 # bath temperature in terms of excitation number c_ops = [np.sqrt(kappa * (1 + n_th)) * a, np.sqrt(kappa * n_th) * a.dag()] states = [ {'state': qutip.coherent_dm(N, np.sqrt(2)), 'label': "coherent state"}, {'state': qutip.thermal_dm(N, 2), 'label': "thermal state"}, {'state': qutip.fock_dm(N, 2), 'label': "Fock state"}, ] fig, ax = plt.subplots(1, 1) for state in states: rho0 = state['state'] # first calculate the occupation number as a function of time n = qutip.mesolve(H, rho0, taus, c_ops, [a.dag() * a]).expect[0] # calculate the correlation function G2 and normalize with n(0)n(t) to # obtain g2 G2 = qutip.correlation_3op_1t(H, rho0, taus, c_ops, a.dag(), a.dag()*a, a) g2 = G2 / (n[0] * n)
def test_destroy_type(): "Operator CSR Type: destroy" op = destroy(5) assert_equal(isspmatrix_csr(op.data), True)
def emitter_drive_sims() -> None: """Run simulations of emitter near mirror with a coherent drive.""" # Some Parameter values for the system being simulated. gamma = 1.0 # Decay rate of the emitter. delta = 0.0 # Detuning of emitter frequency from reference frequency. delay = 4.0 / gamma # Delay between emitter and mirror. ph_mirrors = [0, 0.25 * np.pi, 0.5 * np.pi, 0.75 * np.pi, np.pi] # Mirror phase. ph_delay = np.pi # Phase corresponding to the delay between emitter to # mirror and back at the reference frequency. pulse_width = 2 / gamma pulse_amp = 0.1 * gamma # Numerical parameters. dims = 2 # Dimensionality of each waveguide bin. dt = 0.05 / gamma # Time-step. Also used for meshing waveguide in MPS. num_tsteps = 1000 # Number of time-steps to perform. thresh = 1e-2 # Threshold at which to truncate Schmidth decomposition at # each step of MPS. # Open a h5 file for storing simulation results. data = h5py.File("results/validation_emitter_drive_exponential.h5", "w") param_grp = data.create_group("parameters") param_grp.create_dataset("gamma", data=gamma) param_grp.create_dataset("delta", data=delta) param_grp.create_dataset("delay", data=delay) param_grp.create_dataset("ph_mirrors", data=ph_mirrors) param_grp.create_dataset("ph_delay", data=ph_delay) param_grp.create_dataset("dims", data=dims) param_grp.create_dataset("dt", data=dt) param_grp.create_dataset("num_tsteps", data=num_tsteps) param_grp.create_dataset("thresh", data=thresh) param_grp.create_dataset("pulse_width", data=pulse_width) param_grp.create_dataset("pulse_amp", data=pulse_amp) sim_res_grp = data.create_group("simulation_results") # Define the pulse. def square_pulse(t: float) -> float: if t < pulse_width: return pulse_amp else: return 0 def gaussian_pulse(t: float) -> float: return pulse_amp * np.exp(-(t - pulse_cen)**2 / pulse_width**2) def exponential_pulse(t: float) -> float: return pulse_amp * np.exp(-t / pulse_width) # Run the ideal MPS simulations. print("Running ideal MPS simulations.") results_mps_ideal = [] for ph_mirror in ph_mirrors: print("On ph_mirror = {}".format(ph_mirror)) # Define the low dimensional system. sys = low_dim_sys.DrivenTwoLevelSystem(gamma, delta, exponential_pulse) mps_ideal = oqs_mirror_mps.WgIdealMirror(qutip.basis(2, 0), delay, ph_mirror, ph_delay, dims, sys, dt, thresh) result = mps_ideal.simulate(num_tsteps, [qutip.create(2) * qutip.destroy(2)], 50) results_mps_ideal.append(result[0]) sim_res_grp.create_dataset("mps_ideal", data=np.array(results_mps_ideal)) # Run the nonideal MPS simulations. print("Running nonideal MPS simulations.") results_mps_nonideal = [] for ph_mirror in ph_mirrors: print("On ph_mirror = {}".format(ph_mirror)) # Define the low dimensional system. sys = low_dim_sys.DrivenTwoLevelSystem(gamma, delta, exponential_pulse) mps_nonideal = oqs_mirror_mps.WgPartialMirror(qutip.basis(2, 0), delay, 1, ph_mirror, ph_delay, dims, sys, dt, thresh) result = mps_nonideal.simulate(num_tsteps, [qutip.create(2) * qutip.destroy(2)], 50) results_mps_nonideal.append(result[0]) sim_res_grp.create_dataset("mps_nonideal", data=np.array(results_mps_nonideal))
def emitter_decay_sims() -> None: """Runs simulations of emitter decay with non ideal MPS.""" # Some Parameter values for the system being simulated. gamma = 1.0 # Decay rate of the emitter. delta = 0.0 # Detuning of emitter frequency from reference frequency. delay = 4.0 / gamma # Delay between emitter and mirror. ph_mirrors = [0, 0.25 * np.pi, 0.5 * np.pi, 0.75 * np.pi, np.pi] # Mirror phase. ph_delay = np.pi # Phase corresponding to the delay between emitter to # mirror and back at the reference frequency. # Numerical parameters. dims = 2 # Dimensionality of each waveguide bin. dt = 0.05 / gamma # Time-step. Also used for meshing waveguide in MPS. num_tsteps = 1000 # Number of time-steps to perform. thresh = 1e-2 # Threshold at which to truncate Schmidth decomposition at # each step of MPS. # Open a h5 file for storing simulation results. data = h5py.File("results/validation_emitter_decay.h5", "w") param_grp = data.create_group("parameters") param_grp.create_dataset("gamma", data=gamma) param_grp.create_dataset("delta", data=delta) param_grp.create_dataset("delay", data=delay) param_grp.create_dataset("ph_mirrors", data=ph_mirrors) param_grp.create_dataset("ph_delay", data=ph_delay) param_grp.create_dataset("dims", data=dims) param_grp.create_dataset("dt", data=dt) param_grp.create_dataset("num_tsteps", data=num_tsteps) param_grp.create_dataset("thresh", data=thresh) sim_res_grp = data.create_group("simulation_results") # Quick simulation with FDTD. Want to check if the mirror phase values give # visibly different results in the decay of the emitter. print("Running ideal mirror FDTD simulations.") results_fdtd = [] for ph_mirror in ph_mirrors: result = fdtd.tls_ideal_mirror(gamma, delay, ph_delay, ph_mirror, dt, num_tsteps) # Leaving out the last element in the simulation for the length of FDTD # result to be consistent with the length of MPS simulation. results_fdtd.append(result[:-1]) sim_res_grp.create_dataset("fdtd", data=np.array(results_fdtd)) # MPS with ideal mirror. print("Running ideal mirror MPS simulations.") results_ideal = [] for ph_mirror in ph_mirrors: print("On ph_mirror = {}".format(ph_mirror)) # Define the system. sys = low_dim_sys.TwoLevelSystem(gamma, delta) mps_ideal = oqs_mirror_mps.WgIdealMirror(qutip.basis(2, 1), delay, ph_mirror, ph_delay, dims, sys, dt, thresh) result = mps_ideal.simulate(num_tsteps, [qutip.create(2) * qutip.destroy(2)], 50) results_ideal.append(result[0]) sim_res_grp.create_dataset("mps_ideal", data=np.array(results_ideal)) # MPS with non-ideal mirror MPS code but with reflectivity = 1. print("Running nonideal mirror MPS simulations.") results_nonideal = [] for ph_mirror in ph_mirrors: print("On ph_mirror = {}".format(ph_mirror)) # Define the system. sys = low_dim_sys.TwoLevelSystem(gamma, delta) mps_ideal = oqs_mirror_mps.WgPartialMirror(qutip.basis(2, 1), delay, 1.0, ph_mirror, ph_delay, dims, sys, dt, thresh) result = mps_ideal.simulate(num_tsteps, [qutip.create(2) * qutip.destroy(2)], 50) results_nonideal.append(result[0]) sim_res_grp.create_dataset("mps_nonideal", data=np.array(results_nonideal)) data.close()
def dressed_Hamiltonian(J, nu, nphonon, ldps, rabi): """ Returns the dressed state Hamiltonian. In the form: H = H_mot + H_spinspin + H_int Args: J: Number of ions in trap nu: trap frequency nphonon: maximum number of phonons in system ldps: Lamb-Dicke Parameters rabi: driving field rabi frequency """ if len(ldps) != J: raise Exception('There must be a Lamb-Dicke Parameter for each ion.') basis_m1 = qt.basis(4, 0) basis_0 = qt.basis(4, 1) basis_p1 = qt.basis(4, 2) basis_0tag = qt.basis(4, 3) eye_list = [qt.qeye(4) for j in range(J)] sigmaz_fl = [[-1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0]] sigmaz_fl = qt.Qobj(sigmaz_fl) H_int_J = [0 for j in range(J)] eye_temp = cp.deepcopy(eye_list) eye_temp.append(qt.create(nphonon)) a_dag = qt.tensor(eye_temp) eye_temp = cp.deepcopy(eye_list) eye_temp.append(qt.destroy(nphonon)) a = qt.tensor(eye_temp) # sigmaz = qt.tensor(qt.sigmaz(), qt.qeye(2), qt.qeye(nphonon)) # sigmax_2 = qt.tensor(qt.qeye(2), qt.sigmaz(), qt.qeye(nphonon)) H_mot = nu * a_dag * a for j in range(J): pol, pol_dag = ldps[j] * (a_dag - a), -ldps[j] * (a_dag - a) pol = pol.expm() pol_dag = pol_dag.expm() eye_temp = cp.deepcopy(eye_list) d1 = qt.tensor(basis_p1 * basis_0.trans(), qt.qeye(nphonon)) d2 = qt.tensor(basis_0 * basis_m1.trans(), qt.qeye(nphonon)) d3 = qt.tensor(basis_p1 * basis_0.trans(), qt.qeye(nphonon)) d4 = qt.tensor(basis_m1 * basis_0.trans(), qt.qeye(nphonon)) H_int_j = (rabi / 2) * (d1 * pol + d2 * pol + d3 * pol_dag + d4 * pol_dag) H_int_J[j] = H_int_j H_int_J = qt.tensor(H_int_J) # H_spsp = 0 for j in range(J - 1): for k in range( j + 1, J ): #iteration to avoid double summation or summation over the same index. #print(j,k) H_temp = eye_list H_temp[j] = sigmaz_fl H_temp[k] = sigmaz_fl H_temp = qt.tensor(H_temp) * ldps[j] * ldps[k] # print(H_temp) if j == 0 and k == 1: H_spsp = H_temp else: H_spsp += H_temp #print(H_spsp) H_spinspin = nu * qt.tensor(H_spsp, qt.qeye(nphonon)) return (H_int_J, H_mot, H_spinspin)
#alpha = 0 #beta = np.sqrt(-2j * lam.conjugate()) ''' Testing middle state is steady state ''' beta = 0 psi0 = (np.round(np.cos(theta/2), 5) * qt.tensor(qt.coherent(N, alpha-beta), qt.coherent(N, beta)) + np.round(np.sin(theta/2), 5) * np.exp(1j * phi) * qt.tensor(qt.coherent(N, -alpha+beta), qt.coherent(N, -beta))).unit() ''' guess at final condition ''' beta = alpha psi_final = (np.round(np.cos(theta/2), 5) * qt.tensor(qt.coherent(N, alpha-beta), qt.coherent(N, beta)) + np.round(np.sin(theta/2), 5) * np.exp(1j * phi) * qt.tensor(qt.coherent(N, -alpha+beta), qt.coherent(N, -beta))).unit() ''' Setup operators ''' a = qt.tensor(qt.destroy(N), qt.qeye(N)) b = qt.tensor(qt.qeye(N), qt.destroy(N)) drive_term = (a + b) **2 confinment_term = a ** 2 + 2*a*b loss_ops = [kappa1**.5 * drive_term, kappa2**.5 * confinment_term] H = [eps1 * drive_term + eps1.conjugate() * drive_term.dag()] date = list(str(datetime.datetime.now())[:19]) date[13] = '-' date[16] = '-'
def H1_coeff(t, args): return np.exp(-(t*1j*omega)) def H2_coeff(t, args): return np.exp(t*1j*omega) #For anaharmonicities N=50 omega=1 Xbb=0.09 g=0.2*omega F=0.1*omega HA=omega/2*(-qt.sigmaz()+qt.qeye(2)) HB=omega*qt.create(N)*qt.destroy(N)- Xbb/2*(qt.create(N)*qt.destroy(N)*qt.create(N)*qt.destroy(N)) HAB=g*(qt.tensor(qt.create(2),qt.destroy(N))+qt.tensor(qt.destroy(2), qt.create(N))) H1=qt.tensor(F*qt.create(2),qt.qeye(N)) H2=qt.tensor(F*qt.destroy(2),qt.qeye(N)) H0=qt.tensor(HA, qt.qeye(N))+qt.tensor(qt.qeye(2),HB)+HAB H=[H0, [H1, H1_coeff], [H2, H2_coeff]] t=np.linspace(0,30*math.pi/g,10000) psi0=qt.basis(2*N,0) output = qt.mesolve(H, psi0, t, [qt.tensor(np.sqrt(0.05*omega)*qt.destroy(2),qt.qeye(N))], []) Energy=np.zeros(10000) Ergotropy=np.zeros(10000) v=eigenvectors(HB) EntropyB=np.zeros(10000) for i in range(0,10000): A=np.array(output.states[i])
def liouvillian(omega, g, gamma, beta, n): """Liouvillian for the coupled system of qubit and TLS""" A = np.zeros((n, n)) B = np.zeros((n, n)) Mu = np.zeros((n, n)) for i in range(n): for j in range(n): if j - i == 1: A[i, j] = 0.5 elif i - j == 1: B[i, j] = 0.5 Mu = A + B H0_q = qutip.Qobj(omega * np.array(np.dot(qutip.create(n), qutip.destroy(n)))) # drive qubit Hamiltonian H1_q = omega * Mu # drift TLS Hamiltonian H0_T = omega * 0.5 * (-qutip.operators.sigmaz() + qutip.qeye(2)) # Lift Hamiltonians to joint system operators H0 = np.kron(H0_q, np.identity(2)) + np.kron(np.identity(n), H0_T) H1 = np.kron(H1_q, np.identity(2)) # qubit-TLS interaction H_int = g * ( np.kron(np.array(qutip.create(n)), np.array([[0, 1], [0, 0]])) + np.kron(np.array(qutip.destroy(n)), np.array([[0, 0], [1, 0]]))) # convert Hamiltonians to QuTiP objects H0 = qutip.Qobj(H0 + H_int) H1 = qutip.Qobj(H1) # Define Lindblad operators N = 1.0 / (np.exp(beta * omega) - 1.0) L = [] k = 0 for i in range(0, n - 1): # Cooling on TLS L.append( np.sqrt(gamma * (N + 1)) * np.kron(np.array(qutip.basis(n, i) * qutip.basis(n, i + 1).dag()), np.identity(2))) L.append( np.sqrt(gamma * N) * np.kron(np.array(qutip.basis(n, i + 1) * qutip.basis(n, i).dag()), np.identity(2))) L[k] = qutip.Qobj(L[k]) L[k + 1] = qutip.Qobj(L[k + 1]) k = 2 * (i + 1) # convert Lindblad operators to QuTiP objects # generate the Liouvillian L0 = qutip.liouvillian(H=H0, c_ops=L) L1 = qutip.liouvillian(H=H1) # Shift the qubit and TLS into resonance by default eps0 = lambda t, args: 0.000000000001 return [L0, [L1, eps0]]
plt.show() """ The second-order optical coherence function, with time-delay 𝜏 , is defined as g(2)(𝜏) = <a†(0)a†(𝜏)a(𝜏)a(o)> / <a†(0)a(0)>^2 For a coherent state 𝑔(2)(𝜏) = 1, for a thermal state 𝑔 (2)(𝜏 = 0) = 2 and it decreases as a function of time (bunched photons, they tend to appear together), and for a Fock state with 𝑛 photons 𝑔 (2)(𝜏 = 0) = 𝑛(𝑛−1)/𝑛2 < 1 and it increases with time (anti-bunched photons, more likely to arrive separated in time). The following code calculates and plots 𝑔(2)(𝜏) as a function of 𝜏 for a coherent, thermal and fock state """ N = 25 taus = np.linspace(0, 25.0, 200) a = qt.destroy(N) H = 2 * np.pi * a.dag() * a kappa = 0.25 n_th = 2.0 # bath temperature in terms of excitation number c_ops = [np.sqrt(kappa * (1 + n_th)) * a, np.sqrt(kappa * n_th) * a.dag()] states = [{ "state": coherent_dm(N, np.sqrt(2)), "label": "coherent state" }, { "state": thermal_dm(N, 2), "label": "thermal state" }, { "state": fock_dm(N, 2), "label": "Fock state" }]
def _b_lc(self): """Annihilation operator in the LC basis.""" return qt.destroy(self.nlev_lc)
from qutip import * import matplotlib.pyplot as plt import numpy as np from pylab import * from qutip import tensor, basis, destroy, qeye from matplotlib.patches import Rectangle from matplotlib.animation import FuncAnimation # number of Fock states in Hilbert space. N = 3 M = 3 # field operators a_1 = tensor(destroy(N), qeye(M)) b_1 = tensor(qeye(N), destroy(M)) I_f = tensor(qeye(N), qeye(M)) I = tensor(I_f, qeye(3)) # 2 mode field operators a = tensor(a_1 + b_1, qeye(3)) # atom 1 states astate = basis(3, 0) bstate = basis(3, 1) cstate = basis(3, 2) # atomic operators saa = tensor(I_f, astate * astate.dag()) sbb = tensor(I_f, bstate * bstate.dag()) scc = tensor(I_f, cstate * cstate.dag())
def cav_cost(self, pulse, kind='cost'): sum_fid = 0 shape_cav = [[2, int(self.dims / 2)], [1, 1]] qubit_init = np.array([[0]] * shape_cav[0][0]) qubit_target = np.array([[0]] * shape_cav[0][0]) cavity_init = np.array([[0]] * shape_cav[0][1]) cavity_target = np.array([[0]] * shape_cav[0][1]) qubit_qobj_init = qt.Qobj(self.psi_initial, shape_cav).ptrace(0) qubit_qobj_target = qt.Qobj(self.psi_target, shape_cav).ptrace(0) cavity_qobj_init = qt.Qobj(self.psi_initial, shape_cav).ptrace(1) cavity_qobj_target = qt.Qobj(self.psi_target, shape_cav).ptrace(1) for i in range(shape_cav[0][0]): qubit_init[i] = np.abs(qubit_qobj_init[i][0][i]) qubit_target[i] = np.abs(qubit_qobj_target[i][0][i]) for i in range(shape_cav[0][1]): cavity_init[i] = np.abs(cavity_qobj_init[i][0][i]) cavity_target[i] = np.abs(cavity_qobj_target[i][0][i]) og_cavity_init = cavity_init og_cavity_target = cavity_target og_base_hamiltonian = self.base_hamiltonian og_drive_hamiltonians = self.drive_hamiltonians w_a = 5.66 * 0.5 w_c = 4.5 chi = 2 alpha = w_a * 0.05 K = w_c * 10**(-3) chitag = chi * 10**(-2) for i in range(n_ph): cavity_init = np.array([np.append(cavity_init, [0])]).T cavity_target = np.array([np.append(cavity_target, [0])]).T self.psi_initial = np.kron(qubit_init, cavity_init) self.psi_target = np.kron(qubit_target, cavity_target) self.dims = len(self.psi_initial) qubit_levels = len(qubit_init) cavity_levels = len(cavity_init) a = qt.tensor(qt.destroy(qubit_levels), qt.qeye(cavity_levels)) ad = a.dag() c = qt.tensor(qt.qeye(qubit_levels), qt.destroy(cavity_levels)) cd = c.dag() Ha = w_a * ad * a + (alpha / 2) * ad * ad * a * a Hc = w_c * cd * c + (K / 2) * cd * cd * c * c Hi = chi * cd * c * ad * a + chitag * cd * cd * c * c * ad * a H0 = np.array(Ha + Hc + Hi) Ha_I = np.array(a + ad) Ha_Q = np.array(1j * (a - ad)) Hc_I = np.array(c + cd) Hc_Q = np.array(1j * (c - cd)) drive_hamiltonians = [Ha_I, Ha_Q, Hc_I, Hc_Q] self.drive_hamiltonians = drive_hamiltonians self.base_hamiltonian = H0 if kind == 'cost': sum_fid += self.cost(pulse) else: sum_fid += self.cost_gradient(pulse) cavity_init = og_cavity_init cavity_target = og_cavity_target self.psi_initial = np.kron(qubit_init, cavity_init) self.psi_target = np.kron(qubit_target, cavity_target) self.dims = len(self.psi_initial) self.base_hamiltonian = og_base_hamiltonian self.drive_hamiltonians = og_drive_hamiltonians return sum_fid
ramsey_displaced = ramsey_experiment(rho0, bare_rabi_freq, eta, detuning, times, c_ops, r_ops) plot(times, ramsey_displaced, color='green', label='squeezed-displaced state') legend(loc=1) xlabel('Time') ylabel('Prob(D)') title('Ramsey fringes') show() if 0: # Generate carrier operators N = 3 a = tensor(destroy(N), qeye(2)) Wc = qeye(N) Wc.data = csr_matrix( qeye(N).data.dot(np.diag(rabi_coupling(N, 0, eta)))) sm = tensor(Wc, destroy(2)) print Wc print sm + sm.dag() if 0: # Generate blue sideband operators N = 3 a = tensor(destroy(N), qeye(2)) sm = tensor(qeye(N), destroy(2)) Wbsb = destroy(N).dag( ) # I will overwrite Wsb.data in the next line, but for pedagogical reasons... Wbsb.data = csr_matrix( destroy(N).dag().data.dot( np.diag(
ksz = i_ops while kid > 0: ops[i_ops] = qt.tensor(ops[i_ops], I) # pad with I to the right kid -= 1 while ksz > 0: ops[i_ops] = qt.tensor(-sz, ops[i_ops]) # pad with -sz to the left ksz -= 1 ops[i_ops] = qt.tensor(ops[i_ops], III) #pad 2 I for photons for k in range(2 * orbital_number - 1): aLeft = qt.tensor(aLeft, I) # 1st orbital LUp = ops[0] LDo = ops[1] aLeft = qt.tensor(aLeft, qt.destroy(3)) II = I zero = qt.tensor(qt.fock(2, 1)) zero_photons = qt.tensor(qt.fock(3, 0)) vac = zero for i_ops in range(2 * orbital_number): if i_ops < 2 * orbital_number - 1: vac = qt.tensor(vac, zero) II = qt.tensor(II, I) else: vac = qt.tensor(vac, zero_photons) II = qt.tensor(II, III) for k1, op1 in ops.items(): for k2, op2 in ops.items():
def _2_tuple_split(dimension, kappa, _): a = qutip.destroy(dimension) spectrum = "{kappa} * (w >= 0)".format(kappa=kappa) return ([np.sqrt(kappa) * a, np.sqrt(kappa) * a], [], [[a + a.dag(), spectrum], [(a, a.dag()), (spectrum, '1', '1')]])
name = "coherentstate" samples = 5 evals = 100 cutoffs = range(50, 501, 50) def setup(N): alpha = np.log(N) return alpha def f(N, alpha): return qt.coherent(N, alpha, method="analytic") print("Benchmarking:", name) print("Cutoff: ", end="", flush=True) checks = {} results = [] for N in cutoffs: print(N, "", end="", flush=True) alpha = setup(N) checks[N] = qt.expect(qt.destroy(N), f(N, alpha)) t = benchmarkutils.run_benchmark(f, N, alpha, samples=samples, evals=evals) results.append({"N": N, "t": t}) print() benchmarkutils.check(name, checks, 0.05) benchmarkutils.save(name, results)
def destroy(n): ops = [q.qeye(d) for d in mode_dims] ops[n] = q.destroy(mode_dims[n]) return q.tensor(*list(reversed(ops)))
def test_squeezing_type(): "Operator CSR Type: squeezing" op = squeezing(destroy(5), qeye(5), -0.1j) assert_equal(isspmatrix_csr(op.data), True)
def _harmonic_oscillator_c_ops(n_th, kappa, dimension): a = qutip.destroy(dimension) if n_th == 0: return [np.sqrt(kappa) * a] return [np.sqrt(kappa * (n_th + 1)) * a, np.sqrt(kappa * n_th) * a.dag()]
T1 =0 T2 =T1+T T_final=T2+T n_t = 201 #number of points from T1 to T2 #Wigner params nbWignerPlot = 16 nbCols=4 "Preparation of tensor space, operators and states" Na=trunc # Truncature Nb= trunc # Operators for the control Ia = qt.identity(Na) # identity a = qt.destroy(Na) # lowering operator n_a = a.dag()*a # photon number #Operator for the target Ib = qt.identity(Nb) # identity b = qt.destroy(Nb) # lowering operator n_b = b.dag()*b # photon number #tensor operators I_tensor =qt.tensor(Ia,Ib) a_tensor = qt.tensor(a,Ib) b_tensor = qt.tensor(Ia,b) n_a_tensor = qt.tensor(n_a,Ib) n_b_tensor = qt.tensor(Ia,n_b) #Parameter of the control
xSR = .206 g2 = -.111 * 2 * np.pi eD = 3 kR = np.sqrt(40) kS = np.sqrt(.05) num_steps = 20 max_time = 20 date = list(str(datetime.datetime.now())[:19]) date[13] = '-' date[16] = '-' ''' SUPER IMPORTANT: change the filepath to wherever you want the plots saved ''' filepath = 'C:/Users/Jeff/Documents/qutip/out/leghtas/' + ''.join(date) + '/' ''' Declare opperators and Hamiltonian ''' aS = qt.tensor(qt.destroy(NS), qt.qeye(NR)) aR = qt.tensor(qt.qeye(NS), qt.destroy(NR)) xS = (aS + aS.dag()) / 2 pS = 1j * (aS - aS.dag()) / 2 H_kerr = (-xSS / 2 * aS.dag()**2 * aS**2 - xRR / 2 * aR.dag()**2 * aR**2 - xSR * aS.dag() * aS * aR.dag() * aR) H_2 = (g2 * aS**2 * aR.dag() + g2.conjugate() * aS.dag()**2 * aR + eD * aR.dag() + eD.conjugate() * aR) H = H_2 + H_kerr ''' initial state ''' psi0 = qt.tensor(qt.fock(NS, 0), qt.fock(NR, 0)) ''' Solve the system '''
import qutip as qt import numpy as np import vpython as vp vp.scene.width = 1000 vp.scene.height = 800 CALC_ROOTS = True dt = 0.001 n = 20 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) def squeezed_coherent(s): global n, a return ((s.conjugate() * a * a - s * a.dag() * a.dag()) / 2).expm() * qt.basis(n, 0)
return sum([c*((z**(n-i-1))*(w**(i)))/\ np.sqrt(np.math.factorial(i)*np.math.factorial(n-i-1))\ for i, c in enumerate(spin.full().T[0])]) def upgrade_state2(spin, a): return reduce(lambda x, y: x*y, [sum([c*a[i].dag()\ for i, c in enumerate(xyz_spinor(xyz))]) for xyz in spin_XYZ(spin)]) #################################################################################### dt = 0.005 n = 5 a = [qt.tensor(qt.destroy(n), qt.identity(n)),\ qt.tensor(qt.identity(n), qt.destroy(n))] XYZ = {"X": upgrade(qt.sigmax(), a),\ "Y": upgrade(qt.sigmay(), a),\ "Z": upgrade(qt.sigmaz(), a)} X, Y, Z = XYZ["X"], XYZ["Y"], XYZ["Z"] XL, XV = X.eigenstates() XP = [v * v.dag() for v in XV] YL, YV = Y.eigenstates() YP = [v * v.dag() for v in YV] ZL, ZV = Z.eigenstates() ZP = [v * v.dag() for v in ZV]
def position_ops(N): a = destroy(N) return tensor(I_sys, (a + a.dag()) * 0.5) # Should have a 0.5 in this