def mesolve(H, rho0, tlist, c_ops, expt_ops, args={}, options=None): """ Master equation evolution of a density matrix for a given Hamiltonian. Evolve the state vector or density matrix (`rho0`) using a given Hamiltonian (`H`) and an [optional] set of collapse operators (`c_op_list`), by integrating the set of ordinary differential equations that define the system. In the absense of collase operators the system is evolved according to the unitary evolution of the Hamiltonian. The output is either the state vector at arbitrary points in time (`tlist`), or the expectation values of the supplied operators (`expt_ops`). If expt_ops is a callback function, it is invoked for each time in `tlist` with time and the state as arguments, and the function does not use any return values. **Time-dependent operators** For problems with time-dependent problems `H` and `c_ops` can be callback functions that takes two arguments, time and `args`, and returns the Hamiltonian or Liuovillian for the system at that point in time (*callback format*). Alternatively, `H` and `c_ops` can be a specified in a nested-list format where each element in the list is a list of length 2, containing an operator (:class:`qutip.Qobj`) at the first element and where the second element is either a string (*list string format*) or a callback function (*list callback format*) that evaluates to the time-dependent coefficient for the corresponding operator. *Examples* H = [[H0, 'sin(w*t)'], [H1, 'sin(2*w*t)']] H = [[H0, f0_t], [H1, f1_t]] where f0_t and f1_t are python functions with signature f_t(t, args). In the *list string format* and *list callback format*, the string expression and the callback function must evaluate to a real or complex number (coefficient for the corresponding operator). In all cases of time-dependent operators, `args` is a dictionary of parameters that is used when evaluating operators. It is passed to the callback functions as second argument .. note:: On using callback function: mesolve transforms all :class:`qutip.Qobj` objects to sparse matrices before handing the problem to the integrator function. In order for your callback function to work correctly, pass all :class:`qutip.Qobj` objects that are used in constructing the Hamiltonian via args. odesolve will check for :class:`qutip.Qobj` in `args` and handle the conversion to sparse matrices. All other :class:`qutip.Qobj` objects that are not passed via `args` will be passed on to the integrator to scipy who will raise an NotImplemented exception. Parameters ---------- H : :class:`qutip.Qobj` system Hamiltonian, or a callback function for time-dependent Hamiltonians. rho0 : :class:`qutip.Qobj` initial density matrix or state vector (ket). tlist : *list* / *array* list of times for :math:`t`. c_ops : list of :class:`qutip.Qobj` list of collapse operators. expt_ops : list of :class:`qutip.Qobj` / callback function list of operators for which to evaluate expectation values. args : *dictionary* dictionary of parameters for time-dependent Hamiltonians and collapse operators. options : :class:`qutip.Qdeoptions` with options for the ODE solver. Returns ------- output: :class:`qutip.Odedata` An instance of the class :class:`qutip.Odedata`, which contains either an *array* of expectation values for the times specified by `tlist`, or an *array* or state vectors or density matrices corresponding to the times in `tlist` [if `expt_ops` is an empty list], or nothing if a callback function was given inplace of operators for which to calculate the expectation values. """ # check for type (if any) of time-dependent inputs n_const, n_func, n_str = _ode_checks(H, c_ops) if options == None: _reset_odeconfig() options = Odeoptions() options.max_step = max(tlist) / 10.0 # take at least 10 steps. # # dispatch the appropriate solver # if (c_ops and len(c_ops) > 0) or not isket(rho0): # # we have collapse operators # # # find out if we are dealing with all-constant hamiltonian and # collapse operators or if we have at least one time-dependent # operator. Then delegate to appropriate solver... # if isinstance(H, Qobj): # constant hamiltonian if n_func == 0 and n_str == 0: # constant collapse operators return mesolve_const(H, rho0, tlist, c_ops, expt_ops, args, options) elif n_str > 0: # constant hamiltonian but time-dependent collapse operators in list string format return mesolve_list_str_td([H], rho0, tlist, c_ops, expt_ops, args, options) elif n_func > 0: # constant hamiltonian but time-dependent collapse operators in list function format return mesolve_list_func_td([H], rho0, tlist, c_ops, expt_ops, args, options) if isinstance(H, FunctionType): # old style time-dependence: must have constant collapse operators if n_str > 0: # or n_func > 0: raise TypeError( "Incorrect format: function-format Hamiltonian cannot be mixed with time-dependent collapse operators." ) else: return mesolve_func_td(H, rho0, tlist, c_ops, expt_ops, args, options) if isinstance(H, list): # determine if we are dealing with list of [Qobj, string] or [Qobj, function] # style time-dependences (for pure python and cython, respectively) if n_func > 0: return mesolve_list_func_td(H, rho0, tlist, c_ops, expt_ops, args, options) else: return mesolve_list_str_td(H, rho0, tlist, c_ops, expt_ops, args, options) raise TypeError( "Incorrect specification of Hamiltonian or collapse operators.") else: # # no collapse operators: unitary dynamics # if n_func > 0: return wfsolve_list_func_td(H, rho0, tlist, expt_ops, args, options) elif n_str > 0: return wfsolve_list_str_td(H, rho0, tlist, expt_ops, args, options) elif isinstance(H, FunctionType): return wfsolve_func_td(H, rho0, tlist, expt_ops, args, options) else: return wfsolve_const(H, rho0, tlist, expt_ops, args, options)
def mesolve(H, rho0, tlist, c_ops, expt_ops, args={}, options=None): """ Master equation evolution of a density matrix for a given Hamiltonian. Evolve the state vector or density matrix (`rho0`) using a given Hamiltonian (`H`) and an [optional] set of collapse operators (`c_op_list`), by integrating the set of ordinary differential equations that define the system. In the absense of collase operators the system is evolved according to the unitary evolution of the Hamiltonian. The output is either the state vector at arbitrary points in time (`tlist`), or the expectation values of the supplied operators (`expt_ops`). If expt_ops is a callback function, it is invoked for each time in `tlist` with time and the state as arguments, and the function does not use any return values. **Time-dependent operators** For problems with time-dependent problems `H` and `c_ops` can be callback functions that takes two arguments, time and `args`, and returns the Hamiltonian or Liuovillian for the system at that point in time (*callback format*). Alternatively, `H` and `c_ops` can be a specified in a nested-list format where each element in the list is a list of length 2, containing an operator (:class:`qutip.Qobj`) at the first element and where the second element is either a string (*list string format*) or a callback function (*list callback format*) that evaluates to the time-dependent coefficient for the corresponding operator. *Examples* H = [[H0, 'sin(w*t)'], [H1, 'sin(2*w*t)']] H = [[H0, f0_t], [H1, f1_t]] where f0_t and f1_t are python functions with signature f_t(t, args). In the *list string format* and *list callback format*, the string expression and the callback function must evaluate to a real or complex number (coefficient for the corresponding operator). In all cases of time-dependent operators, `args` is a dictionary of parameters that is used when evaluating operators. It is passed to the callback functions as second argument .. note:: On using callback function: mesolve transforms all :class:`qutip.Qobj` objects to sparse matrices before handing the problem to the integrator function. In order for your callback function to work correctly, pass all :class:`qutip.Qobj` objects that are used in constructing the Hamiltonian via args. odesolve will check for :class:`qutip.Qobj` in `args` and handle the conversion to sparse matrices. All other :class:`qutip.Qobj` objects that are not passed via `args` will be passed on to the integrator to scipy who will raise an NotImplemented exception. Parameters ---------- H : :class:`qutip.Qobj` system Hamiltonian, or a callback function for time-dependent Hamiltonians. rho0 : :class:`qutip.Qobj` initial density matrix or state vector (ket). tlist : *list* / *array* list of times for :math:`t`. c_ops : list of :class:`qutip.Qobj` list of collapse operators. expt_ops : list of :class:`qutip.Qobj` / callback function list of operators for which to evaluate expectation values. args : *dictionary* dictionary of parameters for time-dependent Hamiltonians and collapse operators. options : :class:`qutip.Qdeoptions` with options for the ODE solver. Returns ------- output: :class:`qutip.Odedata` An instance of the class :class:`qutip.Odedata`, which contains either an *array* of expectation values for the times specified by `tlist`, or an *array* or state vectors or density matrices corresponding to the times in `tlist` [if `expt_ops` is an empty list], or nothing if a callback function was given inplace of operators for which to calculate the expectation values. """ # check for type (if any) of time-dependent inputs n_const,n_func,n_str=_ode_checks(H,c_ops) if options == None: _reset_odeconfig() options = Odeoptions() options.max_step = max(tlist)/10.0 # take at least 10 steps. # # dispatch the appropriate solver # if (c_ops and len(c_ops) > 0) or not isket(rho0): # # we have collapse operators # # # find out if we are dealing with all-constant hamiltonian and # collapse operators or if we have at least one time-dependent # operator. Then delegate to appropriate solver... # if isinstance(H, Qobj): # constant hamiltonian if n_func == 0 and n_str == 0: # constant collapse operators return mesolve_const(H, rho0, tlist, c_ops, expt_ops, args, options) elif n_str > 0: # constant hamiltonian but time-dependent collapse operators in list string format return mesolve_list_str_td([H], rho0, tlist, c_ops, expt_ops, args, options) elif n_func > 0: # constant hamiltonian but time-dependent collapse operators in list function format return mesolve_list_func_td([H], rho0, tlist, c_ops, expt_ops, args, options) if isinstance(H, FunctionType): # old style time-dependence: must have constant collapse operators if n_str > 0: # or n_func > 0: raise TypeError("Incorrect format: function-format Hamiltonian cannot be mixed with time-dependent collapse operators.") else: return mesolve_func_td(H, rho0, tlist, c_ops, expt_ops, args, options) if isinstance(H, list): # determine if we are dealing with list of [Qobj, string] or [Qobj, function] # style time-dependences (for pure python and cython, respectively) if n_func > 0: return mesolve_list_func_td(H, rho0, tlist, c_ops, expt_ops, args, options) else: return mesolve_list_str_td(H, rho0, tlist, c_ops, expt_ops, args, options) raise TypeError("Incorrect specification of Hamiltonian or collapse operators.") else: # # no collapse operators: unitary dynamics # if n_func > 0: return wfsolve_list_func_td(H, rho0, tlist, expt_ops, args, options) elif n_str > 0: return wfsolve_list_str_td(H, rho0, tlist, expt_ops, args, options) elif isinstance(H, FunctionType): return wfsolve_func_td(H, rho0, tlist, expt_ops, args, options) else: return wfsolve_const(H, rho0, tlist, expt_ops, args, options)
def odesolve(H, rho0, tlist, c_op_list, expt_ops, H_args=None, options=None): """ Master equation evolution of a density matrix for a given Hamiltonian. Evolution of a state vector or density matrix (`rho0`) for a given Hamiltonian (`H`) and set of collapse operators (`c_op_list`), by integrating the set of ordinary differential equations that define the system. The output is either the state vector at arbitrary points in time (`tlist`), or the expectation values of the supplied operators (`expt_ops`). For problems with time-dependent Hamiltonians, `H` can be a callback function that takes two arguments, time and `H_args`, and returns the Hamiltonian at that point in time. `H_args` is a list of parameters that is passed to the callback function `H` (only used for time-dependent Hamiltonians). Parameters ---------- H : :class:`qutip.Qobj` system Hamiltonian, or a callback function for time-dependent Hamiltonians. rho0 : :class:`qutip.Qobj` initial density matrix or state vector (ket). tlist : *list* / *array* list of times for :math:`t`. c_op_list : list of :class:`qutip.Qobj` list of collapse operators. expt_ops : list of :class:`qutip.Qobj` / callback function list of operators for which to evaluate expectation values. H_args : *dictionary* dictionary of parameters for time-dependent Hamiltonians and collapse operators. options : :class:`qutip.Qdeoptions` with options for the ODE solver. Returns ------- output :array Expectation values of wavefunctions/density matrices for the times specified by `tlist`. Notes ----- On using callback function: odesolve transforms all :class:`qutip.Qobj` objects to sparse matrices before handing the problem to the integrator function. In order for your callback function to work correctly, pass all :class:`qutip.Qobj` objects that are used in constructing the Hamiltonian via H_args. odesolve will check for :class:`qutip.Qobj` in `H_args` and handle the conversion to sparse matrices. All other :class:`qutip.Qobj` objects that are not passed via `H_args` will be passed on to the integrator to scipy who will raise an NotImplemented exception. Depreciated in QuTiP 2.0.0. Use :func:`mesolve` instead. """ if options == None: options = Odeoptions() options.nsteps = 2500 # options.max_step = max(tlist) / 10.0 # take at least 10 steps.. if (c_op_list and len(c_op_list) > 0) or not isket(rho0): if isinstance(H, list): output = mesolve_list_td(H, rho0, tlist, c_op_list, expt_ops, H_args, options) if isinstance(H, FunctionType): output = mesolve_func_td(H, rho0, tlist, c_op_list, expt_ops, H_args, options) else: output = mesolve_const(H, rho0, tlist, c_op_list, expt_ops, H_args, options) else: if isinstance(H, list): output = wfsolve_list_td(H, rho0, tlist, expt_ops, H_args, options) if isinstance(H, FunctionType): output = wfsolve_func_td(H, rho0, tlist, expt_ops, H_args, options) else: output = wfsolve_const(H, rho0, tlist, expt_ops, H_args, options) if len(expt_ops) > 0: return output.expect else: return output.states
def odesolve(H, rho0, tlist, c_op_list, expt_ops, H_args=None, options=None): """ Master equation evolution of a density matrix for a given Hamiltonian. Evolution of a state vector or density matrix (`rho0`) for a given Hamiltonian (`H`) and set of collapse operators (`c_op_list`), by integrating the set of ordinary differential equations that define the system. The output is either the state vector at arbitrary points in time (`tlist`), or the expectation values of the supplied operators (`expt_ops`). For problems with time-dependent Hamiltonians, `H` can be a callback function that takes two arguments, time and `H_args`, and returns the Hamiltonian at that point in time. `H_args` is a list of parameters that is passed to the callback function `H` (only used for time-dependent Hamiltonians). Parameters ---------- H : :class:`qutip.Qobj` system Hamiltonian, or a callback function for time-dependent Hamiltonians. rho0 : :class:`qutip.Qobj` initial density matrix or state vector (ket). tlist : *list* / *array* list of times for :math:`t`. c_op_list : list of :class:`qutip.Qobj` list of collapse operators. expt_ops : list of :class:`qutip.Qobj` / callback function list of operators for which to evaluate expectation values. H_args : *dictionary* dictionary of parameters for time-dependent Hamiltonians and collapse operators. options : :class:`qutip.Qdeoptions` with options for the ODE solver. Returns ------- output :array Expectation values of wavefunctions/density matrices for the times specified by `tlist`. Notes ----- On using callback function: odesolve transforms all :class:`qutip.Qobj` objects to sparse matrices before handing the problem to the integrator function. In order for your callback function to work correctly, pass all :class:`qutip.Qobj` objects that are used in constructing the Hamiltonian via H_args. odesolve will check for :class:`qutip.Qobj` in `H_args` and handle the conversion to sparse matrices. All other :class:`qutip.Qobj` objects that are not passed via `H_args` will be passed on to the integrator to scipy who will raise an NotImplemented exception. Depreciated in QuTiP 2.0.0. Use :func:`mesolve` instead. """ if options == None: options = Odeoptions() options.nsteps = 2500 # options.max_step = max(tlist)/10.0 # take at least 10 steps.. if (c_op_list and len(c_op_list) > 0) or not isket(rho0): if isinstance(H, list): output = mesolve_list_td(H, rho0, tlist, c_op_list, expt_ops, H_args, options) if isinstance(H, FunctionType): output = mesolve_func_td(H, rho0, tlist, c_op_list, expt_ops, H_args, options) else: output = mesolve_const(H, rho0, tlist, c_op_list, expt_ops, H_args, options) else: if isinstance(H, list): output = wfsolve_list_td(H, rho0, tlist, expt_ops, H_args, options) if isinstance(H, FunctionType): output = wfsolve_func_td(H, rho0, tlist, expt_ops, H_args, options) else: output = wfsolve_const(H, rho0, tlist, expt_ops, H_args, options) if len(expt_ops) > 0: return output.expect else: return output.states