def d1_current(A, psi): """ Todo: cythonize, requires poisson increments """ n1 = norm(spmv(A[0].data, A[0].indices, A[0].indptr, psi), 2) return -0.5 * (spmv(A[2].data, A[2].indices, A[2].indptr, psi) - n1 ** 2 * psi)
def d1_current(A, psi): """ Todo: cythonize, requires poisson increments """ n1 = norm(spmv(A[0].data, A[0].indices, A[0].indptr, psi), 2) return -0.5 * (spmv(A[2].data, A[2].indices, A[2].indptr, psi) - n1**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 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_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 d2_current(A, psi): """ Todo: cythonize, requires poisson increments """ psi_1 = spmv(A[0].data, A[0].indices, A[0].indptr, psi) n1 = norm(psi_1, 2) return psi_1 / n1 - psi
def _smesolve_single_trajectory(L, dt, tlist, N_store, N_substeps, rho_t, A_ops, e_ops, data, rhs, d1, d2): """ Internal function. See smesolve. """ dW = np.sqrt(dt) * scipy.randn(len(A_ops), N_store, N_substeps) states_list = [] for t_idx, t in enumerate(tlist): if e_ops: for e_idx, e in enumerate(e_ops): # XXX: need to keep hilbert space structure data.expect[e_idx, t_idx] += expect(e, Qobj(vec2mat(rho_t))) else: states_list.append(Qobj(rho_t)) # dito for j in range(N_substeps): drho_t = spmv(L.data.data, L.data.indices, L.data.indptr, rho_t) * dt for a_idx, A in enumerate(A_ops): drho_t += rhs(L.data, rho_t, A, dt, dW[a_idx, t_idx, j], d1, d2) rho_t += drho_t return states_list
def d1_rho_homodyne(A, rho): """ not tested Todo: cythonize """ return spmv(A[0].data, A[0].indices, A[0].indptr, rho)
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_rho_homodyne(A, rho): """ not tested Todo: cythonize """ e1 = _rho_expect(A[2], rho) return spmv(A[1].data, A[1].indices, A[1].indptr, rho) - e1 * rho
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 _rhs_psi_platen(H, psi_t, A, dt, dW, d1, d2): """ .. note:: Experimental. """ sqrt_dt = np.sqrt(dt) dpsi_t_H = (-1.0j * dt) * spmv(H.data, H.indices, H.indptr, psi_t) psi_t_1 = psi_t + dpsi_t_H + d1(A, psi_t) * dt + d2(A, psi_t) * dW psi_t_p = psi_t + dpsi_t_H + d1(A, psi_t) * dt + d2(A, psi_t) * sqrt_dt psi_t_m = psi_t + dpsi_t_H + d1(A, psi_t) * dt - d2(A, psi_t) * sqrt_dt dpsi_t = 0.50 * (d1(A, psi_t_1) + d1(A, psi_t)) * dt + \ 0.25 * (d2(A, psi_t_p) + d2(A, psi_t_m) + 2 * d2(A, psi_t)) * dW + \ 0.25 * (d2(A, psi_t_p) - d2(A, psi_t_m)) * (dW**2 - dt) * sqrt_dt return dpsi_t
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)
def _rho_expect(oper, state): prod = spmv(oper.data, oper.indices, oper.indptr, state) return sum(vec2mat(prod).diagonal())
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)