def bloch_redfield_solve(R, ekets, rho0, tlist, e_ops=[], opt=None): """ Evolve the ODEs defined by Bloch-Redfeild master equation. """ if opt == None: opt = Odeoptions() opt.nsteps = 2500 # if opt.tidy: R.tidyup() # # check initial state # if isket(rho0): # Got a wave function as initial state: convert to density matrix. rho0 = rho0 * rho0.dag() # # prepare output array # m n_e_ops = len(e_ops) n_tsteps = len(tlist) dt = tlist[1] - tlist[0] if n_e_ops == 0: result_list = [] else: result_list = [] for op in e_ops: if op.isherm and rho0.isherm: result_list.append(zeros(n_tsteps)) else: result_list.append(zeros(n_tsteps, dtype=complex)) # # transform the initial density matrix and the e_ops opterators to the # eigenbasis # if ekets != None: rho0 = rho0.transform(ekets) for n in arange(len(e_ops)): e_ops[n] = e_ops[n].transform(ekets, False) # # setup integrator # initial_vector = mat2vec(rho0.full()) r = scipy.integrate.ode(cyq_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, #nsteps=opt.nsteps, #first_step=opt.first_step, min_step=opt.min_step, 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) # calculate all the expectation values, or output rho if no operators if n_e_ops == 0: result_list.append(Qobj(rho)) else: for m in range(0, n_e_ops): result_list[m][t_idx] = expect(e_ops[m], rho) r.integrate(r.t + dt) t_idx += 1 return result_list
def bloch_redfield_solve(R, ekets, rho0, tlist, e_ops=[], opt=None): """ Evolve the ODEs defined by Bloch-Redfeild master equation. """ if opt == None: opt = Odeoptions() opt.nsteps = 2500 # if opt.tidy: R.tidyup() # # check initial state # if isket(rho0): # Got a wave function as initial state: convert to density matrix. rho0 = rho0 * rho0.dag() # # prepare output array # m n_e_ops = len(e_ops) n_tsteps = len(tlist) dt = tlist[1]-tlist[0] if n_e_ops == 0: result_list = [] else: result_list = [] for op in e_ops: if op.isherm and rho0.isherm: result_list.append(zeros(n_tsteps)) else: result_list.append(zeros(n_tsteps,dtype=complex)) # # transform the initial density matrix and the e_ops opterators to the # eigenbasis # if ekets != None: rho0 = rho0.transform(ekets) for n in arange(len(e_ops)): e_ops[n] = e_ops[n].transform(ekets, False) # # setup integrator # initial_vector = mat2vec(rho0.full()) r = scipy.integrate.ode(cyq_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, #nsteps=opt.nsteps, #first_step=opt.first_step, min_step=opt.min_step, 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) # calculate all the expectation values, or output rho if no operators if n_e_ops == 0: result_list.append(Qobj(rho)) else: for m in range(0, n_e_ops): result_list[m][t_idx] = expect(e_ops[m], rho) r.integrate(r.t + dt) t_idx += 1 return result_list
def bloch_redfield_solve(R, ekets, rho0, tlist, e_ops=[], options=None): """ Evolve the ODEs defined by Bloch-Redfield master equation. The Bloch-Redfield tensor can be calculated by the function :func:`bloch_redfield_tensor`. Parameters ---------- R : :class:`qutip.Qobj` Bloch-Redfield tensor. ekets : array of :class:`qutip.Qobj` Array of kets that make up a basis tranformation for the eigenbasis. rho0 : :class:`qutip.Qobj` Initial density matrix. tlist : *list* / *array* List of times for :math:`t`. e_ops : list of :class:`qutip.Qobj` / callback function List of operators for which to evaluate expectation values. options : :class:`qutip.Qdeoptions` 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`. """ if options == None: options = Odeoptions() options.nsteps = 2500 # if options.tidy: R.tidyup() # # check initial state # if isket(rho0): # Got a wave function as initial state: convert to density matrix. rho0 = rho0 * rho0.dag() # # prepare output array # n_e_ops = len(e_ops) n_tsteps = len(tlist) dt = tlist[1] - tlist[0] if n_e_ops == 0: result_list = [] else: result_list = [] for op in e_ops: if op.isherm and rho0.isherm: result_list.append(np.zeros(n_tsteps)) else: result_list.append(np.zeros(n_tsteps, dtype=complex)) # # transform the initial density matrix and the e_ops opterators to the # eigenbasis # if ekets != None: rho0 = rho0.transform(ekets) for n in arange(len(e_ops)): e_ops[n] = e_ops[n].transform(ekets, False) # # setup integrator # initial_vector = mat2vec(rho0.full()) r = scipy.integrate.ode(cyq_ode_rhs) r.set_f_params(R.data.data, R.data.indices, R.data.indptr) r.set_integrator( 'zvode', method=options.method, order=options.order, atol=options.atol, rtol=options.rtol, #nsteps=options.nsteps, #first_step=options.first_step, min_step=options.min_step, max_step=options.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) # calculate all the expectation values, or output rho if no operators if n_e_ops == 0: result_list.append(Qobj(rho)) else: for m in range(0, n_e_ops): result_list[m][t_idx] = expect(e_ops[m], rho) r.integrate(r.t + dt) t_idx += 1 return result_list
def bloch_redfield_solve(R, ekets, rho0, tlist, e_ops=[], options=None): """ Evolve the ODEs defined by Bloch-Redfield master equation. The Bloch-Redfield tensor can be calculated by the function :func:`bloch_redfield_tensor`. Parameters ---------- R : :class:`qutip.Qobj` Bloch-Redfield tensor. ekets : array of :class:`qutip.Qobj` Array of kets that make up a basis tranformation for the eigenbasis. rho0 : :class:`qutip.Qobj` Initial density matrix. tlist : *list* / *array* List of times for :math:`t`. e_ops : list of :class:`qutip.Qobj` / callback function List of operators for which to evaluate expectation values. options : :class:`qutip.Qdeoptions` 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`. """ if options == None: options = Odeoptions() options.nsteps = 2500 # if options.tidy: R.tidyup() # # check initial state # if isket(rho0): # Got a wave function as initial state: convert to density matrix. rho0 = rho0 * rho0.dag() # # prepare output array # n_e_ops = len(e_ops) n_tsteps = len(tlist) dt = tlist[1]-tlist[0] if n_e_ops == 0: result_list = [] else: result_list = [] for op in e_ops: if op.isherm and rho0.isherm: result_list.append(np.zeros(n_tsteps)) else: result_list.append(np.zeros(n_tsteps,dtype=complex)) # # transform the initial density matrix and the e_ops opterators to the # eigenbasis # if ekets != None: rho0 = rho0.transform(ekets) for n in arange(len(e_ops)): e_ops[n] = e_ops[n].transform(ekets, False) # # setup integrator # initial_vector = mat2vec(rho0.full()) r = scipy.integrate.ode(cyq_ode_rhs) r.set_f_params(R.data.data, R.data.indices, R.data.indptr) r.set_integrator('zvode', method=options.method, order=options.order, atol=options.atol, rtol=options.rtol, #nsteps=options.nsteps, #first_step=options.first_step, min_step=options.min_step, max_step=options.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) # calculate all the expectation values, or output rho if no operators if n_e_ops == 0: result_list.append(Qobj(rho)) else: for m in range(0, n_e_ops): result_list[m][t_idx] = expect(e_ops[m], rho) r.integrate(r.t + dt) t_idx += 1 return result_list
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