示例#1
0
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)
示例#2
0
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)
示例#3
0
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)
示例#4
0
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) 
示例#5
0
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)
示例#6
0
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) 
示例#7
0
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
示例#8
0
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
示例#9
0
def d1_rho_homodyne(A, rho):
    """
    not tested
    Todo: cythonize
    """

    return spmv(A[0].data, A[0].indices, A[0].indptr, rho)
示例#10
0
def d1_rho_homodyne(A, rho):
    """
    not tested
    Todo: cythonize
    """

    return spmv(A[0].data, A[0].indices, A[0].indptr, rho)
示例#11
0
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
示例#12
0
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
示例#13
0
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
示例#14
0
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
示例#15
0
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)
示例#16
0
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
示例#17
0
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
示例#18
0
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
示例#19
0
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
示例#20
0
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
示例#21
0
文件: mcsolve.py 项目: partus/qutip
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)
示例#22
0
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)
示例#23
0
def _rho_expect(oper, state):
    prod = spmv(oper.data, oper.indices, oper.indptr, state)
    return sum(vec2mat(prod).diagonal())
示例#24
0
def _rho_expect(oper, state):
    prod = spmv(oper.data, oper.indices, oper.indptr, state)
    return sum(vec2mat(prod).diagonal())
示例#25
0
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)
示例#26
0
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)