def solveME(self, rho0, ti, tf, **kwargs): """ This function constructs the Hamiltonian and solves the Lindblad master equation with or without collapse operators in the (pi/2)x, (pi)x, (pi/2)y pulse durations and free evolution time: +-------+ +--------------+ +-------+ | | | | | | |(pi/2)x| | (pi)x | |(pi/2)y| +-------+---------------+--------------+---------------+-------+----> Inputs: rho0 : tensor(rho_qb, rho_HO) ti, tf: denotes initial and final time in real time duration kwargs: keyword arguments """ #print ("Number of sub-intervals for (pi/2)y pulse duration: %d"%Num); # Time list for (pi/2)x pulse tlist = np.linspace(ti, tf, pars['Num']) #------------------------------------------- # Customize mesolver options options = self.options #------------------------------ # Retreive collapse operators #------------------------------ cops = self.collapse #Test#print("Collapse Operators",self.collapse) # Setup Hamiltonian for (pi/2)y pulse Hops, Hargs = self.setup_Hamiltonian(ti, tf, **kwargs) #------------------------------------------------- # Evolve system in (pi/2)x or free precess or (pi)x or (pi/2)y pulse duration # Master equation evolution of a density matrix for given Hamiltonian #------------------------------------------------- if self.expectops == []: options.store_states = False options.store_final_state = True out = mesolve(Hops, rho0, tlist, cops, [], Hargs, options, progress_bar=self.progress_bar) rho = out.final_state #rho = out.states[-1]; return rho else: options.store_states = True out = mesolve(Hops, rho0, tlist, cops, self.expectops, Hargs, options, progress_bar=self.progress_bar) return (tlist, out.states[-1], out.expect)
def test_single_decay_ratio(self): """The population in the ground-states after decay from a single excited state is equal to the expected ratio.""" psi0 = self.SLS.basis[1] result = qutip.mesolve(self.SLS.H, psi0, self.times, self.SLS.decay, self.population) if False: for i in range(6): plt.plot(self.times, result.expect[i], "--") plt.show() plt.close() self.assertEqual(round(result.expect[0][-1], 2), 1 / 2) self.assertEqual(round(result.expect[2][-1], 2), round(1 / 3, 2)) self.assertEqual(round(result.expect[4][-1], 2), round(1 / 6, 2)) psi0 = self.SLS.basis[3] result = qutip.mesolve(self.SLS.H, psi0, self.times, self.SLS.decay, self.population) if False: for i in range(6): plt.plot(self.times, result.expect[i], "--") plt.show() plt.close() self.assertEqual(round(result.expect[2][-1], 2), round(1 / 6, 2)) self.assertEqual(round(result.expect[4][-1], 2), round(1 / 3, 2)) self.assertEqual(round(result.expect[5][-1], 2), 1 / 2)
def test_s_splitting(self): psi0 = self.ELS.basis[0] self.ELS.polarization = (1, 1, 1) self.ELS.B = 0.2 self.ELS.sat = 10.0 self.ELS.delta = self.ELS.s_splitting + self.ELS.p_splitting result = qutip.mesolve(self.ELS.H, psi0, self.times, self.ELS.decay, self.population) if False: for i in range(8): plt.plot(self.times, result.expect[i], label="%d" % i) plt.legend() plt.show() plt.close() self.assertTrue(result.expect[0][-1] < 1e-3) self.ELS.delta = (self.ELS.s_splitting + self.ELS.p_splitting) / 2 result = qutip.mesolve(self.ELS.H, psi0, self.times, self.ELS.decay, self.population) if False: for i in range(8): plt.plot(self.times, result.expect[i], label="%d" % i) plt.legend() plt.show() plt.close() self.assertTrue(result.expect[0][-1] > 0.98)
def CRt_echo(tend, psi0): # Echoed CR in qubit 1 frame if tend == 0: return qt.expect(e_op_list, psi0) tlist = np.arange(0, tend, dt) output1 = qt.mesolve(Htp, psi0, tlist[0:int(len(tlist) / 2)], [], [], {}) psiEcho = qt.tensor(qt.rx(np.pi), qt.identity(2)) * output1.states[-1] output2 = qt.mesolve(Htm, psiEcho, tlist[int(len(tlist) / 2):], [], e_op_list, {}) return np.array(output2.expect)[:, -1]
def y(): yt = [] y = [ qt.mesolve(H, psi[0][0], times, noise, [B0]).expect[0] + qt.mesolve(H, psi[0][1], times, noise, [B0]).expect[0] ] for i in range(3): i += 1 y.append( qt.mesolve(H, psi[i][1], times, noise, [B0]).expect[0] - qt.mesolve(H, psi[i][0], times, noise, [B0]).expect[0]) for i in range(len(times)): yt.append(np.asarray([y[0][i], y[1][i], y[2][i], y[3][i]])) return yt
def x(): xt = [] x = [ qt.mesolve(H, psi[0][1], times, noise, [A0]).expect[0] + qt.mesolve(H, psi[0][0], times, noise, [A0]).expect[0] ] for i in range(3): i += 1 x.append( qt.mesolve(H, psi[i][1], times, noise, [A0]).expect[0] - qt.mesolve(H, psi[i][0], times, noise, [A0]).expect[0]) for i in range(len(times)): xt.append(np.asarray([x[0][i], x[1][i], x[2][i], x[3][i]])) return xt
def _qubit_integrate(tlist, psi0, epsilon, delta, g1, g2, solver): H = epsilon / 2.0 * sigmaz() + delta / 2.0 * sigmax() c_op_list = [] rate = g1 if rate > 0.0: c_op_list.append(np.sqrt(rate) * sigmam()) rate = g2 if rate > 0.0: c_op_list.append(np.sqrt(rate) * sigmaz()) e_ops = [sigmax(), sigmay(), sigmaz()] if solver == "me": output = mesolve(H, psi0, tlist, c_op_list, e_ops) elif solver == "es": output = essolve(H, psi0, tlist, c_op_list, e_ops) elif solver == "mc": output = mcsolve(H, psi0, tlist, c_op_list, e_ops, ntraj=750) else: raise ValueError("unknown solver") return output.expect[0], output.expect[1], output.expect[2]
def compute_single_ph_expectation( system: mqs.ModulatedQuantumSystem, inp_freqs: np.ndarray, inp_amp: float, num_periods: int, num_dt: int): # The time-mesh over which to solve the master equation. dt = system.period / num_dt times = np.arange(0, system.period * num_periods, dt) # Iterate over all the frequencies and compute the mean_vals = [] for freq in inp_freqs: # Get the hamiltonian and the decay operators. H, L = system.get_qutip_operators(freq, inp_amp) # Generate an initial state. Note that we randomly generate an initial # state and the expectation is that for system with a single ground # state, the initial state does not matter in steady state. psi_init_as_list = [] for dim in H[0].dims[0]: psi_init_as_list.append(qutip.basis(dim)) psi_init = qutip.tensor(psi_init_as_list) # Solve the master equation. out = qutip.mesolve(H, psi_init, times, c_ops=[L], e_ops=[L.dag() * L]) mean_vals.append(out.expect[0][-num_dt:]) return np.array(mean_vals) / inp_amp**2
def test_driven_tls(datadir): hs = LocalSpace('tls', basis=('g', 'e')) w = symbols(r'\omega', real=True) pi = sympy.pi cos = sympy.cos t, T, E0 = symbols('t, T, E_0', real=True) a = 0.16 blackman = 0.5 * (1 - a - cos(2 * pi * t / T) + a * cos(4 * pi * t / T)) H0 = Destroy(hs=hs).dag() * Destroy(hs=hs) H1 = LocalSigma('g', 'e', hs=hs) + LocalSigma('e', 'g', hs=hs) H = w * H0 + 0.5 * E0 * blackman * H1 circuit = SLH(identity_matrix(0), [], H) num_vals = {w: 1.0, T: 10.0, E0: 1.0 * 2 * np.pi} # test qutip conversion num_circuit = circuit.substitute(num_vals) H_qutip, Ls = SLH_to_qutip(num_circuit, time_symbol=t) assert len(Ls) == 0 assert len(H_qutip) == 3 times = np.linspace(0, num_vals[T], 201) psi0 = qutip.basis(2, 1) states = qutip.mesolve(H_qutip, psi0, times, [], []).states pop0 = np.array(qutip_population(states, state=0)) pop1 = np.array(qutip_population(states, state=1)) datfile = os.path.join(datadir, 'pops.dat') #print("DATFILE: %s" % datfile) #np.savetxt(datfile, np.c_[times, pop0, pop1, pop0+pop1]) pop0_expect, pop1_expect = np.genfromtxt(datfile, unpack=True, usecols=(1, 2)) assert np.max(np.abs(pop0 - pop0_expect)) < 1e-12 assert np.max(np.abs(pop1 - pop1_expect)) < 1e-12 # Test QSD conversion codegen = QSDCodeGen(circuit, num_vals=num_vals, time_symbol=t) codegen.add_observable(LocalSigma('e', 'e', hs=hs), name='P_e') psi0 = BasisKet('e', hs=hs) codegen.set_trajectories(psi_initial=psi0, stepper='AdaptiveStep', dt=0.01, nt_plot_step=5, n_plot_steps=200, n_trajectories=1) scode = codegen.generate_code() compile_cmd = _cmd_list_to_str( codegen._build_compile_cmd(qsd_lib='$HOME/local/lib/libqsd.a', qsd_headers='$HOME/local/include/qsd/', executable='test_driven_tls', path='$HOME/bin', compiler='mpiCC', compile_options='-g -O0')) print(compile_cmd) codefile = os.path.join(datadir, "test_driven_tls.cc") #print("CODEFILE: %s" % codefile) #with(open(codefile, 'w')) as out_fh: #out_fh.write(scode) #out_fh.write("\n") with open(codefile) as in_fh: scode_expected = in_fh.read() assert scode.strip() == scode_expected.strip()
def get_unitary_evolution_states(self, H_ops): q.mesolve """Gets the unitary evolution under heuristic hamiltonian state array. Parameters ---------- H_ops : list, Qutip.Qobj, list of allowed control actions eg : [sigmax()] Returns ------- list A list array containing Qutip.qobj states corresponding to the evolved path """ H = get_approximate_hamiltonian(self, "GRAPE", H_ops) initial_state = self.initial_state T = self.time_max t_frame = self.t_frame n_frames = int(T/t_frame) times = np.linspace(0, T, n_frames) evolution = q.mesolve(H, initial_state, times) return evolution.states
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 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 testCOPSwithAOPS(): """ brmesolve: c_ops with a_ops """ delta = 0.0 * 2 * np.pi epsilon = 0.5 * 2 * np.pi gamma = 0.25 times = np.linspace(0, 10, 100) H = delta / 2 * sigmax() + epsilon / 2 * sigmaz() psi0 = (2 * basis(2, 0) + basis(2, 1)).unit() c_ops = [np.sqrt(gamma) * sigmam(), np.sqrt(gamma) * sigmaz()] c_ops_brme = [np.sqrt(gamma) * sigmaz()] a_ops = [sigmax()] e_ops = [sigmax(), sigmay(), sigmaz()] res_me = mesolve(H, psi0, times, c_ops, e_ops) res_brme = brmesolve(H, psi0, times, a_ops, e_ops, spectra_cb=[lambda w: gamma * (w >= 0)], c_ops=c_ops_brme) 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 do_pulse_sequence(self, psi0, **kwargs): ''' Run a detuning pulse sequence ''' opts = qu.Options(nsteps=100000) self.device.build_hamiltonian(detuning=0) initial_hamiltonian = self.device.Hamiltonian conversion_factor = self.device.alpha * const.eV / const.h # Convert voltage pulse to frequency units detuning_hamiltonian = conversion_factor * qu.Qobj( np.array([[1 / 2, 0, 0, 0, 0], [0, 1 / 2, 0, 0, 0], [0, 0, 1 / 2, 0, 0], [0, 0, 0, 1 / 2, 0], [0, 0, 0, 0, -1 / 2]])) qutip_time_dependence = qu.Cubic_Spline( self.lePulse.time_vec[0], self.lePulse.time_vec[-1], self.lePulse.simulation_waveform) full_H = [ initial_hamiltonian, [detuning_hamiltonian, qutip_time_dependence] ] output = qu.mesolve(full_H, psi0, tlist=self.lePulse.time_vec, c_ops=[], e_ops=[], options=opts, progress_bar=True) self.simulation_result = output
def solve_method_2(input_): t = 1e-6 def Omega(_t: float, *args) -> float: if _t <= 0 or _t >= t: return 0 # scaling = 1 / 100 scaling = input_ return np.sin(_t / t * np.pi) * scaling t_list = np.linspace(0, t, 500) Omegas = np.array([Omega(_t) for _t in t_list]) area = simpson(Omegas, t_list) print(f"Area: {area}") time_independent_terms = Qobj( np.zeros((3, 3)) + Vdd * 1e9 * rcrt @ rcrt.T) Omega_coeff_terms = Qobj((rcrt @ rc1t.T + rc1t @ rcrt.T) / 2) solver = mesolve( [time_independent_terms, [Omega_coeff_terms, Omega]], psi_0, t_list, options=Options(store_states=True, nsteps=20000), ) c_r1 = np.abs(solver.states[-1].data[1, 0]) return c_r1
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 custom_run(sim): sim.setup_run() _raw_dc_calculator = sim.get_calculator((270, 210)) sim.dc_field_calculator = lambda t: _raw_dc_calculator(t).round(1) # def test(t): # x = _raw_dc_calculator(t) # print("hi") # return x # sim.dc_field_calculator = test # sim.rf_freq_calculator = sim.get_calculator(230e6 / 1e9) sim.rf_freq_calculator = sim.get_calculator(240e6 / 1e9) # sim.rf_freq_calculator = sim.get_calculator(245e6 / 1e9) # sim.rf_field_calculator = lambda t: 3 * np.sin(np.pi * t / 1000 / sim.t) # sim.rf_field_calculator = lambda t: 25 * np.sin(np.pi * t / 1000 / sim.t) sim.rf_field_calculator = lambda t: 30 * np.sin(np.pi * t / 1000 / sim.t) t_list = np.linspace(0, sim.t * 1000, sim.timesteps + 1) # Use self.t (in ms) to create t_list in ns initial_state = qutip.basis(sim.states_count, 3) # sim.debug_plots(skip_setup=True) sim.results = qutip.mesolve( sim.get_hamiltonian, initial_state, t_list, c_ops=[], options=qutip.solver.Options(store_states=True, nsteps=20000), progress_bar=True )
def get_qutip_zt(model, time_series): H, _, sigma_z = get_qutip_operator(model) init_state = qutip.tensor( [qutip.basis(2)] + [qutip.basis(ph.n_phys_dim) for ph in model.ph_list]) result = qutip.mesolve(H, init_state, time_series, e_ops=[sigma_z]) return result.expect[0]
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 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) np.testing.assert_allclose(sol.expect[0], sol_ref.expect[0], atol=1e-4)
def test_linewidth_pi(self): psi0 = 1 / np.sqrt(2) * (self.FLS.basis[0] + self.FLS.basis[1]) self.FLS.sat = 0.0001 self.FLS.polarization = (1, 0, 0) self.times = np.linspace(0, 0.2 * 10 ** -6, num=100) detuning = np.linspace(-81.0, 79.0, num=80) transfer = [] for delta in detuning: self.FLS.delta = delta result = qutip.mesolve(self.FLS.H, psi0, self.times, self.FLS.decay, self.population) transfer.append(result.expect[2][-1] + result.expect[3][-1]) if False: plt.plot(result.times, result.expect[2], "--", label="%0.2f" % delta) if False: plt.legend() plt.show() plt.close() popt, pcov = curve_fit(lorentzian, detuning, transfer, p0=[1.0, 20.0]) fit_detuning = np.linspace(min(detuning), max(detuning), num=1000) if False: plt.plot(detuning, transfer, "o") plt.plot(fit_detuning, lorentzian(fit_detuning, *popt), "--", label="$\Gamma$ = %0.2f MHz" % popt[0]) plt.legend() plt.show() plt.close() self.assertTrue(abs(popt[0] - self.FLS.linewidth / 10 ** 6) < 0.1)
def test_harmonic_oscillator(n_th): N = 10 w0 = 1.0 * 2 * np.pi g = 0.05 * w0 kappa = 0.15 S_w = _harmonic_oscillator_spectrum_frequency(n_th, w0, kappa) a = qutip.destroy(N) H = w0 * a.dag() * a + g * (a + a.dag()) psi0 = (qutip.basis(N, 4) + qutip.basis(N, 2) + qutip.basis(N, 0)).unit() psi0 = qutip.ket2dm(psi0) times = np.linspace(0, 25, 1000) c_ops = _harmonic_oscillator_c_ops(n_th, kappa, N) a_ops = [[a + a.dag(), S_w]] e_ops = [a.dag() * a, a + a.dag()] me = qutip.mesolve(H, psi0, times, c_ops, e_ops) brme = qutip.brmesolve(H, psi0, times, a_ops, e_ops) for me_expectation, brme_expectation in zip(me.expect, brme.expect): np.testing.assert_allclose(me_expectation, brme_expectation, atol=1e-2) num = qutip.num(N) me_num = qutip.expect(num, me.states) brme_num = qutip.expect(num, brme.states) np.testing.assert_allclose(me_num, brme_num, atol=1e-2)
def mesolve(self, tlist, rho0=None, e_ops=None, **kwargs): """Run :func:`qutip.mesolve.mesolve` on the system of the objective Solve the dynamics for the :attr:`H` and :attr:`c_ops` of the objective. If `rho0` is not given, the :attr:`initial_state` will be propagated. All other arguments will be passed to :func:`qutip.mesolve.mesolve`. Returns: qutip.solver.Result: Result of the propagation, see :func:`qutip.mesolve.mesolve` for details. """ if rho0 is None: rho0 = self.initial_state if e_ops is None: e_ops = [] H = self.H c_ops = self.c_ops if FIX_QUTIP_932 and sys.platform == "darwin": # pragma: no cover # "darwin" = macOS; the "pragma" excludes from coverage analysis controls = extract_controls([self]) pulses_mapping = extract_controls_mapping([self], controls) mapping = pulses_mapping[0] # "first objective" (dummy structure) H = _plug_in_array_controls_as_func(H, controls, mapping[0], tlist) c_ops = [ _plug_in_array_controls_as_func( c_op, controls, mapping[ic + 1], tlist ) for (ic, c_op) in enumerate(self.c_ops) ] return qutip.mesolve( H=H, rho0=rho0, tlist=tlist, c_ops=c_ops, e_ops=e_ops, **kwargs )
def _integrate(L, E0, ti, tf, integrator='propagator', parallel=False, opt=qt.Options()): """ Basic ode integrator """ if tf > ti: if integrator == 'mesolve': if parallel: warnings.warn('parallelization not implemented for "mesolve"') opt.store_final_state = True sol = qt.mesolve(L, E0, [ti, tf], [], [], options=opt) return sol.final_state elif integrator == 'propagator': return qt.propagator( L, (tf - ti), [], [], parallel=parallel, options=opt) * E0 else: raise ValueError('integrator keyword must be either "propagator"' + 'or "mesolve"') else: return E0
def get_free_evolution_states(self, t_limit): q.mesolve """Gets the free evolution state array. Parameters ---------- t_limit : int maximum time frame for evolution Returns ------- np.array A numpy array containing Qutip.qobj states corresponding to the evolved path Raises ------ ArgumentsValueError Raised if `t_frame` is greater than 't_limit'. """ H = self.hamiltonian initial_state = self.initial_state if (t_frame > t_limit): raise ArgumentsValueError("frame width cannot be greater than maximum time limit") n_frames = int(t_limit/self.t_frame) t_list = np.linspace(0, t_limit, n_frames) evolution = q.mesolve(H, initial_state, t_list) return evolution.states
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_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 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 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 mastersolve(Data): #run master equation solver print "running ME Solver..." rawdm = qt.mesolve( Data.H, Data.psi0, Data.tlist, Data.slist, [] ) #This runs the solver with whichever collapse operators and hamiltonian are chosen Data.entire_raw = rawdm rawdm = rawdm.states Data.rawq = rawdm #Since the analysis always bogs down, and the raw.states data structure can be very large, #This will turn it into a numpy array rather than a qobj for purposes of speed. print "numpying" u = len(rawdm) rawarray = np.zeros(u, dtype=np.ndarray) for i in range(u): #Each Timestep rawi = rawdm[i] #Calls the i,jth element of the state vector structure xary = np.zeros( [8, 8], dtype=complex) #Defines the new array for the state vectors for q in range(8): for j in range(8): xary[q, j] = rawi[q, j] #Turns the qobj to a numpy array rawarray[i] = xary #Writes the element to the array Data.raw = rawarray #Removes the old data structure. return
def solve(self): levels = self.levels if self.params['mixed']: self.rho0 = sum([ level.pop[i] * qu.ket2dm(level.states[i]) for level in levels for i in range(len(level.pop)) ]) if self.cavity: self.rho0 = qu.tensor(self.rho0, self.cavity.psi0) else: self.rho0 = qu.ket2dm( sum([ level.pop[i] * level.states[i] for level in levels for i in range(len(level.pop)) ]).unit()) if self.cavity: self.rho0 = qu.tensor(self.rho0, qu.ket2dm(self.cavity.psi0)) self.e_ops = [] for i in self.projectors.values(): self.e_ops += i if self.cavity: self.e_ops.append(self.ad * self.a) # C_spon = np.sqrt(params['gamma'])*self.sm # C_lw_g = np.sqrt(LW)*proj_g # C_lw_e = np.sqrt(LW)*proj_e # self.c_ops = [C_spon] tlist = self.params['tlist'] self.result = qu.mesolve(self.H, self.rho0, tlist, e_ops=self.e_ops) return self.result
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 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 simulate(self): # setup time-dependent Hamiltonians sequentially psi0 = self.initial_state self.sim_states = [] self.sim_tlist = [] for [H_td, td_coeff, args, tlist] in self._H_td: if H_td is not None: H = [self.H_ti, [H_td, td_coeff]] else: H = self.H_ti args = None output = qt.mesolve(H, psi0, tlist, self.c_ops, [], args=args) # append all but the last step--will the initial step in the next simulation self.sim_states.extend(output.states[:-1]) self.sim_tlist.extend(tlist[:-1]) psi0 = output.states[-1] self.sim_states.extend([output.states[-1]]) self.sim_tlist.extend([tlist[-1]]) self.sim_states = np.array(self.sim_states) self.sim_tlist = np.array(self.sim_tlist)
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 test_jaynes_cummings_zero_temperature(): """ brmesolve: Jaynes-Cummings model, zero temperature """ N = 10 a = qutip.tensor(qutip.destroy(N), qutip.qeye(2)) sp = qutip.tensor(qutip.qeye(N), qutip.sigmap()) psi0 = qutip.ket2dm(qutip.tensor(qutip.basis(N, 1), qutip.basis(2, 0))) a_ops = [[(a + a.dag()), lambda w: kappa * (w >= 0)]] e_ops = [a.dag() * a, sp.dag() * sp] 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 * sp.dag() * sp + g * (a + a.dag()) * (sp + sp.dag()) me = qutip.mesolve(H, psi0, times, c_ops, e_ops) brme = qutip.brmesolve(H, psi0, times, a_ops, e_ops) for me_expectation, brme_expectation in zip(me.expect, brme.expect): # Accept 5% error. np.testing.assert_allclose(me_expectation, brme_expectation, atol=5e-2)
def test_ssesolve_feedback(): "Stochastic: ssesolve: time-dependent H with feedback" tol = 0.01 N = 4 ntraj = 10 nsubsteps = 100 a = destroy(N) H = [num(N)] psi0 = coherent(N, 2.5) sc_ops = [[a + a.dag(), f_dargs]] e_ops = [a.dag() * a, a + a.dag(), (-1j) * (a - a.dag()), qeye(N)] times = np.linspace(0, 10, 101) res_ref = mesolve(H, psi0, times, sc_ops, e_ops, args={"expect_op_3": qeye(N)}) res = ssesolve(H, psi0, times, sc_ops, e_ops, solver=None, noise=1, ntraj=ntraj, nsubsteps=nsubsteps, method='homodyne', map_func=parallel_map, args={"expect_op_3": qeye(N)})
def test_single_decay_ratio(self): """The population in the ground-states after decay from a single excited state is equal to the expected ratio.""" psi0 = self.FLS.basis[2] result = qutip.mesolve(self.FLS.H, psi0, self.times, self.FLS.decay, self.population) self.assertTrue(round(result.expect[0][-1], 6) == round(1 / 3, 6)) self.assertTrue(round(result.expect[1][-1], 6) == round(2 / 3, 6)) psi0 = self.FLS.basis[3] result = qutip.mesolve(self.FLS.H, psi0, self.times, self.FLS.decay, self.population) self.assertTrue(round(result.expect[1][-1], 6) == round(1 / 3, 6)) self.assertTrue(round(result.expect[0][-1], 6) == round(2 / 3, 6))
def me_timestep(self, time=NB_TIME_STEP, from_start=False, options=QT_OPTIONS): # pdb.set_trace() """ Propogates forward by non-unitary evolution including the sinks, to update the current state, Uses qt.mesolve and saves the whole result in the time_evolution_list Same from_start ability as unitary_timestep""" if from_start: if self.verbose: print("unitary list and current state have been reset") rho = self.initial_state # self.time_evolution_list = [] else: rho = self.current_state H = self._extended_hamiltonian cops = self._dissipative_ops if type(time) == list or type(time) == np.ndarray: times = time else: times = np.array([0, time]) result = qt.mesolve(H, rho, times, c_ops=cops, e_ops=[], options=options) self.current_state = result.states[-1]
def correlation_ode(H, rho0, tlist, taulist, c_op_list, a_op, b_op): """ Internal function for calculating correlation functions using the master equation solver. See :func:`correlation` usage. """ if rho0 == None: rho0 = steadystate(H, co_op_list) C_mat = zeros([size(tlist),size(taulist)],dtype=complex) rho_t = mesolve(H, rho0, tlist, c_op_list, []).states for t_idx in range(len(tlist)): C_mat[t_idx,:] = mesolve(H, b_op * rho_t[t_idx], taulist, c_op_list, [a_op]).expect[0] return C_mat
def testMETDDecayAsArray(self): "mesolve: time-dependence as array with super as init cond" me_error = 1e-5 N = 10 a = destroy(N) H = a.dag() * a psi0 = basis(N, 9) rho0vec = operator_to_vector(psi0 * psi0.dag()) E0 = sprepost(qeye(N), qeye(N)) kappa = 0.2 tlist = np.linspace(0, 10, 1000) c_op_list = [[a, np.sqrt(kappa * np.exp(-tlist))]] out1 = mesolve(H, psi0, tlist, c_op_list, []) out2 = mesolve(H, E0, tlist, c_op_list, []) fid = self.fidelitycheck(out1, out2, rho0vec) assert_(max(abs(1.0 - fid)) < me_error, True)
def mesolve(self, exps=[]): """solve Interface to qutip mesolve for the system. :param exps: List of expectation values to calculate at each timestep. Defaults to empty. """ return qt.mesolve(self.hamiltonian()[0], self.initial_state, self.tlist, self._c_ops(), exps)
def do_qt_mesolve(state,H,lindblads,steps,tau,**kwargs): progress = kwargs.pop('progress_bar',None) times = kwargs.pop('times',None) if times is None: times = np.linspace(0,steps*tau,steps,dtype=np.float_) return qt.mesolve(H,qt.ket2dm(state),times,lindblads,[], options=qt.Options(**kwargs), progress_bar=progress).states
def testMETDDecayAsStrList(self): "mesolve: time-dependence as string list with super as init cond" me_error = 1e-6 N = 10 # number of basis states to consider a = destroy(N) H = a.dag() * a psi0 = basis(N, 9) # initial state rho0vec = operator_to_vector(psi0 * psi0.dag()) E0 = sprepost(qeye(N), qeye(N)) kappa = 0.2 # coupling to oscillator c_op_list = [[a, "sqrt(k*exp(-t))"]] args = {"k": kappa} tlist = np.linspace(0, 10, 100) out1 = mesolve(H, psi0, tlist, c_op_list, [], args=args) out2 = mesolve(H, E0, tlist, c_op_list, [], args=args) fid = self.fidelitycheck(out1, out2, rho0vec) assert_(max(abs(1.0 - fid)) < me_error, True)
def run_simulation(self, initial_state, Bstart, Bstop, ramp_time, t_list): args = {'Bstop':Bstop, 'Bstart':Bstart, 'ramp_time':ramp_time } print 'Solving' data = mesolve(self.H, initial_state, t_list, [], [], args = args, options = self.opts) print 'Done Solving' return data
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 _integrate(L, E0, ti, tf, opt=qt.Options()): """ Basic ode integrator """ opt.store_final_state = True if tf > ti: sol = qt.mesolve(L, E0, [ti, tf], [], [], options=opt) return sol.final_state else: return E0
def correlation_ss_ode(H, tlist, c_op_list, a_op, b_op, rho0=None): """ Internal function for calculating correlation functions using the master equation solver. See :func:`correlation_ss` usage. """ L = liouvillian(H, c_op_list) if rho0 == None: rho0 = steady(L) return mesolve(H, b_op * rho0, tlist, c_op_list, [a_op]).expect[0]
def test_driven_tls(datadir): hs = local_space('tls', namespace='sys', basis=('g', 'e')) w = symbols(r'\omega', real=True) pi = sympy.pi cos = sympy.cos t, T, E0 = symbols('t, T, E_0', real=True) a = 0.16 blackman = 0.5 * (1 - a - cos(2*pi * t/T) + a*cos(4*pi*t/T)) H0 = Destroy(hs).dag() * Destroy(hs) H1 = LocalSigma(hs, 'g', 'e') + LocalSigma(hs, 'e', 'g') H = w*H0 + 0.5 * E0 * blackman * H1 circuit = SLH(identity_matrix(0), [], H) num_vals = {w: 1.0, T:10.0, E0:1.0*2*np.pi} # test qutip conversion H_qutip, Ls = circuit.substitute(num_vals).HL_to_qutip(time_symbol=t) assert len(Ls) == 0 assert len(H_qutip) == 3 times = np.linspace(0, num_vals[T], 201) psi0 = qutip.basis(2, 1) states = qutip.mesolve(H_qutip, psi0, times, [], []).states pop0 = np.array(qutip_population(states, state=0)) pop1 = np.array(qutip_population(states, state=1)) datfile = os.path.join(datadir, 'pops.dat') #print("DATFILE: %s" % datfile) #np.savetxt(datfile, np.c_[times, pop0, pop1, pop0+pop1]) pop0_expect, pop1_expect = np.genfromtxt(datfile, unpack=True, usecols=(1,2)) assert np.max(np.abs(pop0 - pop0_expect)) < 1e-12 assert np.max(np.abs(pop1 - pop1_expect)) < 1e-12 # Test QSD conversion codegen = QSDCodeGen(circuit, num_vals=num_vals, time_symbol=t) codegen.add_observable(LocalSigma(hs, 'e', 'e'), name='P_e') psi0 = BasisKet(hs, 'e') codegen.set_trajectories(psi_initial=psi0, stepper='AdaptiveStep', dt=0.01, nt_plot_step=5, n_plot_steps=200, n_trajectories=1) scode = codegen.generate_code() compile_cmd = _cmd_list_to_str(codegen._build_compile_cmd( qsd_lib='$HOME/local/lib/libqsd.a', qsd_headers='$HOME/local/include/qsd/', executable='test_driven_tls', path='$HOME/bin', compiler='mpiCC', compile_options='-g -O0')) print(compile_cmd) codefile = os.path.join(datadir, "test_driven_tls.cc") #print("CODEFILE: %s" % codefile) #with(open(codefile, 'w')) as out_fh: #out_fh.write(scode) #out_fh.write("\n") with open(codefile) as in_fh: scode_expected = in_fh.read() assert scode.strip() == scode_expected.strip()
def get_max_trace_distance(t_list, H, dm_groundstate, dephased): ''' given a list of times, the unitary evolution hamiltonian and two density matrices, computes the maximum subsequent trace distance between the two states. ''' rhos_dephased = mesolve(H,dephased,t_list,[],[]).states trace_distances = [] for rho_dephased in rhos_dephased: trace_distances.append(tracedist(dm_groundstate.ptrace(0), rho_dephased.ptrace(0))) max_trace_distace = np.array(trace_distances).max() total_trace_distance = get_total_distance(dm_groundstate,dephased) return dm_groundstate, rhos_dephased, trace_distances, max_trace_distace, total_trace_distance
def testMETDDecayAsFuncList(self): "mesolve: time-dependence as function list with super as init cond" me_error = 1e-6 N = 10 # number of basis states to consider a = destroy(N) H = a.dag() * a psi0 = basis(N, 9) # initial state rho0vec = operator_to_vector(psi0 * psi0.dag()) E0 = sprepost(qeye(N), qeye(N)) kappa = 0.2 # coupling to oscillator def sqrt_kappa(t, args): return np.sqrt(kappa * np.exp(-t)) c_op_list = [[a, sqrt_kappa]] tlist = np.linspace(0, 10, 100) out1 = mesolve(H, psi0, tlist, c_op_list, []) out2 = mesolve(H, E0, tlist, c_op_list, []) fid = self.fidelitycheck(out1, out2, rho0vec) assert_(max(abs(1.0 - fid)) < me_error, True)
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 testMETDDecayAsFunc(self): "mesolve: time-dependence as function with super as init cond" N = 10 # number of basis states to consider a = destroy(N) H = a.dag() * a rho0 = ket2dm(basis(N, 9)) # initial state rho0vec = operator_to_vector(rho0) E0 = sprepost(qeye(N), qeye(N)) kappa = 0.2 # coupling to oscillator def Liouvillian_func(t, args): c = np.sqrt(kappa * np.exp(-t)) * a data = liouvillian(H, [c]).data return data tlist = np.linspace(0, 10, 100) args = {"kappa": kappa} out1 = mesolve(Liouvillian_func, rho0, tlist, [], [], args=args) out2 = mesolve(Liouvillian_func, E0, tlist, [], [], args=args) fid = self.fidelitycheck(out1, out2, rho0vec) assert_(max(abs(1.0 - fid)) < me_error, True)
def testMEDecaySingleExpect(self): "mesolve: simple constant decay" N = 10 # number of basis states to consider a = destroy(N) H = a.dag() * a psi0 = basis(N, 9) # initial state kappa = 0.2 # coupling to oscillator c_op_list = [np.sqrt(kappa) * a] tlist = np.linspace(0, 10, 100) medata = mesolve(H, psi0, tlist, c_op_list, a.dag() * a) expt = medata.expect[0] actual_answer = 9.0 * np.exp(-kappa * tlist) avg_diff = np.mean(abs(actual_answer - expt) / actual_answer) assert_(avg_diff < me_error)
def testMETDDecayAsArray(self): "mesolve: time-dependence as array" N = 10 a = destroy(N) H = a.dag() * a psi0 = basis(N, 9) kappa = 0.2 tlist = np.linspace(0, 10, 1000) c_op_list = [[a, np.sqrt(kappa * np.exp(-tlist))]] medata = mesolve(H, psi0, tlist, c_op_list, [a.dag() * a]) expt = medata.expect[0] actual_answer = 9.0 * np.exp(-kappa * (1.0 - np.exp(-tlist))) avg_diff = np.mean(abs(actual_answer - expt) / actual_answer) assert_(avg_diff < 100 * me_error)
def free_evolution(rho0, delta, time, c_op_list = [], return_op_list = []): '''Free evolution of an atom + oscillator system under a master equation @ var rho0: initial density matrix @ var delta: detunning @ var time: list of free evolution times @var c_op_list: collapse operators for the master equation treatment @ var return_op_list: 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)) H = delta * a.dag() * a output = mesolve(H, rho0, time, c_op_list, return_op_list) return time, output