def rhot(self, rho0, t, tau): """ Compute the reduced system density matrix :math:`\\rho(t)` Parameters ---------- rho0 : :class:`qutip.Qobj` initial density matrix or state vector (ket) t : float current time tau : float time-delay Returns ------- : :class:`qutip.Qobj` density matrix at time :math:`t` """ if qt.isket(rho0): rho0 = qt.ket2dm(rho0) E = self.propagator(t, tau) rhovec = qt.operator_to_vector(rho0) return qt.vector_to_operator(E*rhovec)
def test_spin_output(func): assert qutip.isket(func(1.0, 0, type='ket')) assert qutip.isbra(func(1.0, 0, type='bra')) assert qutip.isoper(func(1.0, 0, type='dm')) with pytest.raises(ValueError) as e: func(1.0, 0, type='something') assert str(e.value) == "invalid value keyword argument 'type'"
def mesolve(H, rho0, tlist, c_ops=None, e_ops=None, dims={}, t_dep_fL={}, coupling_fL={}, max_step_size=0.1, rtol=1e-6, atol=1e-10): """ Mimic the interface of qutip's mesolve """ lhsL, rhsL, e_op_outL = makeMESymb(H, c_opL=c_ops, e_opL=e_ops) ode_s = ivp.ODESolver(dict(zip(lhsL, rhsL)), dims=dims, driving_syms=list(t_dep_fL.keys())) ode_s.set_driving(t_dep_fL) #ode_s.set_state_dep() # Convert a qobj state input to a density matrix if q.isket(rho0): rho0 = rho0 * rho0.dag() if q.isoper(rho0): rho0 = toDense(rho0) rho0 = Dia(rho0) + Coh(rho0) ode_s.set_initial_conditions(rho0) e_op_f_L = [ sm.lambdify(ode_s.symsD['prop_state_syms'], e_op) for e_op in e_op_outL ] def calc_expectation_vals(state): return [f(*state) for f in e_op_f_L] ode_s.set_online_processing(calc_expectation_vals) ode_s.setup() out = ode_s.integrate(tlist, max_step_size=max_step_size, atol=atol, rtol=rtol) state_res = np.array(ode_s.outputL).squeeze() # Should do something about expectation values here. Probably evaluate them #if e_op_outL: #f = sm.lambdify(ode_s.state_syms, e_op_outL) #return f(state_res) return state_res
def ttmsolve(dynmaps, rho0, times, e_ops=[], learningtimes=None, tensors=None, **kwargs): """ Solve time-evolution using the Transfer Tensor Method, based on a set of precomputed dynamical maps. Parameters ---------- dynmaps : list of :class:`qutip.Qobj` List of precomputed dynamical maps (superoperators), or a callback function that returns the superoperator at a given time. rho0 : :class:`qutip.Qobj` Initial density matrix or state vector (ket). times : array_like list of times :math:`t_n` at which to compute :math:`\\rho(t_n)`. Must be uniformily spaced. e_ops : list of :class:`qutip.Qobj` / callback function single operator or list of operators for which to evaluate expectation values. learningtimes : array_like list of times :math:`t_k` for which we have knowledge of the dynamical maps :math:`E(t_k)`. tensors : array_like optional list of precomputed tensors :math:`T_k` kwargs : dictionary Optional keyword arguments. See :class:`qutip.nonmarkov.ttm.TTMSolverOptions`. Returns ------- output: :class:`qutip.solver.Result` An instance of the class :class:`qutip.solver.Result`. """ opt = TTMSolverOptions(dynmaps=dynmaps, times=times, learningtimes=learningtimes, **kwargs) diff = None if isket(rho0): rho0 = ket2dm(rho0) output = Result() e_sops_data = [] if callable(e_ops): n_expt_op = 0 expt_callback = True else: try: tmp = e_ops[:] del tmp n_expt_op = len(e_ops) expt_callback = False if n_expt_op == 0: # fall back on storing states opt.store_states = True for op in e_ops: e_sops_data.append(spre(op).data) if op.isherm and rho0.isherm: output.expect.append(np.zeros(len(times))) else: output.expect.append(np.zeros(len(times), dtype=complex)) except TypeError: raise TypeError("Argument 'e_ops' should be a callable or" + "list-like.") if tensors is None: tensors, diff = _generatetensors(dynmaps, learningtimes, opt=opt) if rho0.isoper: # vectorize density matrix rho0vec = operator_to_vector(rho0) else: # rho0 might be a super in which case we should not vectorize rho0vec = rho0 K = len(tensors) states = [rho0vec] for n in range(1, len(times)): states.append(None) for k in range(n): if n-k < K: states[-1] += tensors[n-k]*states[k] for i, r in enumerate(states): if opt.store_states or expt_callback: if r.type == 'operator-ket': states[i] = vector_to_operator(r) else: states[i] = r if expt_callback: # use callback method e_ops(times[i], states[i]) for m in range(n_expt_op): if output.expect[m].dtype == complex: output.expect[m][i] = expect_rho_vec(e_sops_data[m], r, 0) else: output.expect[m][i] = expect_rho_vec(e_sops_data[m], r, 1) output.solver = "ttmsolve" output.times = times output.ttmconvergence = diff if opt.store_states: output.states = states return output
def ttmsolve(dynmaps, rho0, times, e_ops=[], learningtimes=None, tensors=None, **kwargs): """ Solve time-evolution using the Transfer Tensor Method, based on a set of precomputed dynamical maps. Parameters ---------- dynmaps : list of :class:`qutip.Qobj` List of precomputed dynamical maps (superoperators), or a callback function that returns the superoperator at a given time. rho0 : :class:`qutip.Qobj` Initial density matrix or state vector (ket). times : array_like list of times :math:`t_n` at which to compute :math:`\\rho(t_n)`. Must be uniformily spaced. e_ops : list of :class:`qutip.Qobj` / callback function single operator or list of operators for which to evaluate expectation values. learningtimes : array_like list of times :math:`t_k` for which we have knowledge of the dynamical maps :math:`E(t_k)`. tensors : array_like optional list of precomputed tensors :math:`T_k` kwargs : dictionary Optional keyword arguments. See :class:`qutip.nonmarkov.ttm.TTMSolverOptions`. Returns ------- output: :class:`qutip.solver.Result` An instance of the class :class:`qutip.solver.Result`. """ opt = TTMSolverOptions(dynmaps=dynmaps, times=times, learningtimes=learningtimes, **kwargs) diff = None if isket(rho0): rho0 = ket2dm(rho0) output = Result() e_sops_data = [] if callable(e_ops): n_expt_op = 0 expt_callback = True else: try: tmp = e_ops[:] del tmp n_expt_op = len(e_ops) expt_callback = False if n_expt_op == 0: # fall back on storing states opt.store_states = True for op in e_ops: e_sops_data.append(spre(op).data) if op.isherm and rho0.isherm: output.expect.append(np.zeros(len(times))) else: output.expect.append(np.zeros(len(times), dtype=complex)) except TypeError: raise TypeError("Argument 'e_ops' should be a callable or" + "list-like.") if tensors is None: tensors, diff = _generatetensors(dynmaps, learningtimes, opt=opt) rho0vec = operator_to_vector(rho0) K = len(tensors) states = [rho0vec] for n in range(1, len(times)): states.append(None) for k in range(n): if n-k < K: states[-1] += tensors[n-k]*states[k] for i, r in enumerate(states): if opt.store_states or expt_callback: if r.type == 'operator-ket': states[i] = vector_to_operator(r) else: states[i] = r if expt_callback: # use callback method e_ops(times[i], states[i]) for m in range(n_expt_op): if output.expect[m].dtype == complex: output.expect[m][i] = expect_rho_vec(e_sops_data[m], r, 0) else: output.expect[m][i] = expect_rho_vec(e_sops_data[m], r, 1) output.solver = "ttmsolve" output.times = times output.ttmconvergence = diff if opt.store_states: output.states = states return output