def _spectrum_es(H, wlist, c_ops, a_op, b_op): """ Internal function for calculating the spectrum of the correlation function :math:`\left<A(\\tau)B(0)\\right>`. """ if debug: print(inspect.stack()[0][3]) # construct the Liouvillian L = liouvillian(H, c_ops) # find the steady state density matrix and a_op and b_op expecation values rho0 = steadystate(L) a_op_ss = expect(a_op, rho0) b_op_ss = expect(b_op, rho0) # eseries solution for (b * rho0)(t) es = ode2es(L, b_op * rho0) # correlation corr_es = expect(a_op, es) # covariance cov_es = corr_es - np.real(np.conjugate(a_op_ss) * b_op_ss) # spectrum spectrum = esspec(cov_es, wlist) return spectrum
def add_states(self, state, kind='vector', alpha=1.0): """Add a state vector Qobj to Bloch sphere. Parameters ---------- state : Qobj Input state vector. kind : {'vector', 'point'} Type of object to plot. alpha : float, default=1. Transparency value for the vectors. Values between 0 and 1. """ if isinstance(state, Qobj): state = [state] for st in state: vec = [expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st)] if kind == 'vector': self.add_vectors(vec, alpha=alpha) elif kind == 'point': self.add_points(vec, alpha=alpha)
def add_states(self, state, kind='vector'): """Add a state vector Qobj to Bloch sphere. Parameters ---------- state : qobj Input state vector. kind : str {'vector','point'} Type of object to plot. """ if isinstance(state, Qobj): state = [state] for st in state: vec = [ expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st) ] if kind == 'vector': self.add_vectors(vec) elif kind == 'point': self.add_points(vec)
def _correlation_es_2op_1t(H, rho0, tlist, c_ops, a_op, b_op, reverse=False, args=None, options=Odeoptions()): """ Internal function for calculating correlation functions using the exponential series solver. See :func:`correlation_ss` usage. """ if debug: print(inspect.stack()[0][3]) # contruct the Liouvillian L = liouvillian(H, c_ops) # find the steady state if rho0 is None: rho0 = steadystate(L) elif rho0 and isket(rho0): rho0 = ket2dm(rho0) # evaluate the correlation function if reverse: # <A(t)B(t+tau)> solC_tau = ode2es(L, rho0 * a_op) return esval(expect(b_op, solC_tau), tlist) else: # default: <A(t+tau)B(t)> solC_tau = ode2es(L, b_op * rho0) return esval(expect(a_op, solC_tau), tlist)
def add_annotation(self, state_or_vector, text, **kwargs): """Add a text or LaTeX annotation to Bloch sphere, parametrized by a qubit state or a vector. Parameters ---------- state_or_vector : Qobj/array/list/tuple Position for the annotaion. Qobj of a qubit or a vector of 3 elements. text : str/unicode Annotation text. You can use LaTeX, but remember to use raw string e.g. r"$\\langle x \\rangle$" or escape backslashes e.g. "$\\\\langle x \\\\rangle$". **kwargs : Options as for mplot3d.axes3d.text, including: fontsize, color, horizontalalignment, verticalalignment. """ if isinstance(state_or_vector, Qobj): vec = [expect(sigmax(), state_or_vector), expect(sigmay(), state_or_vector), expect(sigmaz(), state_or_vector)] elif isinstance(state_or_vector, (list, ndarray, tuple)) \ and len(state_or_vector) == 3: vec = state_or_vector else: raise Exception("Position needs to be specified by a qubit " + "state or a 3D vector.") self.annotations.append({'position': vec, 'text': text, 'opts': kwargs})
def spectrum_ss(H, wlist, c_op_list, a_op, b_op): """ Calculate the spectrum corresponding to a correlation function :math:`\left<A(\\tau)B(0)\\right>`, i.e., the Fourier transform of the correlation function: .. math:: S(\omega) = \int_{-\infty}^{\infty} \left<A(\\tau)B(0)\\right> e^{-i\omega\\tau} d\\tau. Parameters ---------- H : :class:`qutip.qobj` system Hamiltonian. wlist : *list* / *array* list of frequencies for :math:`\\omega`. c_op_list : list of :class:`qutip.qobj` list of collapse operators. a_op : :class:`qutip.qobj` operator A. b_op : :class:`qutip.qobj` operator B. Returns ------- spectrum: *array* An *array* with spectrum :math:`S(\omega)` for the frequencies specified in `wlist`. """ # contruct the Liouvillian L = liouvillian(H, c_op_list) # find the steady state density matrix and a_op and b_op expecation values rho0 = steady(L) a_op_ss = expect(a_op, rho0) b_op_ss = expect(b_op, rho0) # eseries solution for (b * rho0)(t) es = ode2es(L, b_op * rho0) # correlation corr_es = expect(a_op, es) # covarience cov_es = corr_es - np.real(np.conjugate(a_op_ss) * b_op_ss) # spectrum spectrum = esspec(cov_es, wlist) return spectrum
def _spectrum_es(H, wlist, c_ops, a_op, b_op): """ Internal function for calculating the spectrum of the correlation function :math:`\left<A(\\tau)B(0)\\right>`. """ if debug: print(inspect.stack()[0][3]) # construct the Liouvillian L = liouvillian(H, c_ops) # find the steady state density matrix and a_op and b_op expecation values rho0 = steadystate(L) a_op_ss = expect(a_op, rho0) b_op_ss = expect(b_op, rho0) # eseries solution for (b * rho0)(t) es = ode2es(L, b_op * rho0) # correlation corr_es = expect(a_op, es) # covariance cov_es = corr_es - a_op_ss * b_op_ss # tidy up covariance (to combine, e.g., zero-frequency components that cancel) cov_es.tidyup() # spectrum spectrum = esspec(cov_es, wlist) return spectrum
def spectrum_ss(H, wlist, c_op_list, a_op, b_op): """ Calculate the spectrum corresponding to a correlation function :math:`\left<A(\\tau)B(0)\\right>`, i.e., the Fourier transform of the correlation function: .. math:: S(\omega) = \int_{-\infty}^{\infty} \left<A(\\tau)B(0)\\right> e^{-i\omega\\tau} d\\tau. Parameters ---------- H : :class:`qutip.Qobj` system Hamiltonian. wlist : *list* / *array* list of frequencies for :math:`\\omega`. c_op_list : list of :class:`qutip.Qobj` list of collapse operators. a_op : :class:`qutip.Qobj` operator A. b_op : :class:`qutip.Qobj` operator B. Returns ------- spectrum: *array* An *array* with spectrum :math:`S(\omega)` for the frequencies specified in `wlist`. """ # contruct the Liouvillian L = liouvillian(H, c_op_list) # find the steady state density matrix and a_op and b_op expecation values rho0 = steady(L) a_op_ss = expect(a_op, rho0) b_op_ss = expect(b_op, rho0) # eseries solution for (b * rho0)(t) es = ode2es(L, b_op * rho0) # correlation corr_es = expect(a_op, es) # covarience cov_es = corr_es - np.real(np.conjugate(a_op_ss) * b_op_ss) # spectrum spectrum = esspec(cov_es, wlist) return spectrum
def _smepdpsolve_single_trajectory(data, L, dt, times, N_store, N_substeps, rho_t, dims, c_ops, e_ops): """ Internal function. See smepdpsolve. """ states_list = [] rho_t = np.copy(rho_t) sigma_t = np.copy(rho_t) prng = RandomState() # todo: seed it r_jump, r_op = prng.rand(2) jump_times = [] jump_op_idx = [] for t_idx, t in enumerate(times): if e_ops: for e_idx, e in enumerate(e_ops): data.expect[e_idx, t_idx] += expect_rho_vec(e, rho_t) else: states_list.append(Qobj(vec2mat(rho_t), dims=dims)) for j in range(N_substeps): if sigma_t.norm() < r_jump: # jump occurs p = np.array([expect(c.dag() * c, rho_t) for c in c_ops]) p = np.cumsum(p / np.sum(p)) n = np.where(p >= r_op)[0][0] # apply jump rho_t = c_ops[n] * rho_t * c_ops[n].dag() rho_t /= expect(c_ops[n].dag() * c_ops[n], rho_t) sigma_t = np.copy(rho_t) # store info about jump jump_times.append(times[t_idx] + dt * j) jump_op_idx.append(n) # get new random numbers for next jump r_jump, r_op = prng.rand(2) # deterministic evolution wihtout correction for norm decay dsigma_t = spmv(L.data, sigma_t) * dt # deterministic evolution with correction for norm decay drho_t = spmv(L.data, rho_t) * dt rho_t += drho_t # increment density matrices sigma_t += dsigma_t rho_t += drho_t return states_list, jump_times, jump_op_idx
def covariance_matrix(basis, rho): """ The covariance matrix given a basis of operators. .. note:: Experimental. """ return np.array([[expect(op1*op2+op2*op1, rho)-expect(op1, rho)*expect(op2, rho) for op1 in basis] for op2 in basis])
def testOperatorListState(self): """ expect: operator list and state """ res = expect([sigmax(), sigmay(), sigmaz()], fock(2, 0)) assert_(len(res) == 3) assert_(all(abs(res - [0, 0, 1]) < 1e-12)) res = expect([sigmax(), sigmay(), sigmaz()], fock_dm(2, 1)) assert_(len(res) == 3) assert_(all(abs(res - [0, 0, -1]) < 1e-12))
def testOperatorDensityMatrix(self): """ expect: operator and density matrix """ N = 10 op_N = num(N) op_a = destroy(N) for n in range(N): e = expect(op_N, fock_dm(N, n)) assert_(e == n) assert_(type(e) == float) e = expect(op_a, fock_dm(N, n)) assert_(e == 0) assert_(type(e) == complex)
def testOperatorKet(self): """ expect: operator and ket """ N = 10 op_N = num(N) op_a = destroy(N) for n in range(N): e = expect(op_N, fock(N, n)) assert_(e == n) assert_(type(e) == float) e = expect(op_a, fock(N, n)) assert_(e == 0) assert_(type(e) == complex)
def _correlation_es_2t(H, state0, tlist, taulist, c_ops, a_op, b_op, c_op): """ Internal function for calculating the three-operator two-time correlation function: <A(t)B(t+tau)C(t)> using an exponential series solver. """ # the solvers only work for positive time differences and the correlators # require positive tau if state0 is None: rho0 = steadystate(H, c_ops) tlist = [0] elif isket(state0): rho0 = ket2dm(state0) else: rho0 = state0 if debug: print(inspect.stack()[0][3]) # contruct the Liouvillian L = liouvillian(H, c_ops) corr_mat = np.zeros([np.size(tlist), np.size(taulist)], dtype=complex) solES_t = ode2es(L, rho0) # evaluate the correlation function for t_idx in range(len(tlist)): rho_t = esval(solES_t, [tlist[t_idx]]) solES_tau = ode2es(L, c_op * rho_t * a_op) corr_mat[t_idx, :] = esval(expect(b_op, solES_tau), taulist) return corr_mat
def _ssesolve_single_trajectory(H, dt, tlist, N_store, N_substeps, psi_t, A_ops, e_ops, data, rhs, d1, d2): """ Internal function. See ssesolve. """ dW = np.sqrt(dt) * scipy.randn(len(A_ops), N_store, N_substeps) states_list = [] for t_idx, t in enumerate(tlist): if e_ops: for e_idx, e in enumerate(e_ops): data.expect[e_idx, t_idx] += expect(e, Qobj(psi_t)) else: states_list.append(Qobj(psi_t)) for j in range(N_substeps): dpsi_t = (-1.0j * dt) * (H.data * psi_t) for a_idx, A in enumerate(A_ops): dpsi_t += rhs( H.data, psi_t, A, dt, dW[a_idx, t_idx, j], d1, d2) # increment and renormalize the wave function psi_t += dpsi_t psi_t /= norm(psi_t, 2) return states_list
def correlation_es(H, rho0, tlist, taulist, c_op_list, a_op, b_op): """ Internal function for calculating correlation functions using the exponential series solver. See :func:`correlation` usage. """ # contruct the Liouvillian L = liouvillian(H, c_op_list) if rho0 == None: rho0 = steady(L) C_mat = np.zeros([np.size(tlist), np.size(taulist)], dtype=complex) solES_t = ode2es(L, rho0) for t_idx in range(len(tlist)): rho_t = esval_op(solES_t, [tlist[t_idx]]) solES_tau = ode2es(L, b_op * rho_t) C_mat[t_idx, :] = esval(expect(a_op, solES_tau), taulist) return C_mat
def correlation_matrix(basis, rho=None): """ Given a basis set of operators :math:`\\{a\\}_n`, calculate the correlation matrix: .. math:: C_{mn} = \\langle a_m a_n \\rangle Parameters ---------- basis : list of :class:`qutip.qobj.Qobj` List of operators that defines the basis for the correlation matrix. rho : :class:`qutip.qobj.Qobj` Density matrix for which to calculate the correlation matrix. If `rho` is `None`, then a matrix of correlation matrix operators is returned instead of expectation values of those operators. Returns ------- corr_mat: *array* A 2-dimensional *array* of correlation values or operators. """ if rho is None: # return array of operators return np.array([[op1 * op2 for op1 in basis] for op2 in basis], dtype=object) else: # return array of expectation values return np.array([[expect(op1 * op2, rho) for op1 in basis] for op2 in basis], dtype=object)
def testOperatorKetRand(self): """ expect: rand operator & rand ket """ for kk in range(20): N = 20 H = rand_herm(N, 0.2) psi = rand_ket(N, 0.3) out = expect(H, psi) ans = (psi.dag() * H * psi).tr() assert_(np.abs(out - ans) < 1e-14) G = rand_herm(N, 0.1) out = expect(H + 1j * G, psi) ans = (psi.dag() * (H + 1j * G) * psi).tr() assert_(np.abs(out - ans) < 1e-14)
def _smesolve_single_trajectory(L, dt, tlist, N_store, N_substeps, rho_t, A_ops, e_ops, data, rhs, d1, d2): """ Internal function. See smesolve. """ dW = np.sqrt(dt) * scipy.randn(len(A_ops), N_store, N_substeps) states_list = [] for t_idx, t in enumerate(tlist): if e_ops: for e_idx, e in enumerate(e_ops): # XXX: need to keep hilbert space structure data.expect[e_idx, t_idx] += expect(e, Qobj(vec2mat(rho_t))) else: states_list.append(Qobj(rho_t)) # dito for j in range(N_substeps): drho_t = spmv( L.data.data, L.data.indices, L.data.indptr, rho_t) * dt for a_idx, A in enumerate(A_ops): drho_t += rhs( L.data, rho_t, A, dt, dW[a_idx, t_idx, j], d1, d2) rho_t += drho_t return states_list
def _smesolve_single_trajectory(L, dt, tlist, N_store, N_substeps, rho_t, A_ops, e_ops, data, rhs, d1, d2): """ Internal function. See smesolve. """ dW = np.sqrt(dt) * scipy.randn(len(A_ops), N_store, N_substeps) states_list = [] for t_idx, t in enumerate(tlist): if e_ops: for e_idx, e in enumerate(e_ops): # XXX: need to keep hilbert space structure data.expect[e_idx, t_idx] += expect(e, Qobj(vec2mat(rho_t))) else: states_list.append(Qobj(rho_t)) # dito for j in range(N_substeps): drho_t = spmv(L.data.data, L.data.indices, L.data.indptr, rho_t) * dt for a_idx, A in enumerate(A_ops): drho_t += rhs(L.data, rho_t, A, dt, dW[a_idx, t_idx, j], d1, d2) rho_t += drho_t return states_list
def wigner_covariance_matrix(a1=None, a2=None, R=None, rho=None): """ calculate the wigner covariance matrix given the quadrature correlation matrix (R) and a state. .. note:: Experimental. """ if R != None: if rho is None: return np.array([[np.real(R[i,j]+R[j,i]) for i in range(4)] for j in range(4)]) else: return np.array([[np.real(expect(R[i,j]+R[j,i], rho)) for i in range(4)] for j in range(4)]) elif a1 != None and a2 != None: if rho != None: x1 = (a1 + a1.dag()) / np.sqrt(2) p1 = 1j * (a1 - a1.dag()) / np.sqrt(2) x2 = (a2 + a2.dag()) / np.sqrt(2) p2 = 1j * (a2 - a2.dag()) / np.sqrt(2) return covariance_matrix([x1, p1, x2, p2], rho) else: raise ValueError("Must give rho if using field operators (a1 and a2)") else: raise ValueError("Must give either field operators (a1 and a2) or a precomputed correlation matrix (R)")
def _ssesolve_single_trajectory(H, dt, tlist, N_store, N_substeps, psi_t, A_ops, e_ops, data, rhs, d1, d2): """ Internal function. See ssesolve. """ dW = np.sqrt(dt) * scipy.randn(len(A_ops), N_store, N_substeps) states_list = [] for t_idx, t in enumerate(tlist): if e_ops: for e_idx, e in enumerate(e_ops): data.expect[e_idx, t_idx] += expect(e, Qobj(psi_t)) else: states_list.append(Qobj(psi_t)) for j in range(N_substeps): dpsi_t = (-1.0j * dt) * (H.data * psi_t) for a_idx, A in enumerate(A_ops): dpsi_t += rhs(H.data, psi_t, A, dt, dW[a_idx, t_idx, j], d1, d2) # increment and renormalize the wave function psi_t += dpsi_t psi_t /= norm(psi_t, 2) return states_list
def _expectation_values( e_ops, n_expt_op, expt_callback, res, evolved_states, partitions, idx, t_idx, options, ): if options.store_states: res.states += evolved_states for t, state in zip(range(t_idx, t_idx + len(partitions[idx][1:-1])), evolved_states): if expt_callback: # use callback method res.expect.append(e_ops(t, state)) for m in range(n_expt_op): op = e_ops[m] if not isinstance(op, Qobj) and callable(op): res.expect[m][t] = op(t, state) continue res.expect[m][t] = expect(op, state) if (idx == len(partitions) - 1 and options.store_final_state and not options.store_states): res.states = [evolved_states[-1]] return res
def correlation_es(H, rho0, tlist, taulist, c_op_list, a_op, b_op): """ Internal function for calculating correlation functions using the exponential series solver. See :func:`correlation` usage. """ # contruct the Liouvillian L = liouvillian(H, c_op_list) if rho0 is None: rho0 = steady(L) C_mat = np.zeros([np.size(tlist), np.size(taulist)], dtype=complex) solES_t = ode2es(L, rho0) for t_idx in range(len(tlist)): rho_t = esval(solES_t, [tlist[t_idx]]) solES_tau = ode2es(L, b_op * rho_t) C_mat[t_idx, :] = esval(expect(a_op, solES_tau), taulist) return C_mat
def correlation_matrix(basis, rho=None): r""" Given a basis set of operators :math:`\{a\}_n`, calculate the correlation matrix: .. math:: C_{mn} = \langle a_m a_n \rangle Parameters ---------- basis : list List of operators that defines the basis for the correlation matrix. rho : Qobj Density matrix for which to calculate the correlation matrix. If `rho` is `None`, then a matrix of correlation matrix operators is returned instead of expectation values of those operators. Returns ------- corr_mat : ndarray A 2-dimensional *array* of correlation values or operators. """ if rho is None: # return array of operators out = np.empty((len(basis), len(basis)), dtype=object) for i, op2 in enumerate(basis): out[i, :] = [op1 * op2 for op1 in basis] return out else: # return array of expectation values return np.array([[expect(op1 * op2, rho) for op1 in basis] for op2 in basis])
def coherence_function_g1(H, taulist, c_ops, a_op, solver="me", args=None, options=Options(ntraj=[20, 100])): """ Calculate the normalized first-order quantum coherence function: .. math:: g^{(1)}(\\tau) = \lim_{t \to \infty} \\frac{\\langle a^\\dagger(t+\\tau)a(t)\\rangle} {\\langle a^\\dagger(t)a(t)\\rangle} using the quantum regression theorem and the evolution solver indicated by the `solver` parameter. Note: g1 is only defined for stationary statistics (uses steady state). Parameters ---------- H : :class:`qutip.qobj.Qobj` system Hamiltonian. taulist : *list* / *array* list of times for :math:`\\tau`. taulist must be positive and contain the element `0`. c_ops : list of :class:`qutip.qobj.Qobj` list of collapse operators. a_op : :class:`qutip.qobj.Qobj` The annihilation operator of the mode. solver : str choice of solver (`me` for master-equation and `es` for exponential series) options : :class:`qutip.solver.Options` solver options class. `ntraj` is taken as a two-element list because the `mc` correlator calls `mcsolve()` recursively; by default, `ntraj=[20, 100]`. `mc_corr_eps` prevents divide-by-zero errors in the `mc` correlator; by default, `mc_corr_eps=1e-10`. Returns ------- g1: *array* The normalized first-order coherence function. """ # first calculate the steady state photon number rho0 = steadystate(H, c_ops) n = np.array([expect(rho0, a_op.dag() * a_op)]) # calculate the correlation function G1 and normalize with n to obtain g1 G1 = correlation_2op_1t(H, None, taulist, c_ops, a_op.dag(), a_op, args=args, solver=solver, options=options) g1 = G1 / n return g1
def wigner_covariance_matrix(a1=None, a2=None, R=None, rho=None): """ Calculate the Wigner covariance matrix :math:`V_{ij} = \\frac{1}{2}(R_{ij} + R_{ji})`, given the quadrature correlation matrix :math:`R_{ij} = \\langle R_{i} R_{j}\\rangle - \\langle R_{i}\\rangle \\langle R_{j}\\rangle`, where :math:`R = (q_1, p_1, q_2, p_2)^T` is the vector with quadrature operators for the two modes. Alternatively, if `R = None`, and if annihilation operators `a1` and `a2` for the two modes are supplied instead, the quadrature correlation matrix is constructed from the annihilation operators before then the covariance matrix is calculated. Parameters ---------- a1 : :class:`qutip.qobj.Qobj` Field operator for mode 1. a2 : :class:`qutip.qobj.Qobj` Field operator for mode 2. R : *array* The quadrature correlation matrix. rho : :class:`qutip.qobj.Qobj` Density matrix for which to calculate the covariance matrix. Returns ------- cov_mat: *array* A 2-dimensional *array* of covariance values. """ if R is not None: if rho is None: return np.array([[0.5 * np.real(R[i, j] + R[j, i]) for i in range(4)] for j in range(4)], dtype=object) else: return np.array( [[0.5 * np.real(expect(R[i, j] + R[j, i], rho)) for i in range(4)] for j in range(4)], dtype=object ) elif a1 is not None and a2 is not None: if rho is not None: x1 = (a1 + a1.dag()) / np.sqrt(2) p1 = -1j * (a1 - a1.dag()) / np.sqrt(2) x2 = (a2 + a2.dag()) / np.sqrt(2) p2 = -1j * (a2 - a2.dag()) / np.sqrt(2) return covariance_matrix([x1, p1, x2, p2], rho) else: raise ValueError("Must give rho if using field operators " + "(a1 and a2)") else: raise ValueError("Must give either field operators (a1 and a2) " + "or a precomputed correlation matrix (R)")
def _correlation_es_2op_2t(H, rho0, tlist, taulist, c_ops, a_op, b_op, reverse=False, args=None, options=Odeoptions()): """ Internal function for calculating correlation functions using the exponential series solver. See :func:`correlation` usage. """ if debug: print(inspect.stack()[0][3]) # contruct the Liouvillian L = liouvillian(H, c_ops) if rho0 is None: rho0 = steadystate(L) elif rho0 and isket(rho0): rho0 = ket2dm(rho0) C_mat = np.zeros([np.size(tlist), np.size(taulist)], dtype=complex) solES_t = ode2es(L, rho0) # evaluate the correlation function if reverse: # <A(t)B(t+tau)> for t_idx in range(len(tlist)): rho_t = esval(solES_t, [tlist[t_idx]]) solES_tau = ode2es(L, rho_t * a_op) C_mat[t_idx, :] = esval(expect(b_op, solES_tau), taulist) else: # default: <A(t+tau)B(t)> for t_idx in range(len(tlist)): rho_t = esval(solES_t, [tlist[t_idx]]) solES_tau = ode2es(L, b_op * rho_t) C_mat[t_idx, :] = esval(expect(a_op, solES_tau), taulist) return C_mat
def essolve(H, rho0, tlist, c_op_list, expt_op_list): """ Evolution of a state vector or density matrix (`rho0`) for a given Hamiltonian (`H`) and set of collapse operators (`c_op_list`), by expressing the ODE as an exponential series. The output is either the state vector at arbitrary points in time (`tlist`), or the expectation values of the supplied operators (`expt_op_list`). Parameters ---------- H : qobj/function_type System Hamiltonian. rho0 : :class:`qutip.qobj` Initial state density matrix. tlist : list/array ``list`` of times for :math:`t`. c_op_list : list of :class:`qutip.qobj` ``list`` of :class:`qutip.qobj` collapse operators. expt_op_list : list of :class:`qutip.qobj` ``list`` of :class:`qutip.qobj` operators for which to evaluate expectation values. Returns ------- expt_array : array Expectation values of wavefunctions/density matrices for the times specified in ``tlist``. .. note:: This solver does not support time-dependent Hamiltonians. """ n_expt_op = len(expt_op_list) n_tsteps = len(tlist) # Calculate the Liouvillian if c_op_list is None or len(c_op_list) == 0: L = H else: L = liouvillian(H, c_op_list) es = ode2es(L, rho0) # evaluate the expectation values if n_expt_op == 0: result_list = [Qobj()] * n_tsteps else: result_list = np.zeros([n_expt_op, n_tsteps], dtype=complex) for n in range(0, n_expt_op): result_list[n, :] = esval(expect(expt_op_list[n], es), tlist) return result_list
def coherence_function_g2(H, rho0, taulist, c_ops, a_op, solver="me", args=None, options=Odeoptions()): """ Calculate the second-order quantum coherence function: .. math:: g^{(2)}(\\tau) = \\frac{\\langle a^\\dagger(0)a^\\dagger(\\tau)a(\\tau)a(0)\\rangle} {\\langle a^\\dagger(\\tau)a(\\tau)\\rangle \\langle a^\\dagger(0)a(0)\\rangle} Parameters ---------- H : :class:`qutip.qobj.Qobj` system Hamiltonian. rho0 : :class:`qutip.qobj.Qobj` Initial state density matrix (or state vector). If 'rho0' is 'None', then the steady state will be used as initial state. taulist : *list* / *array* list of times for :math:`\\tau`. c_ops : list of :class:`qutip.qobj.Qobj` list of collapse operators. a_op : :class:`qutip.qobj.Qobj` The annihilation operator of the mode. solver : str choice of solver (currently only 'me') Returns ------- g2, G2: tuble of *array* The normalized and unnormalized second-order coherence function. """ # first calculate the photon number if rho0 is None: rho0 = steadystate(H, c_ops) n = np.array([expect(rho0, a_op.dag() * a_op)]) else: n = mesolve( H, rho0, taulist, c_ops, [a_op.dag() * a_op], args=args, options=options).expect[0] # calculate the correlation function G2 and normalize with n to obtain g2 G2 = correlation_4op_1t(H, rho0, taulist, c_ops, a_op.dag(), a_op.dag(), a_op, a_op, solver=solver, args=args, options=options) g2 = G2 / (n[0] * n) return g2, G2
def testOperatorListStateList(self): """ expect: operator list and state list """ operators = [sigmax(), sigmay(), sigmaz(), sigmam(), sigmap()] states = [fock(2, 0), fock(2, 1), fock_dm(2, 0), fock_dm(2, 1)] res = expect(operators, states) assert_(len(res) == len(operators)) for r_idx, r in enumerate(res): assert_(isinstance(r, np.ndarray)) if operators[r_idx].isherm: assert_(r.dtype == np.float64) else: assert_(r.dtype == np.complex128) for s_idx, s in enumerate(states): assert_(r[s_idx] == expect(operators[r_idx], states[s_idx]))
def add_states(self, state, kind='vector'): """Add a state vector Qobj to Bloch sphere. Parameters ---------- state : qobj Input state vector. kind : str {'vector','point'} Type of object to plot. """ if isinstance(state, Qobj): state = [state] for st in state: vec = [expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st)] if kind == 'vector': self.add_vectors(vec) elif kind == 'point': self.add_points(vec)
def testOperatorStateList(self): """ expect: operator and state list """ N = 10 op = num(N) res = expect(op, [fock(N, n) for n in range(N)]) assert_(all(res == range(N))) assert_(isinstance(res, np.ndarray) and res.dtype == np.float64) res = expect(op, [fock_dm(N, n) for n in range(N)]) assert_(all(res == range(N))) assert_(isinstance(res, np.ndarray) and res.dtype == np.float64) op = destroy(N) res = expect(op, [fock(N, n) for n in range(N)]) assert_(all(res == np.zeros(N))) assert_(isinstance(res, np.ndarray) and res.dtype == np.complex128) res = expect(op, [fock_dm(N, n) for n in range(N)]) assert_(all(res == np.zeros(N))) assert_(isinstance(res, np.ndarray) and res.dtype == np.complex128)
def _correlation_matrix(basis, rho=None): """ The correlation matrix given a basis of operators. .. note:: Experimental. """ if rho is None: # return array of operators return np.array([[op1*op2 for op1 in basis] for op2 in basis]) else: # return array of expectation balues return np.array([[expect(op1*op2, rho) for op1 in basis] for op2 in basis])
def correlation_ss_es(H, tlist, c_op_list, a_op, b_op, rho0=None): """ Internal function for calculating correlation functions using the exponential series solver. See :func:`correlation_ss` usage. """ # contruct the Liouvillian L = liouvillian(H, c_op_list) # find the steady state if rho0 == None: rho0 = steady(L) # evaluate the correlation function solC_tau = ode2es(L, b_op * rho0) return esval(expect(a_op, solC_tau), tlist)
def correlation_ss_es(H, tlist, c_op_list, a_op, b_op, rho0=None): """ Internal function for calculating correlation functions using the exponential series solver. See :func:`correlation_ss` usage. """ # contruct the Liouvillian L = liouvillian(H, c_op_list) # find the steady state if rho0 is None: rho0 = steady(L) # evaluate the correlation function solC_tau = ode2es(L, b_op * rho0) return esval(expect(a_op, solC_tau), tlist)
def covariance_matrix(basis, rho, symmetrized=True): """ Given a basis set of operators :math:`\{a\}_n`, calculate the covariance matrix: .. math:: V_{mn} = \\frac{1}{2}\\langle a_m a_n + a_n a_m \\rangle - \\langle a_m \\rangle \\langle a_n\\rangle or, if of the optional argument `symmetrized=False`, .. math:: V_{mn} = \\langle a_m a_n\\rangle - \\langle a_m \\rangle \\langle a_n\\rangle Parameters ---------- basis : list of :class:`qutip.qobj.Qobj` List of operators that defines the basis for the covariance matrix. rho : :class:`qutip.qobj.Qobj` Density matrix for which to calculate the covariance matrix. symmetrized : *bool* Flag indicating whether the symmetrized (default) or non-symmetrized correlation matrix is to be calculated. Returns ------- corr_mat: *array* A 2-dimensional *array* of covariance values. """ if symmetrized: return np.array( [ [0.5 * expect(op1 * op2 + op2 * op1, rho) - expect(op1, rho) * expect(op2, rho) for op1 in basis] for op2 in basis ], dtype=object, ) else: return np.array( [[expect(op1 * op2, rho) - expect(op1, rho) * expect(op2, rho) for op1 in basis] for op2 in basis], dtype=object, )
def covariance_matrix(basis, rho, symmetrized=True): """ Given a basis set of operators :math:`\{a\}_n`, calculate the covariance matrix: .. math:: V_{mn} = \\frac{1}{2}\\langle a_m a_n + a_n a_m \\rangle - \\langle a_m \\rangle \\langle a_n\\rangle or, if of the optional argument `symmetrized=False`, .. math:: V_{mn} = \\langle a_m a_n\\rangle - \\langle a_m \\rangle \\langle a_n\\rangle Parameters ---------- basis : list of :class:`qutip.qobj.Qobj` List of operators that defines the basis for the covariance matrix. rho : :class:`qutip.qobj.Qobj` Density matrix for which to calculate the covariance matrix. symmetrized : *bool* Flag indicating whether the symmetrized (default) or non-symmetrized correlation matrix is to be calculated. Returns ------- corr_mat: *array* A 2-dimensional *array* of covariance values. """ if symmetrized: return np.array([[ 0.5 * expect(op1 * op2 + op2 * op1, rho) - expect(op1, rho) * expect(op2, rho) for op1 in basis ] for op2 in basis]) else: return np.array([[ expect(op1 * op2, rho) - expect(op1, rho) * expect(op2, rho) for op1 in basis ] for op2 in basis])
def add_line(self, start, end, fmt="k", **kwargs): """Adds a line segment connecting two points on the bloch sphere. The line segment is set to be a black solid line by default. Parameters ---------- start : Qobj or array-like Array with cartesian coordinates of the first point, or a state vector or density matrix that can be mapped to a point on or within the Bloch sphere. end : Qobj or array-like Array with cartesian coordinates of the second point, or a state vector or density matrix that can be mapped to a point on or within the Bloch sphere. fmt : str, default: "k" A matplotlib format string for rendering the line. **kwargs : dict Additional parameters to pass to the matplotlib .plot function when rendering this line. """ if isinstance(start, Qobj): pt1 = [ expect(sigmax(), start), expect(sigmay(), start), expect(sigmaz(), start), ] else: pt1 = start if isinstance(end, Qobj): pt2 = [ expect(sigmax(), end), expect(sigmay(), end), expect(sigmaz(), end), ] else: pt2 = end pt1 = np.asarray(pt1) pt2 = np.asarray(pt2) x = [pt1[1], pt2[1]] y = [-pt1[0], -pt2[0]] z = [pt1[2], pt2[2]] v = [x, y, z] self._lines.append([v, fmt, kwargs])
def testExpectSolverCompatibility(self): """ expect: operator list and state list """ c_ops = [0.0001 * sigmaz()] e_ops = [sigmax(), sigmay(), sigmaz(), sigmam(), sigmap()] times = np.linspace(0, 10, 100) res1 = mesolve(sigmax(), fock(2, 0), times, c_ops, e_ops) res2 = mesolve(sigmax(), fock(2, 0), times, c_ops, []) e1 = res1.expect e2 = expect(e_ops, res2.states) assert_(len(e1) == len(e2)) for n in range(len(e1)): assert_(len(e1[n]) == len(e2[n])) assert_(isinstance(e1[n], np.ndarray)) assert_(isinstance(e2[n], np.ndarray)) assert_(e1[n].dtype == e2[n].dtype) assert_(all(abs(e1[n] - e2[n]) < 1e-12))
def _generic_ode_solve(r, psi0, tlist, e_ops, opt, progress_bar, state_norm_func=None,dims=None): """ Internal function for solving ODEs. """ # # prepare output array # n_tsteps = len(tlist) dt = tlist[1] - tlist[0] output = Odedata() output.solver = "sesolve" output.times = tlist if opt.store_states: output.states = [] if isinstance(e_ops, types.FunctionType): n_expt_op = 0 expt_callback = True elif isinstance(e_ops, list): n_expt_op = len(e_ops) expt_callback = False if n_expt_op == 0: # fallback on storing states output.states = [] opt.store_states = True else: output.expect = [] output.num_expect = n_expt_op for op in e_ops: if op.isherm and psi0.isherm: output.expect.append(np.zeros(n_tsteps)) else: output.expect.append(np.zeros(n_tsteps, dtype=complex)) else: raise TypeError("Expectation parameter must be a list or a function") # # start evolution # progress_bar.start(n_tsteps) for t_idx, t in enumerate(tlist): progress_bar.update(t_idx) if not r.successful(): break if state_norm_func: data = r.y / state_norm_func(r.y) r.set_initial_value(data, r.t) if opt.store_states: output.states.append(Qobj(r.y,dims=dims)) if expt_callback: # use callback method e_ops(t, Qobj(r.y)) for m in range(n_expt_op): output.expect[m][t_idx] = expect(e_ops[m], Qobj(r.y)) # optimize r.integrate(r.t + dt) progress_bar.finished() if not opt.rhs_reuse and odeconfig.tdname is not None: try: os.remove(odeconfig.tdname + ".pyx") except: pass if opt.store_final_state: output.final_state = Qobj(r.y) return output
def floquet_markov_mesolve(R, ekets, rho0, tlist, e_ops, f_modes_table=None, options=None, floquet_basis=True): """ Solve the dynamics for the system using the Floquet-Markov master equation. """ if options is None: opt = Options() else: opt = options if opt.tidy: R.tidyup() # # check initial state # if isket(rho0): # Got a wave function as initial state: convert to density matrix. rho0 = ket2dm(rho0) # # prepare output array # n_tsteps = len(tlist) dt = tlist[1] - tlist[0] output = Result() output.solver = "fmmesolve" output.times = tlist if isinstance(e_ops, FunctionType): n_expt_op = 0 expt_callback = True elif isinstance(e_ops, list): n_expt_op = len(e_ops) expt_callback = False if n_expt_op == 0: output.states = [] else: if not f_modes_table: raise TypeError("The Floquet mode table has to be provided " + "when requesting expectation values.") output.expect = [] output.num_expect = n_expt_op for op in e_ops: if op.isherm: output.expect.append(np.zeros(n_tsteps)) else: output.expect.append(np.zeros(n_tsteps, dtype=complex)) else: raise TypeError("Expectation parameter must be a list or a function") # # transform the initial density matrix to the eigenbasis: from # computational basis to the floquet basis # if ekets is not None: rho0 = rho0.transform(ekets) # # setup integrator # initial_vector = mat2vec(rho0.full()) r = scipy.integrate.ode(cy_ode_rhs) r.set_f_params(R.data.data, R.data.indices, R.data.indptr) r.set_integrator('zvode', method=opt.method, order=opt.order, atol=opt.atol, rtol=opt.rtol, max_step=opt.max_step) r.set_initial_value(initial_vector, tlist[0]) # # start evolution # rho = Qobj(rho0) t_idx = 0 for t in tlist: if not r.successful(): break rho.data = vec2mat(r.y) if expt_callback: # use callback method if floquet_basis: e_ops(t, Qobj(rho)) else: f_modes_table_t, T = f_modes_table f_modes_t = floquet_modes_t_lookup(f_modes_table_t, t, T) e_ops(t, Qobj(rho).transform(f_modes_t, True)) else: # calculate all the expectation values, or output rho if # no operators if n_expt_op == 0: if floquet_basis: output.states.append(Qobj(rho)) else: f_modes_table_t, T = f_modes_table f_modes_t = floquet_modes_t_lookup(f_modes_table_t, t, T) output.states.append(Qobj(rho).transform(f_modes_t, True)) else: f_modes_table_t, T = f_modes_table f_modes_t = floquet_modes_t_lookup(f_modes_table_t, t, T) for m in range(0, n_expt_op): output.expect[m][t_idx] = \ expect(e_ops[m], rho.transform(f_modes_t, False)) r.integrate(r.t + dt) t_idx += 1 return output