def setODEChecksMC(self): #define operators H = rand_herm(10) c_op = qeye(10) def f_c_op(t, args): return 0 def f_H(t, args): return 0 #check constant H and no C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [], 'mc') self.assertTrue(time_type=0) #check constant H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [c_op], 'mc') self.assertTrue(time_type=0) #check constant H and str C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [c_op, '1'], 'mc') self.assertTrue(time_type=1) #check constant H and func C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [f_c_op], 'mc') self.assertTrue(time_type=2) # # #check str H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks([H, '1'], [c_op], 'mc') self.assertTrue(time_type=10) #check str H and str C_ops time_type, h_stuff, c_stuff = _ode_checks([H, '1'], [c_op, '1'], 'mc') self.assertTrue(time_type=11) #check str H and func C_ops time_type, h_stuff, c_stuff = _ode_checks([H, '1'], [f_c_op], 'mc') self.assertTrue(time_type=12) # # #check func H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [c_op], 'mc') self.assertTrue(time_type=20) #check func H and str C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [c_op, '1'], 'mc') self.assertTrue(time_type=21) #check func H and func C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [f_c_op], 'mc') self.assertTrue(time_type=22)
def setODEChecksMC(self): #define operators H=rand_herm(10) c_op=qeye(10) def f_c_op(t,args):return 0 def f_H(t,args):return 0 #check constant H and no C_ops time_type,h_stuff,c_stuff=_ode_checks(H,[],'mc') self.assertTrue(time_type=0) #check constant H and constant C_ops time_type,h_stuff,c_stuff=_ode_checks(H,[c_op],'mc') self.assertTrue(time_type=0) #check constant H and str C_ops time_type,h_stuff,c_stuff=_ode_checks(H,[c_op,'1'],'mc') self.assertTrue(time_type=1) #check constant H and func C_ops time_type,h_stuff,c_stuff=_ode_checks(H,[f_c_op],'mc') self.assertTrue(time_type=2) # # #check str H and constant C_ops time_type,h_stuff,c_stuff=_ode_checks([H,'1'],[c_op],'mc') self.assertTrue(time_type=10) #check str H and str C_ops time_type,h_stuff,c_stuff=_ode_checks([H,'1'],[c_op,'1'],'mc') self.assertTrue(time_type=11) #check str H and func C_ops time_type,h_stuff,c_stuff=_ode_checks([H,'1'],[f_c_op],'mc') self.assertTrue(time_type=12) # # #check func H and constant C_ops time_type,h_stuff,c_stuff=_ode_checks(f_H,[c_op],'mc') self.assertTrue(time_type=20) #check func H and str C_ops time_type,h_stuff,c_stuff=_ode_checks(f_H,[c_op,'1'],'mc') self.assertTrue(time_type=21) #check func H and func C_ops time_type,h_stuff,c_stuff=_ode_checks(f_H,[f_c_op],'mc') self.assertTrue(time_type=22)
def test_setODEChecksMC(): "odechecks: monte-carlo" # define operators H = rand_herm(10) c_op = qeye(10) def f_c_op(t, args): return 0 def f_H(t, args): return 0 # check constant H and no C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [], "mc") assert_(time_type == 0) # check constant H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [c_op], "mc") assert_(time_type == 0) # check constant H and str C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [c_op, "1"], "mc") # assert_(time_type==1) # this test fails!! # check constant H and func C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [f_c_op], "mc") # assert_(time_type==2) # FAILURE # check str H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks([H, "1"], [c_op], "mc") # assert_(time_type==10) # check str H and str C_ops time_type, h_stuff, c_stuff = _ode_checks([H, "1"], [c_op, "1"], "mc") # assert_(time_type==11) # check str H and func C_ops time_type, h_stuff, c_stuff = _ode_checks([H, "1"], [f_c_op], "mc") # assert_(time_type==12) # check func H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [c_op], "mc") # assert_(time_type==20) # check func H and str C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [c_op, "1"], "mc") # assert_(time_type==21) # check func H and func C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [f_c_op], "mc")
def test_setODEChecksMC(): "odechecks: monte-carlo" #define operators H = rand_herm(10) c_op = qeye(10) def f_c_op(t, args): return 0 def f_H(t, args): return 0 #check constant H and no C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [], 'mc') assert_(time_type == 0) #check constant H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [c_op], 'mc') assert_(time_type == 0) #check constant H and str C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [c_op, '1'], 'mc') #assert_(time_type==1) # this test fails!! #check constant H and func C_ops time_type, h_stuff, c_stuff = _ode_checks(H, [f_c_op], 'mc') #assert_(time_type==2) # FAILURE #check str H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks([H, '1'], [c_op], 'mc') #assert_(time_type==10) #check str H and str C_ops time_type, h_stuff, c_stuff = _ode_checks([H, '1'], [c_op, '1'], 'mc') #assert_(time_type==11) #check str H and func C_ops time_type, h_stuff, c_stuff = _ode_checks([H, '1'], [f_c_op], 'mc') #assert_(time_type==12) #check func H and constant C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [c_op], 'mc') #assert_(time_type==20) #check func H and str C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [c_op, '1'], 'mc') #assert_(time_type==21) #check func H and func C_ops time_type, h_stuff, c_stuff = _ode_checks(f_H, [f_c_op], 'mc')
def sesolve(H, rho0, tlist, e_ops, args={}, options=None, progress_bar=BaseProgressBar()): """ Schrodinger equation evolution of a state vector for a given Hamiltonian. Evolve the state vector or density matrix (`rho0`) using a given Hamiltonian (`H`), 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 (`e_ops`). If e_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. 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`. e_ops : list of :class:`qutip.qobj` / callback function single single operator or 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 `e_ops` is an empty list], or nothing if a callback function was given inplace of operators for which to calculate the expectation values. """ if isinstance(e_ops, Qobj): e_ops = [e_ops] if isinstance(e_ops, dict): e_ops_dict = e_ops e_ops = [e for e in e_ops.values()] else: e_ops_dict = None # check for type (if any) of time-dependent inputs n_const, n_func, n_str = _ode_checks(H, []) if options is None: options = Odeoptions() if (not options.rhs_reuse) or (not odeconfig.tdfunc): # reset odeconfig time-dependence flags to default values odeconfig.reset() if n_func > 0: res = _sesolve_list_func_td(H, rho0, tlist, e_ops, args, options, progress_bar) elif n_str > 0: res = _sesolve_list_str_td(H, rho0, tlist, e_ops, args, options, progress_bar) elif isinstance(H, (types.FunctionType, types.BuiltinFunctionType, partial)): res = _sesolve_func_td(H, rho0, tlist, e_ops, args, options, progress_bar) else: res = _sesolve_const(H, rho0, tlist, e_ops, args, options, progress_bar) if e_ops_dict: res.expect = {e: res.expect[n] for n, e in enumerate(e_ops_dict.keys())} return res
def mesolve(H, rho0, tlist, c_ops, e_ops, args={}, options=None, progress_bar=BaseProgressBar()): """ 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 (`e_ops`). If e_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:: If an element in the list-specification of the Hamiltonian or the list of collapse operators are in super-operator for it will be added to the total Liouvillian of the problem with out further transformation. This allows for using mesolve for solving master equations that are not on standard Lindblad form. .. 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` single collapse operator, or list of collapse operators. e_ops : list of :class:`qutip.qobj` / callback function single single operator or list of operators for which to evaluate expectation values. args : *dictionary* dictionary of parameters for time-dependent Hamiltonians and collapse operators. options : :class:`qutip.Odeoptions` 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 `e_ops` is an empty list], or nothing if a callback function was given inplace of operators for which to calculate the expectation values. """ # check whether c_ops or e_ops is is a single operator # if so convert it to a list containing only that operator if isinstance(c_ops, Qobj): c_ops = [c_ops] if isinstance(e_ops, Qobj): e_ops = [e_ops] if isinstance(e_ops, dict): e_ops_dict = e_ops e_ops = [e for e in e_ops.values()] else: e_ops_dict = None # check for type (if any) of time-dependent inputs n_const, n_func, n_str = _ode_checks(H, c_ops) if options is None: options = Odeoptions() if (not options.rhs_reuse) or (not odeconfig.tdfunc): # reset odeconfig collapse and time-dependence flags to default values odeconfig.reset() res = None # # dispatch the appropriate solver # if ((c_ops and len(c_ops) > 0) or (not isket(rho0)) or (isinstance(H, Qobj) and issuper(H)) or (isinstance(H, list) and isinstance(H[0], Qobj) and issuper(H[0]))): # # 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 res = _mesolve_const(H, rho0, tlist, c_ops, e_ops, args, options, progress_bar) elif n_str > 0: # constant hamiltonian but time-dependent collapse # operators in list string format res = _mesolve_list_str_td([H], rho0, tlist, c_ops, e_ops, args, options, progress_bar) elif n_func > 0: # constant hamiltonian but time-dependent collapse # operators in list function format res = _mesolve_list_func_td([H], rho0, tlist, c_ops, e_ops, args, options, progress_bar) elif isinstance(H, (types.FunctionType, types.BuiltinFunctionType, partial)): # 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: res = _mesolve_func_td(H, rho0, tlist, c_ops, e_ops, args, options, progress_bar) elif isinstance(H, list): # determine if we are dealing with list of [Qobj, string] or # [Qobj, function] style time-dependencies (for pure python and # cython, respectively) if n_func > 0: res = _mesolve_list_func_td(H, rho0, tlist, c_ops, e_ops, args, options, progress_bar) else: res = _mesolve_list_str_td(H, rho0, tlist, c_ops, e_ops, args, options, progress_bar) else: raise TypeError("Incorrect specification of Hamiltonian " + "or collapse operators.") else: # # no collapse operators: unitary dynamics # if n_func > 0: res = _sesolve_list_func_td(H, rho0, tlist, e_ops, args, options, progress_bar) elif n_str > 0: res = _sesolve_list_str_td(H, rho0, tlist, e_ops, args, options, progress_bar) elif isinstance(H, (types.FunctionType, types.BuiltinFunctionType, partial)): res = _sesolve_func_td(H, rho0, tlist, e_ops, args, options, progress_bar) else: res = _sesolve_const(H, rho0, tlist, e_ops, args, options, progress_bar) if e_ops_dict: res.expect = {e: res.expect[n] for n, e in enumerate(e_ops_dict.keys())} return res
def mesolve(H, rho0, tlist, c_ops, e_ops, args={}, options=None, progress_bar=BaseProgressBar()): """ 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 (`e_ops`). If e_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:: If an element in the list-specification of the Hamiltonian or the list of collapse operators are in super-operator for it will be added to the total Liouvillian of the problem with out further transformation. This allows for using mesolve for solving master equations that are not on standard Lindblad form. .. 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` single collapse operator, or list of collapse operators. e_ops : list of :class:`qutip.qobj` / callback function single single operator or list of operators for which to evaluate expectation values. args : *dictionary* dictionary of parameters for time-dependent Hamiltonians and collapse operators. options : :class:`qutip.Odeoptions` 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 `e_ops` is an empty list], or nothing if a callback function was given inplace of operators for which to calculate the expectation values. """ # check whether c_ops or e_ops is is a single operator # if so convert it to a list containing only that operator if isinstance(c_ops, Qobj): c_ops = [c_ops] if isinstance(e_ops, Qobj): e_ops = [e_ops] if isinstance(e_ops, dict): e_ops_dict = e_ops e_ops = [e for e in e_ops.values()] else: e_ops_dict = None # check for type (if any) of time-dependent inputs n_const, n_func, n_str = _ode_checks(H, c_ops) if options is None: options = Odeoptions() if (not options.rhs_reuse) or (not odeconfig.tdfunc): # reset odeconfig collapse and time-dependence flags to default values odeconfig.reset() res = None # # dispatch the appropriate solver # if ((c_ops and len(c_ops) > 0) or (not isket(rho0)) or (isinstance(H, Qobj) and issuper(H)) or (isinstance(H, list) and isinstance(H[0], Qobj) and issuper(H[0]))): # # 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 res = _mesolve_const(H, rho0, tlist, c_ops, e_ops, args, options, progress_bar) elif n_str > 0: # constant hamiltonian but time-dependent collapse # operators in list string format res = _mesolve_list_str_td([H], rho0, tlist, c_ops, e_ops, args, options, progress_bar) elif n_func > 0: # constant hamiltonian but time-dependent collapse # operators in list function format res = _mesolve_list_func_td([H], rho0, tlist, c_ops, e_ops, args, options, progress_bar) elif isinstance( H, (types.FunctionType, types.BuiltinFunctionType, partial)): # 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: res = _mesolve_func_td(H, rho0, tlist, c_ops, e_ops, args, options, progress_bar) elif isinstance(H, list): # determine if we are dealing with list of [Qobj, string] or # [Qobj, function] style time-dependencies (for pure python and # cython, respectively) if n_func > 0: res = _mesolve_list_func_td(H, rho0, tlist, c_ops, e_ops, args, options, progress_bar) else: res = _mesolve_list_str_td(H, rho0, tlist, c_ops, e_ops, args, options, progress_bar) else: raise TypeError("Incorrect specification of Hamiltonian " + "or collapse operators.") else: # # no collapse operators: unitary dynamics # if n_func > 0: res = _sesolve_list_func_td(H, rho0, tlist, e_ops, args, options, progress_bar) elif n_str > 0: res = _sesolve_list_str_td(H, rho0, tlist, e_ops, args, options, progress_bar) elif isinstance( H, (types.FunctionType, types.BuiltinFunctionType, partial)): res = _sesolve_func_td(H, rho0, tlist, e_ops, args, options, progress_bar) else: res = _sesolve_const(H, rho0, tlist, e_ops, args, options, progress_bar) if e_ops_dict: res.expect = { e: res.expect[n] for n, e in enumerate(e_ops_dict.keys()) } return res
def rhs_generate(H, psi0, tlist, c_ops, e_ops, ntraj=500, args={}, options=Odeoptions(), solver="me", name=None): """ Used to generate the Cython functions for solving the dynamics of a given system before using the parfor function. Parameters ---------- H : qobj System Hamiltonian. psi0 : qobj Initial state vector tlist : array_like Times at which results are recorded. ntraj : int Number of trajectories to run. c_ops : array_like ``list`` or ``array`` of collapse operators. e_ops : array_like ``list`` or ``array`` of operators for calculating expectation values. args : dict Arguments for time-dependent Hamiltonian and collapse operator terms. options : Odeoptions Instance of ODE solver options. solver: str String indicating which solver "me" or "mc" name: str Name of generated RHS """ _reset_odeconfig() # clear odeconfig # ------------------------ # GENERATE MCSOLVER DATA # ------------------------ if solver == "mc": odeconfig.tlist = tlist if isinstance(ntraj, (list, ndarray)): odeconfig.ntraj = sort(ntraj)[-1] else: odeconfig.ntraj = ntraj # check for type of time-dependence (if any) time_type, h_stuff, c_stuff = _ode_checks(H, c_ops, "mc") h_terms = len(h_stuff[0]) + len(h_stuff[1]) + len(h_stuff[2]) c_terms = len(c_stuff[0]) + len(c_stuff[1]) + len(c_stuff[2]) # set time_type for use in multiprocessing odeconfig.tflag = time_type # check for collapse operators if c_terms > 0: odeconfig.cflag = 1 else: odeconfig.cflag = 0 # Configure data _mc_data_config(H, psi0, h_stuff, c_ops, c_stuff, args, e_ops, options) os.environ["CFLAGS"] = "-w" import pyximport pyximport.install(setup_args={"include_dirs": [numpy.get_include()]}) if odeconfig.tflag in array([1, 11]): code = compile( "from " + odeconfig.tdname + " import cyq_td_ode_rhs,col_spmv,col_expect", "<string>", "exec" ) exec(code) odeconfig.tdfunc = cyq_td_ode_rhs odeconfig.colspmv = col_spmv odeconfig.colexpect = col_expect else: code = compile("from " + odeconfig.tdname + " import cyq_td_ode_rhs", "<string>", "exec") exec(code) odeconfig.tdfunc = cyq_td_ode_rhs try: os.remove(odeconfig.tdname + ".pyx") except: print("Error removing pyx file. File not found.") # ------------------------ # GENERATE MESOLVER STUFF # ------------------------ elif solver == "me": odeconfig.tdname = "rhs" + str(odeconfig.cgen_num) cgen = Codegen(h_terms=n_L_terms, h_tdterms=Lcoeff, args=args) cgen.generate(odeconfig.tdname + ".pyx") os.environ["CFLAGS"] = "-O3 -w" import pyximport pyximport.install(setup_args={"include_dirs": [numpy.get_include()]}) code = compile("from " + odeconfig.tdname + " import cyq_td_ode_rhs", "<string>", "exec") exec(code) odeconfig.tdfunc = cyq_td_ode_rhs
def mcsolve(H,psi0,tlist,c_ops,e_ops,ntraj=500,args={},options=Odeoptions()): """Monte-Carlo evolution of a state vector :math:`|\psi \\rangle` for a given Hamiltonian and sets of collapse operators, and possibly, operators for calculating expectation values. Options for the underlying ODE solver are given by the Odeoptions class. mcsolve supports time-dependent Hamiltonians and collapse operators using either Python functions of strings to represent time-dependent coefficients. Note that, the system Hamiltonian MUST have at least one constant term. As an example of a time-dependent problem, consider a Hamiltonian with two terms ``H0`` and ``H1``, where ``H1`` is time-dependent with coefficient ``sin(w*t)``, and collapse operators ``C0`` and ``C1``, where ``C1`` is time-dependent with coeffcient ``exp(-a*t)``. Here, w and a are constant arguments with values ``W`` and ``A``. Using the Python function time-dependent format requires two Python functions, one for each collapse coefficient. Therefore, this problem could be expressed as:: def H1_coeff(t,args): return sin(args['w']*t) def C1_coeff(t,args): return exp(-args['a']*t) H=[H0,[H1,H1_coeff]] c_op_list=[C0,[C1,C1_coeff]] args={'a':A,'w':W} or in String (Cython) format we could write:: H=[H0,[H1,'sin(w*t)']] c_op_list=[C0,[C1,'exp(-a*t)']] args={'a':A,'w':W} Constant terms are preferably placed first in the Hamiltonian and collapse operator lists. Parameters ---------- H : qobj System Hamiltonian. psi0 : qobj Initial state vector tlist : array_like Times at which results are recorded. ntraj : int Number of trajectories to run. c_ops : array_like ``list`` or ``array`` of collapse operators. e_ops : array_like ``list`` or ``array`` of operators for calculating expectation values. args : dict Arguments for time-dependent Hamiltonian and collapse operator terms. options : Odeoptions Instance of ODE solver options. Returns ------- results : Odedata Object storing all results from simulation. """ if psi0.type!='ket': raise Exception("Initial state must be a state vector.") odeconfig.options=options #set num_cpus to the value given in qutip.settings if none in Odeoptions if not odeconfig.options.num_cpus: odeconfig.options.num_cpus=qutip.settings.num_cpus #set initial value data if options.tidy: odeconfig.psi0=psi0.tidyup(options.atol).full() else: odeconfig.psi0=psi0.full() odeconfig.psi0_dims=psi0.dims odeconfig.psi0_shape=psi0.shape #set general items odeconfig.tlist=tlist if isinstance(ntraj,(list,ndarray)): odeconfig.ntraj=sort(ntraj)[-1] else: odeconfig.ntraj=ntraj #---- #---------------------------------------------- # SETUP ODE DATA IF NONE EXISTS OR NOT REUSING #---------------------------------------------- if (not options.rhs_reuse) or (not odeconfig.tdfunc): #reset odeconfig collapse and time-dependence flags to default values _reset_odeconfig() #check for type of time-dependence (if any) time_type,h_stuff,c_stuff=_ode_checks(H,c_ops,'mc') h_terms=len(h_stuff[0])+len(h_stuff[1])+len(h_stuff[2]) c_terms=len(c_stuff[0])+len(c_stuff[1])+len(c_stuff[2]) #set time_type for use in multiprocessing odeconfig.tflag=time_type #-Check for PyObjC on Mac platforms if sys.platform=='darwin': try: import Foundation except: odeconfig.options.gui=False #check if running in iPython and using Cython compiling (then no GUI to work around error) if odeconfig.options.gui and odeconfig.tflag in array([1,10,11]): try: __IPYTHON__ except: pass else: odeconfig.options.gui=False if qutip.settings.qutip_gui=="NONE": odeconfig.options.gui=False #check for collapse operators if c_terms>0: odeconfig.cflag=1 else: odeconfig.cflag=0 #Configure data _mc_data_config(H,psi0,h_stuff,c_ops,c_stuff,args,e_ops,options) if odeconfig.tflag in array([1,10,11]): #compile time-depdendent RHS code os.environ['CFLAGS'] = '-w' import pyximport pyximport.install(setup_args={'include_dirs':[numpy.get_include()]}) if odeconfig.tflag in array([1,11]): code = compile('from '+odeconfig.tdname+' import cyq_td_ode_rhs,col_spmv,col_expect', '<string>', 'exec') exec(code, globals()) odeconfig.tdfunc=cyq_td_ode_rhs odeconfig.colspmv=col_spmv odeconfig.colexpect=col_expect else: code = compile('from '+odeconfig.tdname+' import cyq_td_ode_rhs', '<string>', 'exec') exec(code, globals()) odeconfig.tdfunc=cyq_td_ode_rhs try: os.remove(odeconfig.tdname+".pyx") except: print("Error removing pyx file. File not found.") elif odeconfig.tflag==0: odeconfig.tdfunc=cyq_ode_rhs else:#setup args for new parameters when rhs_reuse=True and tdfunc is given #string based if odeconfig.tflag in array([1,10,11]): if any(args): odeconfig.c_args=[] arg_items=args.items() for k in range(len(args)): odeconfig.c_args.append(arg_items[k][1]) #function based elif odeconfig.tflag in array([2,3,20,22]): odeconfig.h_func_args=args #load monte-carlo class mc=MC_class() #RUN THE SIMULATION mc.run() #AFTER MCSOLVER IS DONE -------------------------------------- #-------COLLECT AND RETURN OUTPUT DATA IN ODEDATA OBJECT --------------# output=Odedata() output.solver='mcsolve' #state vectors if any(mc.psi_out) and odeconfig.options.mc_avg: output.states=mc.psi_out #expectation values if any(mc.expect_out) and odeconfig.cflag and odeconfig.options.mc_avg:#averaging if multiple trajectories if isinstance(ntraj,int): output.expect=mean(mc.expect_out,axis=0) elif isinstance(ntraj,(list,ndarray)): output.expect=[] for num in ntraj: expt_data=mean(mc.expect_out[:num],axis=0) data_list=[] if any([op.isherm==False for op in e_ops]): for k in range(len(e_ops)): if e_ops[k].isherm: data_list.append(real(expt_data[k])) else: data_list.append(expt_data[k]) else: data_list=[data for data in expt_data] output.expect.append(data_list) else:#no averaging for single trajectory or if mc_avg flag (Odeoptions) is off output.expect=mc.expect_out #simulation parameters output.times=odeconfig.tlist output.num_expect=odeconfig.e_num output.num_collapse=odeconfig.c_num output.ntraj=odeconfig.ntraj output.col_times=mc.collapse_times_out output.col_which=mc.which_op_out return output
def mcsolve(H, psi0, tlist, c_ops, e_ops, ntraj=500, args={}, options=Odeoptions()): """Monte-Carlo evolution of a state vector :math:`|\psi \\rangle` for a given Hamiltonian and sets of collapse operators, and possibly, operators for calculating expectation values. Options for the underlying ODE solver are given by the Odeoptions class. mcsolve supports time-dependent Hamiltonians and collapse operators using either Python functions of strings to represent time-dependent coefficients. Note that, the system Hamiltonian MUST have at least one constant term. As an example of a time-dependent problem, consider a Hamiltonian with two terms ``H0`` and ``H1``, where ``H1`` is time-dependent with coefficient ``sin(w*t)``, and collapse operators ``C0`` and ``C1``, where ``C1`` is time-dependent with coeffcient ``exp(-a*t)``. Here, w and a are constant arguments with values ``W`` and ``A``. Using the Python function time-dependent format requires two Python functions, one for each collapse coefficient. Therefore, this problem could be expressed as:: def H1_coeff(t,args): return sin(args['w']*t) def C1_coeff(t,args): return exp(-args['a']*t) H=[H0,[H1,H1_coeff]] c_op_list=[C0,[C1,C1_coeff]] args={'a':A,'w':W} or in String (Cython) format we could write:: H=[H0,[H1,'sin(w*t)']] c_op_list=[C0,[C1,'exp(-a*t)']] args={'a':A,'w':W} Constant terms are preferably placed first in the Hamiltonian and collapse operator lists. Parameters ---------- H : qobj System Hamiltonian. psi0 : qobj Initial state vector tlist : array_like Times at which results are recorded. ntraj : int Number of trajectories to run. c_ops : array_like ``list`` or ``array`` of collapse operators. e_ops : array_like ``list`` or ``array`` of operators for calculating expectation values. args : dict Arguments for time-dependent Hamiltonian and collapse operator terms. options : Odeoptions Instance of ODE solver options. Returns ------- results : Odedata Object storing all results from simulation. """ if psi0.type != 'ket': raise Exception("Initial state must be a state vector.") odeconfig.options = options #set num_cpus to the value given in qutip.settings if none in Odeoptions if not odeconfig.options.num_cpus: odeconfig.options.num_cpus = qutip.settings.num_cpus #set initial value data if options.tidy: odeconfig.psi0 = psi0.tidyup(options.atol).full() else: odeconfig.psi0 = psi0.full() odeconfig.psi0_dims = psi0.dims odeconfig.psi0_shape = psi0.shape #set general items odeconfig.tlist = tlist if isinstance(ntraj, (list, ndarray)): odeconfig.ntraj = sort(ntraj)[-1] else: odeconfig.ntraj = ntraj #---- #---------------------------------------------- # SETUP ODE DATA IF NONE EXISTS OR NOT REUSING #---------------------------------------------- if (not options.rhs_reuse) or (not odeconfig.tdfunc): #reset odeconfig collapse and time-dependence flags to default values _reset_odeconfig() #check for type of time-dependence (if any) time_type, h_stuff, c_stuff = _ode_checks(H, c_ops, 'mc') h_terms = len(h_stuff[0]) + len(h_stuff[1]) + len(h_stuff[2]) c_terms = len(c_stuff[0]) + len(c_stuff[1]) + len(c_stuff[2]) #set time_type for use in multiprocessing odeconfig.tflag = time_type #-Check for PyObjC on Mac platforms if sys.platform == 'darwin': try: import Foundation except: odeconfig.options.gui = False #check if running in iPython and using Cython compiling (then no GUI to work around error) if odeconfig.options.gui and odeconfig.tflag in array([1, 10, 11]): try: __IPYTHON__ except: pass else: odeconfig.options.gui = False if qutip.settings.qutip_gui == "NONE": odeconfig.options.gui = False #check for collapse operators if c_terms > 0: odeconfig.cflag = 1 else: odeconfig.cflag = 0 #Configure data _mc_data_config(H, psi0, h_stuff, c_ops, c_stuff, args, e_ops, options) if odeconfig.tflag in array([1, 10, 11]): #compile time-depdendent RHS code os.environ['CFLAGS'] = '-w' import pyximport pyximport.install( setup_args={'include_dirs': [numpy.get_include()]}) if odeconfig.tflag in array([1, 11]): code = compile( 'from ' + odeconfig.tdname + ' import cyq_td_ode_rhs,col_spmv,col_expect', '<string>', 'exec') exec(code, globals()) odeconfig.tdfunc = cyq_td_ode_rhs odeconfig.colspmv = col_spmv odeconfig.colexpect = col_expect else: code = compile( 'from ' + odeconfig.tdname + ' import cyq_td_ode_rhs', '<string>', 'exec') exec(code, globals()) odeconfig.tdfunc = cyq_td_ode_rhs try: os.remove(odeconfig.tdname + ".pyx") except: print("Error removing pyx file. File not found.") elif odeconfig.tflag == 0: odeconfig.tdfunc = cyq_ode_rhs else: #setup args for new parameters when rhs_reuse=True and tdfunc is given #string based if odeconfig.tflag in array([1, 10, 11]): if any(args): odeconfig.c_args = [] arg_items = args.items() for k in range(len(args)): odeconfig.c_args.append(arg_items[k][1]) #function based elif odeconfig.tflag in array([2, 3, 20, 22]): odeconfig.h_func_args = args #load monte-carlo class mc = MC_class() #RUN THE SIMULATION mc.run() #AFTER MCSOLVER IS DONE -------------------------------------- #-------COLLECT AND RETURN OUTPUT DATA IN ODEDATA OBJECT --------------# output = Odedata() output.solver = 'mcsolve' #state vectors if any(mc.psi_out) and odeconfig.options.mc_avg: output.states = mc.psi_out #expectation values if any( mc.expect_out ) and odeconfig.cflag and odeconfig.options.mc_avg: #averaging if multiple trajectories if isinstance(ntraj, int): output.expect = mean(mc.expect_out, axis=0) elif isinstance(ntraj, (list, ndarray)): output.expect = [] for num in ntraj: expt_data = mean(mc.expect_out[:num], axis=0) data_list = [] if any([op.isherm == False for op in e_ops]): for k in range(len(e_ops)): if e_ops[k].isherm: data_list.append(real(expt_data[k])) else: data_list.append(expt_data[k]) else: data_list = [data for data in expt_data] output.expect.append(data_list) else: #no averaging for single trajectory or if mc_avg flag (Odeoptions) is off output.expect = mc.expect_out #simulation parameters output.times = odeconfig.tlist output.num_expect = odeconfig.e_num output.num_collapse = odeconfig.c_num output.ntraj = odeconfig.ntraj output.col_times = mc.collapse_times_out output.col_which = mc.which_op_out return output
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 rhs_generate(H, psi0, tlist, c_ops, e_ops, ntraj=500, args={}, options=Odeoptions(), solver='me', name=None): """ Used to generate the Cython functions for solving the dynamics of a given system before using the parfor function. Parameters ---------- H : qobj System Hamiltonian. psi0 : qobj Initial state vector tlist : array_like Times at which results are recorded. ntraj : int Number of trajectories to run. c_ops : array_like ``list`` or ``array`` of collapse operators. e_ops : array_like ``list`` or ``array`` of operators for calculating expectation values. args : dict Arguments for time-dependent Hamiltonian and collapse operator terms. options : Odeoptions Instance of ODE solver options. solver: str String indicating which solver "me" or "mc" name: str Name of generated RHS """ _reset_odeconfig() #clear odeconfig #------------------------ # GENERATE MCSOLVER DATA #------------------------ if solver == 'mc': odeconfig.tlist = tlist if isinstance(ntraj, (list, ndarray)): odeconfig.ntraj = sort(ntraj)[-1] else: odeconfig.ntraj = ntraj #check for type of time-dependence (if any) time_type, h_stuff, c_stuff = _ode_checks(H, c_ops, 'mc') h_terms = len(h_stuff[0]) + len(h_stuff[1]) + len(h_stuff[2]) c_terms = len(c_stuff[0]) + len(c_stuff[1]) + len(c_stuff[2]) #set time_type for use in multiprocessing odeconfig.tflag = time_type #check for collapse operators if c_terms > 0: odeconfig.cflag = 1 else: odeconfig.cflag = 0 #Configure data _mc_data_config(H, psi0, h_stuff, c_ops, c_stuff, args, e_ops, options) os.environ['CFLAGS'] = '-w' import pyximport pyximport.install(setup_args={'include_dirs': [numpy.get_include()]}) if odeconfig.tflag in array([1, 11]): code = compile( 'from ' + odeconfig.tdname + ' import cyq_td_ode_rhs,col_spmv,col_expect', '<string>', 'exec') exec(code) odeconfig.tdfunc = cyq_td_ode_rhs odeconfig.colspmv = col_spmv odeconfig.colexpect = col_expect else: code = compile( 'from ' + odeconfig.tdname + ' import cyq_td_ode_rhs', '<string>', 'exec') exec(code) odeconfig.tdfunc = cyq_td_ode_rhs try: os.remove(odeconfig.tdname + ".pyx") except: print("Error removing pyx file. File not found.") #------------------------ # GENERATE MESOLVER STUFF #------------------------ elif solver == 'me': odeconfig.tdname = "rhs" + str(odeconfig.cgen_num) cgen = Codegen(h_terms=n_L_terms, h_tdterms=Lcoeff, args=args) cgen.generate(odeconfig.tdname + ".pyx") os.environ['CFLAGS'] = '-O3 -w' import pyximport pyximport.install(setup_args={'include_dirs': [numpy.get_include()]}) code = compile('from ' + odeconfig.tdname + ' import cyq_td_ode_rhs', '<string>', 'exec') exec(code) odeconfig.tdfunc = cyq_td_ode_rhs