def no_collapse_expect_out(num_times,expect_out): ##Calculates xpect.values at times tlist if no collapse ops. given # #------------------------------------ opt=odeconfig.options if odeconfig.tflag in array([1,10,11]): ODE=ode(odeconfig.tdfunc) code = compile('ODE.set_f_params('+odeconfig.string+')', '<string>', 'exec') exec(code) elif odeconfig.tflag==2: ODE=ode(cRHStd) elif odeconfig.tflag in array([20,22]): ODE=ode(tdRHStd) elif odeconfig.tflag==3: ODE=ode(pyRHSc) else: ODE = ode(cyq_ode_rhs) ODE.set_f_params(odeconfig.h_data, odeconfig.h_ind, odeconfig.h_ptr) ODE.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) #initialize ODE solver for RHS ODE.set_initial_value(odeconfig.psi0,odeconfig.tlist[0]) #set initial conditions for jj in range(odeconfig.e_num): expect_out[jj][0]=mc_expect(odeconfig.e_ops_data[jj],odeconfig.e_ops_ind[jj],odeconfig.e_ops_ptr[jj],odeconfig.e_ops_isherm[jj],odeconfig.psi0) for k in range(1,num_times): ODE.integrate(odeconfig.tlist[k],step=0) #integrate up to tlist[k] if ODE.successful(): state=ODE.y/norm(ODE.y) for jj in range(odeconfig.e_num): expect_out[jj][k]=mc_expect(odeconfig.e_ops_data[jj],odeconfig.e_ops_ind[jj],odeconfig.e_ops_ptr[jj],odeconfig.e_ops_isherm[jj],state) else: raise ValueError('Error in ODE solver') return expect_out #return times and expectiation values
def d1_psi_heterodyne(A, psi): """ not working/tested Todo: cythonize """ e1 = mc_expect(A[0].data, A[0].indices, A[0].indptr, 0, psi) B = A[0].T.conj() e2 = mc_expect(B.data, B.indices, B.indptr, 0, psi) return ( e2 * spmv(A[0].data, A[0].indices, A[0].indptr, psi) - 0.5 * spmv(A[2].data, A[2].indices, A[2].indptr, psi) - 0.5 * e1 * e2 * psi)
def d1_psi_heterodyne(A, psi): """ not working/tested Todo: cythonize """ e1 = mc_expect(A[0].data, A[0].indices, A[0].indptr, 0, psi) B = A[0].T.conj() e2 = mc_expect(B.data, B.indices, B.indptr, 0, psi) return (e2 * spmv(A[0].data, A[0].indices, A[0].indptr, psi) - 0.5 * spmv(A[2].data, A[2].indices, A[2].indptr, psi) - 0.5 * e1 * e2 * psi)
def no_collapse_expect_out(num_times, expect_out): ##Calculates xpect.values at times tlist if no collapse ops. given # #------------------------------------ opt = odeconfig.options if odeconfig.tflag in array([1, 10, 11]): ODE = ode(odeconfig.tdfunc) code = compile('ODE.set_f_params(' + odeconfig.string + ')', '<string>', 'exec') exec(code) elif odeconfig.tflag == 2: ODE = ode(cRHStd) elif odeconfig.tflag in array([20, 22]): ODE = ode(tdRHStd) elif odeconfig.tflag == 3: ODE = ode(pyRHSc) else: ODE = ode(cyq_ode_rhs) ODE.set_f_params(odeconfig.h_data, odeconfig.h_ind, odeconfig.h_ptr) ODE.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) #initialize ODE solver for RHS ODE.set_initial_value(odeconfig.psi0, odeconfig.tlist[0]) #set initial conditions for jj in range(odeconfig.e_num): expect_out[jj][0] = mc_expect(odeconfig.e_ops_data[jj], odeconfig.e_ops_ind[jj], odeconfig.e_ops_ptr[jj], odeconfig.e_ops_isherm[jj], odeconfig.psi0) for k in range(1, num_times): ODE.integrate(odeconfig.tlist[k], step=0) #integrate up to tlist[k] if ODE.successful(): state = ODE.y / norm(ODE.y) for jj in range(odeconfig.e_num): expect_out[jj][k] = mc_expect(odeconfig.e_ops_data[jj], odeconfig.e_ops_ind[jj], odeconfig.e_ops_ptr[jj], odeconfig.e_ops_isherm[jj], state) else: raise ValueError('Error in ODE solver') return expect_out #return times and expectiation values
def run(self): if odeconfig.c_num == 0: if odeconfig.ntraj != 1: #check if ntraj!=1 which is pointless for no collapse operators odeconfig.ntraj = 1 print( 'No collapse operators specified.\nRunning a single trajectory only.\n' ) if odeconfig.e_num == 0: # return psi Qobj at each requested time self.psi_out = no_collapse_psi_out(self.num_times, self.psi_out) else: # return expectation values of requested operators self.expect_out = no_collapse_expect_out( self.num_times, self.expect_out) elif odeconfig.c_num != 0: self.seed = array([ int(ceil(random.rand() * 1e4)) for ll in range(odeconfig.ntraj) ]) if odeconfig.e_num == 0: mc_alg_out = zeros((self.num_times), dtype=ndarray) mc_alg_out[0] = odeconfig.psi0 else: #PRE-GENERATE LIST OF EXPECTATION VALUES mc_alg_out = [] for i in range(odeconfig.e_num): if odeconfig.e_ops_isherm[ i]: #preallocate real array of zeros mc_alg_out.append(zeros(self.num_times)) else: #preallocate complex array of zeros mc_alg_out.append(zeros(self.num_times, dtype=complex)) mc_alg_out[i][0] = mc_expect(odeconfig.e_ops_data[i], odeconfig.e_ops_ind[i], odeconfig.e_ops_ptr[i], odeconfig.e_ops_isherm[i], odeconfig.psi0) #set arguments for input to monte-carlo args = (mc_alg_out, odeconfig.options, odeconfig.tlist, self.num_times, self.seed) if not odeconfig.options.gui: self.parallel(args, self) else: if qutip.settings.qutip_gui == "PYSIDE": from PySide import QtGui, QtCore elif qutip.settings.qutip_gui == "PYQT4": from PyQt4 import QtGui, QtCore from gui.ProgressBar import ProgressBar, Pthread app = QtGui.QApplication.instance( ) #checks if QApplication already exists (needed for iPython) if not app: #create QApplication if it doesnt exist app = QtGui.QApplication(sys.argv) thread = Pthread(target=self.parallel, args=args, top=self) self.bar = ProgressBar(self, thread, odeconfig.ntraj, self.cpus) QtCore.QTimer.singleShot(0, self.bar.run) self.bar.show() self.bar.activateWindow() self.bar.raise_() app.exec_() return
def d2_psi_heterodyne(A, psi): """ not working/tested Todo: cythonize """ e1 = mc_expect(A[0].data, A[0].indices, A[0].indptr, 0, psi) return spmv(A[0].data, A[0].indices, A[0].indptr, psi) - e1 * psi
def d2_psi_homodyne(A, psi): """ OK Todo: cythonize """ e1 = mc_expect(A[1].data, A[1].indices, A[1].indptr, 0, psi) return spmv(A[0].data, A[0].indices, A[0].indptr, psi) - 0.5 * e1 * psi
def d2_psi_homodyne(A, psi): """ OK Todo: cythonize """ e1 = mc_expect(A[1].data, A[1].indices, A[1].indptr, 0, psi) return (spmv(A[0].data, A[0].indices, A[0].indptr, psi) - 0.5 * e1 * psi)
def __init__(self): #-----------------------------------# # INIT MC CLASS #-----------------------------------# #----MAIN OBJECT PROPERTIES--------------------# ##holds instance of the ProgressBar class self.bar=None ##holds instance of the Pthread class self.thread=None #Number of completed trajectories self.count=0 ##step-size for count attribute self.step=1 ##Percent of trajectories completed self.percent=0.0 ##used in implimenting the command line progress ouput self.level=0.1 ##times at which to output state vectors or expectation values ##number of time steps in tlist self.num_times=len(odeconfig.tlist) #holds seed for random number generator self.seed=None #holds expected time to completion self.st=None #number of cpus to be used self.cpus=odeconfig.options.num_cpus #set output variables, even if they are not used to simplify output code. self.psi_out=None self.expect_out=None self.collapse_times_out=None self.which_op_out=None #FOR EVOLUTION FOR NO COLLAPSE OPERATORS if odeconfig.c_num==0: if odeconfig.e_num==0: ##Output array of state vectors calculated at times in tlist self.psi_out=array([Qobj()]*self.num_times)#preallocate array of Qobjs elif odeconfig.e_num!=0:#no collpase expectation values ##List of output expectation values calculated at times in tlist self.expect_out=[] for i in range(odeconfig.e_num): if odeconfig.e_ops_isherm[i]:#preallocate real array of zeros self.expect_out.append(zeros(self.num_times)) else:#preallocate complex array of zeros self.expect_out.append(zeros(self.num_times,dtype=complex)) self.expect_out[i][0]=mc_expect(odeconfig.e_ops_data[i],odeconfig.e_ops_ind[i],odeconfig.e_ops_ptr[i],odeconfig.e_ops_isherm[i],odeconfig.psi0) #FOR EVOLUTION WITH COLLAPSE OPERATORS elif odeconfig.c_num!=0: #preallocate #ntraj arrays for state vectors, collapse times, and which operator self.collapse_times_out=zeros((odeconfig.ntraj),dtype=ndarray) self.which_op_out=zeros((odeconfig.ntraj),dtype=ndarray) if odeconfig.e_num==0:# if no expectation operators, preallocate #ntraj arrays for state vectors self.psi_out=array([zeros((self.num_times),dtype=object) for q in range(odeconfig.ntraj)])#preallocate array of Qobjs else: #preallocate array of lists for expectation values self.expect_out=[[] for x in range(odeconfig.ntraj)]
def d1_psi_homodyne(A, psi): """ OK Todo: cythonize """ e1 = mc_expect(A[1].data, A[1].indices, A[1].indptr, 0, psi) return 0.5 * (e1 * spmv(A[0].data, A[0].indices, A[0].indptr, psi) - spmv( A[2].data, A[2].indices, A[2].indptr, psi) - 0.25 * e1**2 * psi)
def d1_psi_homodyne(A, psi): """ OK Todo: cythonize """ e1 = mc_expect(A[1].data, A[1].indices, A[1].indptr, 0, psi) return 0.5 * (e1 * spmv(A[0].data, A[0].indices, A[0].indptr, psi) - spmv(A[2].data, A[2].indices, A[2].indptr, psi) - 0.25 * e1**2 * psi)
def run(self): if odeconfig.c_num==0: if odeconfig.ntraj!=1:#check if ntraj!=1 which is pointless for no collapse operators odeconfig.ntraj=1 print('No collapse operators specified.\nRunning a single trajectory only.\n') if odeconfig.e_num==0:# return psi Qobj at each requested time self.psi_out=_no_collapse_psi_out(self.num_times,self.psi_out) else:# return expectation values of requested operators self.expect_out=_no_collapse_expect_out(self.num_times,self.expect_out) elif odeconfig.c_num!=0: self.seed=random_integers(1e8,size=odeconfig.ntraj) if odeconfig.e_num==0: mc_alg_out=zeros((self.num_times),dtype=ndarray) if odeconfig.options.mc_avg: #output is averaged states, so use dm mc_alg_out[0]=odeconfig.psi0*odeconfig.psi0.conj().T else: #output is not averaged, so write state vectors mc_alg_out[0]=odeconfig.psi0 else: #PRE-GENERATE LIST OF EXPECTATION VALUES mc_alg_out=[] for i in range(odeconfig.e_num): if odeconfig.e_ops_isherm[i]:#preallocate real array of zeros mc_alg_out.append(zeros(self.num_times)) else:#preallocate complex array of zeros mc_alg_out.append(zeros(self.num_times,dtype=complex)) mc_alg_out[i][0]=mc_expect(odeconfig.e_ops_data[i],odeconfig.e_ops_ind[i],odeconfig.e_ops_ptr[i],odeconfig.e_ops_isherm[i],odeconfig.psi0) #set arguments for input to monte-carlo args=(mc_alg_out,odeconfig.options,odeconfig.tlist,self.num_times,self.seed) if not odeconfig.options.gui: self.parallel(args,self) else: if qutip.settings.qutip_gui=="PYSIDE": from PySide import QtGui,QtCore elif qutip.settings.qutip_gui=="PYQT4": from PyQt4 import QtGui,QtCore from gui.ProgressBar import ProgressBar,Pthread app=QtGui.QApplication.instance()#checks if QApplication already exists (needed for iPython) if not app:#create QApplication if it doesnt exist app = QtGui.QApplication(sys.argv) thread=Pthread(target=self.parallel,args=args,top=self) self.bar=ProgressBar(self,thread,odeconfig.ntraj,self.cpus) QtCore.QTimer.singleShot(0,self.bar.run) self.bar.show() self.bar.activateWindow() self.bar.raise_() app.exec_() return
def mc_alg_evolve(nt,args): """ Monte-Carlo algorithm returning state-vector or expectation values at times tlist for a single trajectory. """ #get input data mc_alg_out,opt,tlist,num_times,seeds=args #number of operators of each type num_expect=odeconfig.e_num num_collapse=odeconfig.c_num collapse_times=[] #times at which collapse occurs which_oper=[] # which operator did the collapse #SEED AND RNG AND GENERATE random.seed(seeds[nt]) rand_vals=random.rand(2)#first rand is collapse norm, second is which operator #CREATE ODE OBJECT CORRESPONDING TO DESIRED TIME-DEPENDENCE if odeconfig.tflag in array([1,10,11]): ODE=ode(odeconfig.tdfunc) code = compile('ODE.set_f_params('+odeconfig.string+')', '<string>', 'exec') exec(code) elif odeconfig.tflag==2: ODE=ode(cRHStd) elif odeconfig.tflag in array([20,22]): ODE=ode(tdRHStd) elif odeconfig.tflag==3: ODE=ode(pyRHSc) else: ODE = ode(cyq_ode_rhs) ODE.set_f_params(odeconfig.h_data, odeconfig.h_ind, odeconfig.h_ptr) #initialize ODE solver for RHS ODE.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) #set initial conditions ODE.set_initial_value(odeconfig.psi0,tlist[0]) #RUN ODE UNTIL EACH TIME IN TLIST cinds=arange(num_collapse) for k in range(1,num_times): #ODE WHILE LOOP FOR INTEGRATE UP TO TIME TLIST[k] while ODE.successful() and ODE.t<tlist[k]: last_t=ODE.t;last_y=ODE.y ODE.integrate(tlist[k],step=1) #integrate up to tlist[k], one step at a time. psi_nrm2=norm(ODE.y,2)**2 if psi_nrm2<=rand_vals[0]:# <== collpase has occured collapse_times.append(ODE.t) #some string based collapse operators if odeconfig.tflag in array([1,11]): n_dp=[mc_expect(odeconfig.n_ops_data[i],odeconfig.n_ops_ind[i],odeconfig.n_ops_ptr[i],1,ODE.y) for i in odeconfig.c_const_inds] exec(odeconfig.col_expect_code) #calculates the expectation values for time-dependent norm collapse operators n_dp=array(n_dp) #some Python function based collapse operators elif odeconfig.tflag in array([2,20,22]): n_dp=[mc_expect(odeconfig.n_ops_data[i],odeconfig.n_ops_ind[i],odeconfig.n_ops_ptr[i],1,ODE.y) for i in odeconfig.c_const_inds] n_dp+=[abs(odeconfig.c_funcs[i](ODE.t,odeconfig.c_func_args))**2*mc_expect(odeconfig.n_ops_data[i],odeconfig.n_ops_ind[i],odeconfig.n_ops_ptr[i],1,ODE.y) for i in odeconfig.c_td_inds] n_dp=array(n_dp) #all constant collapse operators. else: n_dp=array([mc_expect(odeconfig.n_ops_data[i],odeconfig.n_ops_ind[i],odeconfig.n_ops_ptr[i],1,ODE.y) for i in range(num_collapse)]) #determine which operator does collapse kk=cumsum(n_dp/sum(n_dp)) j=cinds[kk>=rand_vals[1]][0] which_oper.append(j) #record which operator did collapse if j in odeconfig.c_const_inds: state=spmv(odeconfig.c_ops_data[j],odeconfig.c_ops_ind[j],odeconfig.c_ops_ptr[j],ODE.y) else: if odeconfig.tflag in array([1,11]): exec(odeconfig.col_spmv_code)#calculates the state vector for collapse by a time-dependent collapse operator else: state=odeconfig.c_funcs[j](ODE.t,odeconfig.c_func_args)*spmv(odeconfig.c_ops_data[j],odeconfig.c_ops_ind[j],odeconfig.c_ops_ptr[j],ODE.y) state_nrm=norm(state,2) ODE.set_initial_value(state/state_nrm,ODE.t) rand_vals=random.rand(2) #------------------------------------------------------- ###--after while loop--#### psi=copy(ODE.y) if ODE.t>last_t: psi=(psi-last_y)/(ODE.t-last_t)*(tlist[k]-last_t)+last_y epsi=psi/norm(psi,2) if num_expect==0: mc_alg_out[k]=epsi else: for jj in range(num_expect): mc_alg_out[jj][k]=mc_expect(odeconfig.e_ops_data[jj],odeconfig.e_ops_ind[jj],odeconfig.e_ops_ptr[jj],odeconfig.e_ops_isherm[jj],epsi) #RETURN VALUES if num_expect==0: mc_alg_out=array([Qobj(k,odeconfig.psi0_dims,odeconfig.psi0_shape,fast='mc') for k in mc_alg_out]) return nt,mc_alg_out,array(collapse_times),array(which_oper) else: return nt,mc_alg_out,array(collapse_times),array(which_oper)
def _mc_alg_evolve(nt, args): """ Monte-Carlo algorithm returning state-vector or expectation values at times tlist for a single trajectory. """ #get input data mc_alg_out, opt, tlist, num_times, seeds = args collapse_times = [] #times at which collapse occurs which_oper = [] # which operator did the collapse #SEED AND RNG AND GENERATE prng = RandomState(seeds[nt]) rand_vals = prng.rand( 2) #first rand is collapse norm, second is which operator #CREATE ODE OBJECT CORRESPONDING TO DESIRED TIME-DEPENDENCE if odeconfig.tflag in array([1, 10, 11]): ODE = ode(odeconfig.tdfunc) code = compile('ODE.set_f_params(' + odeconfig.string + ')', '<string>', 'exec') exec(code) elif odeconfig.tflag == 2: ODE = ode(_cRHStd) elif odeconfig.tflag in array([20, 22]): ODE = ode(_tdRHStd) elif odeconfig.tflag == 3: ODE = ode(_pyRHSc) else: ODE = ode(cyq_ode_rhs) ODE.set_f_params(odeconfig.h_data, odeconfig.h_ind, odeconfig.h_ptr) #initialize ODE solver for RHS ODE.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) #set initial conditions ODE.set_initial_value(odeconfig.psi0, tlist[0]) #make array for collapse operator inds cinds = arange(odeconfig.c_num) #RUN ODE UNTIL EACH TIME IN TLIST for k in range(1, num_times): #ODE WHILE LOOP FOR INTEGRATE UP TO TIME TLIST[k] while ODE.t < tlist[k]: t_prev = ODE.t y_prev = ODE.y norm2_prev = norm(ODE.y, 2)**2 ODE.integrate( tlist[k], step=1) #integrate up to tlist[k], one step at a time. if not ODE.successful(): raise Exception("ZVODE failed!") #check if ODE jumped over tlist[k], if so, integrate until tlist exactly if ODE.t > tlist[k]: ODE.set_initial_value(y_prev, t_prev) ODE.integrate(tlist[k], step=0) if not ODE.successful(): raise Exception("ZVODE failed!") norm2_psi = norm(ODE.y, 2)**2 if norm2_psi <= rand_vals[0]: # <== collpase has occured #find collpase time to within specified tolerance #--------------------------------------------------- ii = 0 t_final = ODE.t while ii < odeconfig.norm_steps: ii += 1 #t_guess=t_prev+(rand_vals[0]-norm2_prev)/(norm2_psi-norm2_prev)*(t_final-t_prev) t_guess = t_prev + log(norm2_prev / rand_vals[0]) / log( norm2_prev / norm2_psi) * (t_final - t_prev) ODE.set_initial_value(y_prev, t_prev) ODE.integrate(t_guess, step=0) if not ODE.successful(): raise Exception( "ZVODE failed after adjusting step size!") norm2_guess = norm(ODE.y, 2)**2 if abs(rand_vals[0] - norm2_guess) < odeconfig.norm_tol * rand_vals[0]: break elif (norm2_guess < rand_vals[0]): # t_guess is still > t_jump t_final = t_guess norm2_psi = norm2_guess else: # t_guess < t_jump t_prev = t_guess y_prev = ODE.y norm2_prev = norm2_guess if ii > odeconfig.norm_steps: raise Exception( "Norm tolerance not reached. Increase accuracy of ODE solver or Odeoptions.norm_steps." ) #--------------------------------------------------- collapse_times.append(ODE.t) #some string based collapse operators if odeconfig.tflag in array([1, 11]): n_dp = [ mc_expect(odeconfig.n_ops_data[i], odeconfig.n_ops_ind[i], odeconfig.n_ops_ptr[i], 1, ODE.y) for i in odeconfig.c_const_inds ] _locals = locals() exec( odeconfig.col_expect_code, globals(), _locals ) #calculates the expectation values for time-dependent norm collapse operators n_dp = array(_locals['n_dp']) #some Python function based collapse operators elif odeconfig.tflag in array([2, 20, 22]): n_dp = [ mc_expect(odeconfig.n_ops_data[i], odeconfig.n_ops_ind[i], odeconfig.n_ops_ptr[i], 1, ODE.y) for i in odeconfig.c_const_inds ] n_dp += [ abs(odeconfig.c_funcs[i](ODE.t, odeconfig.c_func_args)) **2 * mc_expect(odeconfig.n_ops_data[i], odeconfig.n_ops_ind[i], odeconfig.n_ops_ptr[i], 1, ODE.y) for i in odeconfig.c_td_inds ] n_dp = array(n_dp) #all constant collapse operators. else: n_dp = array([ mc_expect(odeconfig.n_ops_data[i], odeconfig.n_ops_ind[i], odeconfig.n_ops_ptr[i], 1, ODE.y) for i in range(odeconfig.c_num) ]) #determine which operator does collapse kk = cumsum(n_dp / sum(n_dp)) j = cinds[kk >= rand_vals[1]][0] which_oper.append(j) #record which operator did collapse if j in odeconfig.c_const_inds: state = spmv(odeconfig.c_ops_data[j], odeconfig.c_ops_ind[j], odeconfig.c_ops_ptr[j], ODE.y) else: if odeconfig.tflag in array([1, 11]): _locals = locals() exec( odeconfig.col_spmv_code, globals(), _locals ) #calculates the state vector for collapse by a time-dependent collapse operator state = _locals['state'] else: state = odeconfig.c_funcs[j]( ODE.t, odeconfig.c_func_args) * spmv( odeconfig.c_ops_data[j], odeconfig.c_ops_ind[j], odeconfig.c_ops_ptr[j], ODE.y) state = state / norm(state, 2) ODE.set_initial_value(state, ODE.t) rand_vals = prng.rand(2) #------------------------------------------------------- ###--after while loop--#### out_psi = ODE.y / norm(ODE.y, 2) if odeconfig.e_num == 0: if odeconfig.options.mc_avg: mc_alg_out[k] = out_psi * out_psi.conj().T else: mc_alg_out[k] = out_psi else: for jj in range(odeconfig.e_num): mc_alg_out[jj][k] = mc_expect(odeconfig.e_ops_data[jj], odeconfig.e_ops_ind[jj], odeconfig.e_ops_ptr[jj], odeconfig.e_ops_isherm[jj], out_psi) #RETURN VALUES if odeconfig.e_num == 0: if odeconfig.options.mc_avg: mc_alg_out = array([ Qobj(k, [odeconfig.psi0_dims[0], odeconfig.psi0_dims[0]], [odeconfig.psi0_shape[0], odeconfig.psi0_shape[0]], fast='mc-dm') for k in mc_alg_out ]) else: mc_alg_out = array([ Qobj(k, odeconfig.psi0_dims, odeconfig.psi0_shape, fast='mc') for k in mc_alg_out ]) return nt, mc_alg_out, array(collapse_times), array(which_oper) else: return nt, mc_alg_out, array(collapse_times), array(which_oper)
def __init__(self): #-----------------------------------# # INIT MC CLASS #-----------------------------------# #----MAIN OBJECT PROPERTIES--------------------# ##holds instance of the ProgressBar class self.bar = None ##holds instance of the Pthread class self.thread = None #Number of completed trajectories self.count = 0 ##step-size for count attribute self.step = 1 ##Percent of trajectories completed self.percent = 0.0 ##used in implimenting the command line progress ouput self.level = 0.1 ##times at which to output state vectors or expectation values ##number of time steps in tlist self.num_times = len(odeconfig.tlist) #holds seed for random number generator self.seed = None #holds expected time to completion self.st = None #number of cpus to be used self.cpus = odeconfig.options.num_cpus #set output variables, even if they are not used to simplify output code. self.psi_out = None self.expect_out = None self.collapse_times_out = None self.which_op_out = None #FOR EVOLUTION FOR NO COLLAPSE OPERATORS if odeconfig.c_num == 0: if odeconfig.e_num == 0: ##Output array of state vectors calculated at times in tlist self.psi_out = array( [Qobj()] * self.num_times) #preallocate array of Qobjs elif odeconfig.e_num != 0: #no collpase expectation values ##List of output expectation values calculated at times in tlist self.expect_out = [] for i in range(odeconfig.e_num): if odeconfig.e_ops_isherm[ i]: #preallocate real array of zeros self.expect_out.append(zeros(self.num_times)) else: #preallocate complex array of zeros self.expect_out.append( zeros(self.num_times, dtype=complex)) self.expect_out[i][0] = mc_expect( odeconfig.e_ops_data[i], odeconfig.e_ops_ind[i], odeconfig.e_ops_ptr[i], odeconfig.e_ops_isherm[i], odeconfig.psi0) #FOR EVOLUTION WITH COLLAPSE OPERATORS elif odeconfig.c_num != 0: #preallocate #ntraj arrays for state vectors, collapse times, and which operator self.collapse_times_out = zeros((odeconfig.ntraj), dtype=ndarray) self.which_op_out = zeros((odeconfig.ntraj), dtype=ndarray) if odeconfig.e_num == 0: # if no expectation operators, preallocate #ntraj arrays for state vectors self.psi_out = array([ zeros((self.num_times), dtype=object) for q in range(odeconfig.ntraj) ]) #preallocate array of Qobjs else: #preallocate array of lists for expectation values self.expect_out = [[] for x in range(odeconfig.ntraj)]
def _mc_alg_evolve(nt,args): """ Monte-Carlo algorithm returning state-vector or expectation values at times tlist for a single trajectory. """ #get input data mc_alg_out,opt,tlist,num_times,seeds=args collapse_times=[] #times at which collapse occurs which_oper=[] # which operator did the collapse #SEED AND RNG AND GENERATE prng = RandomState(seeds[nt]) rand_vals=prng.rand(2)#first rand is collapse norm, second is which operator #CREATE ODE OBJECT CORRESPONDING TO DESIRED TIME-DEPENDENCE if odeconfig.tflag in array([1,10,11]): ODE=ode(odeconfig.tdfunc) code = compile('ODE.set_f_params('+odeconfig.string+')', '<string>', 'exec') exec(code) elif odeconfig.tflag==2: ODE=ode(_cRHStd) elif odeconfig.tflag in array([20,22]): ODE=ode(_tdRHStd) elif odeconfig.tflag==3: ODE=ode(_pyRHSc) else: ODE = ode(cyq_ode_rhs) ODE.set_f_params(odeconfig.h_data, odeconfig.h_ind, odeconfig.h_ptr) #initialize ODE solver for RHS ODE.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) #set initial conditions ODE.set_initial_value(odeconfig.psi0,tlist[0]) #make array for collapse operator inds cinds=arange(odeconfig.c_num) #RUN ODE UNTIL EACH TIME IN TLIST for k in range(1,num_times): #ODE WHILE LOOP FOR INTEGRATE UP TO TIME TLIST[k] while ODE.t<tlist[k]: t_prev=ODE.t;y_prev=ODE.y;norm2_prev=norm(ODE.y,2)**2 ODE.integrate(tlist[k],step=1) #integrate up to tlist[k], one step at a time. if not ODE.successful(): raise Exception("ZVODE failed!") #check if ODE jumped over tlist[k], if so, integrate until tlist exactly if ODE.t>tlist[k]: ODE.set_initial_value(y_prev,t_prev) ODE.integrate(tlist[k],step=0) if not ODE.successful(): raise Exception("ZVODE failed!") norm2_psi=norm(ODE.y,2)**2 if norm2_psi<=rand_vals[0]:# <== collpase has occured #find collpase time to within specified tolerance #--------------------------------------------------- ii=0 t_final=ODE.t while ii < odeconfig.norm_steps: ii+=1 #t_guess=t_prev+(rand_vals[0]-norm2_prev)/(norm2_psi-norm2_prev)*(t_final-t_prev) t_guess=t_prev+log(norm2_prev/rand_vals[0])/log(norm2_prev/norm2_psi)*(t_final-t_prev) ODE.set_initial_value(y_prev,t_prev) ODE.integrate(t_guess,step=0) if not ODE.successful(): raise Exception("ZVODE failed after adjusting step size!") norm2_guess=norm(ODE.y,2)**2 if abs(rand_vals[0]-norm2_guess) < odeconfig.norm_tol*rand_vals[0]: break elif (norm2_guess < rand_vals[0]): # t_guess is still > t_jump t_final=t_guess norm2_psi=norm2_guess else: # t_guess < t_jump t_prev=t_guess y_prev=ODE.y norm2_prev=norm2_guess if ii > odeconfig.norm_steps: raise Exception("Norm tolerance not reached. Increase accuracy of ODE solver or Odeoptions.norm_steps.") #--------------------------------------------------- collapse_times.append(ODE.t) #some string based collapse operators if odeconfig.tflag in array([1,11]): n_dp=[mc_expect(odeconfig.n_ops_data[i],odeconfig.n_ops_ind[i],odeconfig.n_ops_ptr[i],1,ODE.y) for i in odeconfig.c_const_inds] _locals = locals() exec(odeconfig.col_expect_code, globals(), _locals) #calculates the expectation values for time-dependent norm collapse operators n_dp=array(_locals['n_dp']) #some Python function based collapse operators elif odeconfig.tflag in array([2,20,22]): n_dp=[mc_expect(odeconfig.n_ops_data[i],odeconfig.n_ops_ind[i],odeconfig.n_ops_ptr[i],1,ODE.y) for i in odeconfig.c_const_inds] n_dp+=[abs(odeconfig.c_funcs[i](ODE.t,odeconfig.c_func_args))**2*mc_expect(odeconfig.n_ops_data[i],odeconfig.n_ops_ind[i],odeconfig.n_ops_ptr[i],1,ODE.y) for i in odeconfig.c_td_inds] n_dp=array(n_dp) #all constant collapse operators. else: n_dp=array([mc_expect(odeconfig.n_ops_data[i],odeconfig.n_ops_ind[i],odeconfig.n_ops_ptr[i],1,ODE.y) for i in range(odeconfig.c_num)]) #determine which operator does collapse kk=cumsum(n_dp/sum(n_dp)) j=cinds[kk>=rand_vals[1]][0] which_oper.append(j) #record which operator did collapse if j in odeconfig.c_const_inds: state=spmv(odeconfig.c_ops_data[j],odeconfig.c_ops_ind[j],odeconfig.c_ops_ptr[j],ODE.y) else: if odeconfig.tflag in array([1,11]): _locals = locals() exec(odeconfig.col_spmv_code, globals(), _locals)#calculates the state vector for collapse by a time-dependent collapse operator state = _locals['state'] else: state=odeconfig.c_funcs[j](ODE.t,odeconfig.c_func_args)*spmv(odeconfig.c_ops_data[j],odeconfig.c_ops_ind[j],odeconfig.c_ops_ptr[j],ODE.y) state=state/norm(state,2) ODE.set_initial_value(state,ODE.t) rand_vals=prng.rand(2) #------------------------------------------------------- ###--after while loop--#### out_psi=ODE.y/norm(ODE.y,2) if odeconfig.e_num==0: if odeconfig.options.mc_avg: mc_alg_out[k]=out_psi*out_psi.conj().T else: mc_alg_out[k]=out_psi else: for jj in range(odeconfig.e_num): mc_alg_out[jj][k]=mc_expect(odeconfig.e_ops_data[jj],odeconfig.e_ops_ind[jj],odeconfig.e_ops_ptr[jj],odeconfig.e_ops_isherm[jj],out_psi) #RETURN VALUES if odeconfig.e_num==0: if odeconfig.options.mc_avg: mc_alg_out=array([Qobj(k,[odeconfig.psi0_dims[0],odeconfig.psi0_dims[0]],[odeconfig.psi0_shape[0],odeconfig.psi0_shape[0]],fast='mc-dm') for k in mc_alg_out]) else: mc_alg_out=array([Qobj(k,odeconfig.psi0_dims,odeconfig.psi0_shape,fast='mc') for k in mc_alg_out]) return nt,mc_alg_out,array(collapse_times),array(which_oper) else: return nt,mc_alg_out,array(collapse_times),array(which_oper)
def mc_alg_evolve(nt, args): """ Monte-Carlo algorithm returning state-vector or expectation values at times tlist for a single trajectory. """ #get input data mc_alg_out, opt, tlist, num_times, seeds = args #number of operators of each type num_expect = odeconfig.e_num num_collapse = odeconfig.c_num collapse_times = [] #times at which collapse occurs which_oper = [] # which operator did the collapse #SEED AND RNG AND GENERATE random.seed(seeds[nt]) rand_vals = random.rand( 2) #first rand is collapse norm, second is which operator #CREATE ODE OBJECT CORRESPONDING TO DESIRED TIME-DEPENDENCE if odeconfig.tflag in array([1, 10, 11]): ODE = ode(odeconfig.tdfunc) code = compile('ODE.set_f_params(' + odeconfig.string + ')', '<string>', 'exec') exec(code) elif odeconfig.tflag == 2: ODE = ode(cRHStd) elif odeconfig.tflag in array([20, 22]): ODE = ode(tdRHStd) elif odeconfig.tflag == 3: ODE = ode(pyRHSc) else: ODE = ode(cyq_ode_rhs) ODE.set_f_params(odeconfig.h_data, odeconfig.h_ind, odeconfig.h_ptr) #initialize ODE solver for RHS ODE.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) #set initial conditions ODE.set_initial_value(odeconfig.psi0, tlist[0]) #RUN ODE UNTIL EACH TIME IN TLIST cinds = arange(num_collapse) for k in range(1, num_times): #ODE WHILE LOOP FOR INTEGRATE UP TO TIME TLIST[k] while ODE.successful() and ODE.t < tlist[k]: last_t = ODE.t last_y = ODE.y ODE.integrate( tlist[k], step=1) #integrate up to tlist[k], one step at a time. psi_nrm2 = norm(ODE.y, 2)**2 if psi_nrm2 <= rand_vals[0]: # <== collpase has occured collapse_times.append(ODE.t) #some string based collapse operators if odeconfig.tflag in array([1, 11]): n_dp = [ mc_expect(odeconfig.n_ops_data[i], odeconfig.n_ops_ind[i], odeconfig.n_ops_ptr[i], 1, ODE.y) for i in odeconfig.c_const_inds ] exec( odeconfig.col_expect_code ) #calculates the expectation values for time-dependent norm collapse operators n_dp = array(n_dp) #some Python function based collapse operators elif odeconfig.tflag in array([2, 20, 22]): n_dp = [ mc_expect(odeconfig.n_ops_data[i], odeconfig.n_ops_ind[i], odeconfig.n_ops_ptr[i], 1, ODE.y) for i in odeconfig.c_const_inds ] n_dp += [ abs(odeconfig.c_funcs[i](ODE.t, odeconfig.c_func_args)) **2 * mc_expect(odeconfig.n_ops_data[i], odeconfig.n_ops_ind[i], odeconfig.n_ops_ptr[i], 1, ODE.y) for i in odeconfig.c_td_inds ] n_dp = array(n_dp) #all constant collapse operators. else: n_dp = array([ mc_expect(odeconfig.n_ops_data[i], odeconfig.n_ops_ind[i], odeconfig.n_ops_ptr[i], 1, ODE.y) for i in range(num_collapse) ]) #determine which operator does collapse kk = cumsum(n_dp / sum(n_dp)) j = cinds[kk >= rand_vals[1]][0] which_oper.append(j) #record which operator did collapse if j in odeconfig.c_const_inds: state = spmv(odeconfig.c_ops_data[j], odeconfig.c_ops_ind[j], odeconfig.c_ops_ptr[j], ODE.y) else: if odeconfig.tflag in array([1, 11]): exec( odeconfig.col_spmv_code ) #calculates the state vector for collapse by a time-dependent collapse operator else: state = odeconfig.c_funcs[j]( ODE.t, odeconfig.c_func_args) * spmv( odeconfig.c_ops_data[j], odeconfig.c_ops_ind[j], odeconfig.c_ops_ptr[j], ODE.y) state_nrm = norm(state, 2) ODE.set_initial_value(state / state_nrm, ODE.t) rand_vals = random.rand(2) #------------------------------------------------------- ###--after while loop--#### psi = copy(ODE.y) if ODE.t > last_t: psi = (psi - last_y) / (ODE.t - last_t) * (tlist[k] - last_t) + last_y epsi = psi / norm(psi, 2) if num_expect == 0: mc_alg_out[k] = epsi else: for jj in range(num_expect): mc_alg_out[jj][k] = mc_expect(odeconfig.e_ops_data[jj], odeconfig.e_ops_ind[jj], odeconfig.e_ops_ptr[jj], odeconfig.e_ops_isherm[jj], epsi) #RETURN VALUES if num_expect == 0: mc_alg_out = array([ Qobj(k, odeconfig.psi0_dims, odeconfig.psi0_shape, fast='mc') for k in mc_alg_out ]) return nt, mc_alg_out, array(collapse_times), array(which_oper) else: return nt, mc_alg_out, array(collapse_times), array(which_oper)