Esempio n. 1
0
def floquet_master_equation_tensor(Alist, f_energies):
    """
    Construct a tensor that represents the master equation in the floquet
    basis (with constant Hamiltonian and collapse operators).
    
    Simplest RWA approximation [Grifoni et al, Phys.Rep. 304 229 (1998)]
    """

    if isinstance(Alist, list):
        # Alist can be a list of rate matrices corresponding
        # to different operators that couple to the environment
        N, M = shape(Alist[0])
    else:
        # or a simple rate matrix, in which case we put it in a list
        Alist = [Alist]
        N, M = shape(Alist[0])

    R = Qobj(scipy.sparse.csr_matrix((N * N, N * N)), [[N, N], [N, N]],
             [N * N, N * N])

    R.data = R.data.tolil()
    for I in range(N * N):
        a, b = vec2mat_index(N, I)
        for J in range(N * N):
            c, d = vec2mat_index(N, J)

            R.data[I, J] = -1.0j * (f_energies[a] -
                                    f_energies[b]) * (a == c) * (b == d)

            for A in Alist:
                s1 = s2 = 0
                for n in range(N):
                    s1 += A[a, n] * (n == c) * (n == d) - A[n, a] * (
                        a == c) * (a == d)
                    s2 += (A[n, a] + A[n, b]) * (a == c) * (b == d)

                dR = (a == b) * s1 - 0.5 * (1 - (a == b)) * s2

                if dR != 0.0:
                    R.data[I, J] += dR

    R.data = R.data.tocsr()
    return R
Esempio n. 2
0
def liouvillian_fast(H, c_op_list):
    """Assembles the Liouvillian superoperator from a Hamiltonian 
    and a ``list`` of collapse operators. Like liouvillian, but with an 
    experimental implementation which avoids creating extra Qobj instances,
    which can be advantageous for large systems.
    
    Parameters
    ----------
    H : qobj
        System Hamiltonian.
        
    c_op_list : array_like 
        A ``list`` or ``array`` of collpase operators.
    
    Returns
    -------
    L : qobj
        Louvillian superoperator.

    .. note::

        Experimental.
    
    """
    d = H.dims[1]
    L = Qobj()
    L.dims = [[H.dims[0][:], d[:]], [H.dims[1][:], d[:]]]
    L.shape = [prod(L.dims[0][0]) * prod(L.dims[0][1]), prod(L.dims[1][0]) * prod(L.dims[1][1])]
    L.data = -1j * (
        sp.kron(sp.identity(prod(d)), H.data, format="csr") - sp.kron(H.data.T, sp.identity(prod(d)), format="csr")
    )

    n_op = len(c_op_list)
    for m in range(0, n_op):
        L.data = L.data + sp.kron(sp.identity(prod(d)), c_op_list[m].data, format="csr") * sp.kron(
            c_op_list[m].data.T.conj().T, sp.identity(prod(d)), format="csr"
        )
        cdc = c_op_list[m].data.T.conj() * c_op_list[m].data
        L.data = L.data - 0.5 * sp.kron(sp.identity(prod(d)), cdc, format="csr")
        L.data = L.data - 0.5 * sp.kron(cdc.T, sp.identity(prod(d)), format="csr")
    return L
Esempio n. 3
0
def floquet_master_equation_tensor(Alist, f_energies):
    """
    Construct a tensor that represents the master equation in the floquet
    basis (with constant Hamiltonian and collapse operators).
    
    Simplest RWA approximation [Grifoni et al, Phys.Rep. 304 229 (1998)]
    """

    if isinstance(Alist, list):
        # Alist can be a list of rate matrices corresponding
        # to different operators that couple to the environment
        N, M = shape(Alist[0])
    else:
        # or a simple rate matrix, in which case we put it in a list
        Alist = [Alist]
        N, M = shape(Alist[0])
      
    R = Qobj(scipy.sparse.csr_matrix((N*N,N*N)), [[N,N], [N,N]], [N*N,N*N])

    R.data=R.data.tolil()      
    for I in range(N*N):
        a,b = vec2mat_index(N, I)
        for J in range(N*N):
            c,d = vec2mat_index(N, J)

            R.data[I,J] = - 1.0j * (f_energies[a]-f_energies[b]) * (a == c) * (b == d)
                    
            for A in Alist:               
                s1 = s2 = 0
                for n in range(N):
                    s1 += A[a,n] * (n == c) * (n == d) - A[n,a] * (a == c) * (a == d)
                    s2 += (A[n,a] + A[n,b]) * (a == c) * (b == d)
                       
                dR = (a == b) * s1 - 0.5 * (1 - (a == b)) * s2
                            
                if dR != 0.0:
                    R.data[I,J] += dR

    R.data=R.data.tocsr()
    return R                   
Esempio n. 4
0
def liouvillian_fast(H, c_op_list):
    """Assembles the Liouvillian superoperator from a Hamiltonian 
    and a ``list`` of collapse operators. Like liouvillian, but with an 
    experimental implementation which avoids creating extra Qobj instances,
    which can be advantageous for large systems.
    
    Parameters
    ----------
    H : qobj
        System Hamiltonian.
        
    c_op_list : array_like 
        A ``list`` or ``array`` of collpase operators.
    
    Returns
    -------
    L : qobj
        Louvillian superoperator.

    .. note::

        Experimental.
    
    """
    d=H.dims[1]
    L=Qobj()
    L.dims=[[H.dims[0][:],d[:]],[H.dims[1][:],d[:]]]
    L.shape=[prod(L.dims[0][0])*prod(L.dims[0][1]),prod(L.dims[1][0])*prod(L.dims[1][1])]
    L.data = -1j *(sp.kron(sp.identity(prod(d)), H.data,format='csr') - sp.kron(H.data.T,sp.identity(prod(d)),format='csr'))

    n_op = len(c_op_list)
    for m in range(0, n_op):
        L.data = L.data + sp.kron(sp.identity(prod(d)), c_op_list[m].data,format='csr') * sp.kron(c_op_list[m].data.T.conj().T,sp.identity(prod(d)),format='csr')
        cdc = c_op_list[m].data.T.conj()*c_op_list[m].data
        L.data = L.data - 0.5 * sp.kron(sp.identity(prod(d)), cdc,format='csr')
        L.data = L.data - 0.5 * sp.kron(cdc.T,sp.identity(prod(d)),format='csr')
    return L
Esempio n. 5
0
def photon_dist(rho):
    """return diagonals of photon density matrix"""

    from operators import vector_to_operator
    from qutip import Qobj, ptrace
    from basis import ldim_p, ldim_s

    rho_small = convert_rho.dot(rho)
    rho_small = vector_to_operator(rho_small)

    rho_q = Qobj()

    rho_q.data = rho_small
    rho_q.dims = [[ldim_p, ldim_s], [ldim_p, ldim_s]]

    rho_q = ptrace(rho_q, 0)

    pops = rho_q.data.diagonal()

    return pops
Esempio n. 6
0
def spost(A):
	"""Superoperator formed from post-multiplication by operator A

    Parameters
    ----------
    A : qobj
        Quantum operator for post multiplication.
    
    Returns
    -------
    super : qobj
       Superoperator formed from input qauntum object.
	"""
	if not isoper(A):
		raise TypeError('Input is not a quantum object')

	d=A.dims[0]
	S=Qobj()
	S.dims=[[d[:],A.dims[1][:]],[d[:],A.dims[0][:]]]
	S.shape=[prod(S.dims[0][0])*prod(S.dims[0][1]),prod(S.dims[1][0])*prod(S.dims[1][1])]
	S.data=sp.kron(A.data.T,sp.identity(prod(d)))
	return Qobj(S)
Esempio n. 7
0
def spre(A):
	"""Superoperator formed from pre-multiplication by operator A.
    
    Parameters
    ----------
    A : qobj
        Quantum operator for pre-multiplication.
    
    Returns
    --------
    super :qobj
        Superoperator formed from input quantum object.
    
    """
	if not isoper(A):
		raise TypeError('Input is not a quantum object')
	d=A.dims[1]
	S=Qobj()
	S.dims=[[A.dims[0][:],d[:]],[A.dims[1][:],d[:]]]
	S.shape=[prod(S.dims[0][0])*prod(S.dims[0][1]),prod(S.dims[1][0])*prod(S.dims[1][1])]
	S.data=sp.kron(sp.identity(prod(d)),A.data,format='csr')
	return S
Esempio n. 8
0
def wigner_comp(rho, xvec, yvec):
    """calculate wigner function of central site from density matrix rho
    at a grid of points defined by xvec and yvec"""

    global convert_rho
    from operators import expect, vector_to_operator
    from qutip import Qobj, wigner, ptrace
    from basis import ldim_p, ldim_s
    rho_small = convert_rho.dot(rho)

    rho_small = vector_to_operator(rho_small)

    rho_q = Qobj()

    rho_q.data = rho_small
    rho_q.dims = [[ldim_p, ldim_s], [ldim_p, ldim_s]]

    rho_q = ptrace(rho_q, 0)

    w = wigner(rho_q, xvec, yvec)

    return w
Esempio n. 9
0
def spre(A):
    """Superoperator formed from pre-multiplication by operator A.
    
    Parameters
    ----------
    A : qobj
        Quantum operator for pre-multiplication.
    
    Returns
    --------
    super :qobj
        Superoperator formed from input quantum object.
    
    """
    if not isoper(A):
        raise TypeError("Input is not a quantum object")
    d = A.dims[1]
    S = Qobj()
    S.dims = [[A.dims[0][:], d[:]], [A.dims[1][:], d[:]]]
    S.shape = [prod(S.dims[0][0]) * prod(S.dims[0][1]), prod(S.dims[1][0]) * prod(S.dims[1][1])]
    S.data = sp.kron(sp.identity(prod(d)), A.data, format="csr")
    return S
Esempio n. 10
0
def floquet_markov_mesolve(R, ekets, rho0, tlist, e_ops, opt=None):
    """
    Solve the dynamics for the system using the Floquet-Markov master equation.   
    """

    if opt == None:
        opt = Odeoptions()

    if opt.tidy:
        R.tidyup()

    #
    # check initial state
    #
    if isket(rho0):
        # Got a wave function as initial state: convert to density matrix.
        rho0 = ket2dm(rho0)
       
    #
    # prepare output array
    # 
    n_tsteps  = len(tlist)
    dt        = tlist[1]-tlist[0]
       
    output = Odedata()
    output.times = tlist
        
    if isinstance(e_ops, FunctionType):
        n_expt_op = 0
        expt_callback = True
        
    elif isinstance(e_ops, list):
  
        n_expt_op = len(e_ops)
        expt_callback = False

        if n_expt_op == 0:
            output.states = []
        else:
            output.expect = []
            output.num_expect = n_expt_op
            for op in e_ops:
                if op.isherm:
                    output.expect.append(zeros(n_tsteps))
                else:
                    output.expect.append(zeros(n_tsteps,dtype=complex))

    else:
        raise TypeError("Expectation parameter must be a list or a function")


    #
    # transform the initial density matrix and the e_ops opterators to the
    # eigenbasis: from computational basis to the floquet basis
    #
    if ekets != None:
        rho0 = rho0.transform(ekets, True)
        if isinstance(e_ops, list):
            for n in arange(len(e_ops)):             # not working
                e_ops[n] = e_ops[n].transform(ekets) #

    #
    # setup integrator
    #
    initial_vector = mat2vec(rho0.full())
    r = scipy.integrate.ode(cyq_ode_rhs)
    r.set_f_params(R.data.data, R.data.indices, R.data.indptr)
    r.set_integrator('zvode', method=opt.method, order=opt.order,
                              atol=opt.atol, rtol=opt.rtol,
                              max_step=opt.max_step)
    r.set_initial_value(initial_vector, tlist[0])

    #
    # start evolution
    #
    rho = Qobj(rho0)

    t_idx = 0
    for t in tlist:
        if not r.successful():
            break;

        rho.data = vec2mat(r.y)

        if expt_callback:
            # use callback method
            e_ops(t, Qobj(rho))
        else:
            # calculate all the expectation values, or output rho if no operators
            if n_expt_op == 0:
                output.states.append(Qobj(rho)) # copy psi/rho
            else:
                for m in range(0, n_expt_op):
                    output.expect[m][t_idx] = expect(e_ops[m], rho) # basis OK?

        r.integrate(r.t + dt)
        t_idx += 1
          
    return output
Esempio n. 11
0
def bloch_redfield_solve(R, ekets, rho0, tlist, e_ops=[], opt=None):
    """
    Evolve the ODEs defined by Bloch-Redfeild master equation.
    """

    if opt == None:
        opt = Odeoptions()
        opt.nsteps = 2500  #

    if opt.tidy:
        R.tidyup()

    #
    # check initial state
    #
    if isket(rho0):
        # Got a wave function as initial state: convert to density matrix.
        rho0 = rho0 * rho0.dag()

    #
    # prepare output array
    # m
    n_e_ops = len(e_ops)
    n_tsteps = len(tlist)
    dt = tlist[1] - tlist[0]

    if n_e_ops == 0:
        result_list = []
    else:
        result_list = []
        for op in e_ops:
            if op.isherm and rho0.isherm:
                result_list.append(zeros(n_tsteps))
            else:
                result_list.append(zeros(n_tsteps, dtype=complex))

    #
    # transform the initial density matrix and the e_ops opterators to the
    # eigenbasis
    #
    if ekets != None:
        rho0 = rho0.transform(ekets)
        for n in arange(len(e_ops)):
            e_ops[n] = e_ops[n].transform(ekets, False)

    #
    # setup integrator
    #
    initial_vector = mat2vec(rho0.full())
    r = scipy.integrate.ode(cyq_ode_rhs)
    r.set_f_params(R.data.data, R.data.indices, R.data.indptr)
    r.set_integrator(
        'zvode',
        method=opt.method,
        order=opt.order,
        atol=opt.atol,
        rtol=opt.rtol,  #nsteps=opt.nsteps,
        #first_step=opt.first_step, min_step=opt.min_step,
        max_step=opt.max_step)
    r.set_initial_value(initial_vector, tlist[0])

    #
    # start evolution
    #
    rho = Qobj(rho0)

    t_idx = 0
    for t in tlist:
        if not r.successful():
            break

        rho.data = vec2mat(r.y)

        # calculate all the expectation values, or output rho if no operators
        if n_e_ops == 0:
            result_list.append(Qobj(rho))
        else:
            for m in range(0, n_e_ops):
                result_list[m][t_idx] = expect(e_ops[m], rho)

        r.integrate(r.t + dt)
        t_idx += 1

    return result_list
Esempio n. 12
0
def bloch_redfield_solve(R, ekets, rho0, tlist, e_ops=[], opt=None):
    """
    Evolve the ODEs defined by Bloch-Redfeild master equation.
    """

    if opt == None:
        opt = Odeoptions()
        opt.nsteps = 2500  # 

    if opt.tidy:
        R.tidyup()

    #
    # check initial state
    #
    if isket(rho0):
        # Got a wave function as initial state: convert to density matrix.
        rho0 = rho0 * rho0.dag()
       
    #
    # prepare output array
    # m
    n_e_ops  = len(e_ops)
    n_tsteps = len(tlist)
    dt       = tlist[1]-tlist[0]

    if n_e_ops == 0:
        result_list = []
    else:
        result_list = []
        for op in e_ops:
            if op.isherm and rho0.isherm:
                result_list.append(zeros(n_tsteps))
            else:
                result_list.append(zeros(n_tsteps,dtype=complex))


    #
    # transform the initial density matrix and the e_ops opterators to the
    # eigenbasis
    #
    if ekets != None:
        rho0 = rho0.transform(ekets)
        for n in arange(len(e_ops)):
            e_ops[n] = e_ops[n].transform(ekets, False)

    #
    # setup integrator
    #
    initial_vector = mat2vec(rho0.full())
    r = scipy.integrate.ode(cyq_ode_rhs)
    r.set_f_params(R.data.data, R.data.indices, R.data.indptr)
    r.set_integrator('zvode', method=opt.method, order=opt.order,
                              atol=opt.atol, rtol=opt.rtol, #nsteps=opt.nsteps,
                              #first_step=opt.first_step, min_step=opt.min_step,
                              max_step=opt.max_step)
    r.set_initial_value(initial_vector, tlist[0])

    #
    # start evolution
    #
    rho = Qobj(rho0)

    t_idx = 0
    for t in tlist:
        if not r.successful():
            break;

        rho.data = vec2mat(r.y)
        
        # calculate all the expectation values, or output rho if no operators
        if n_e_ops == 0:
            result_list.append(Qobj(rho))
        else:
            for m in range(0, n_e_ops):
                result_list[m][t_idx] = expect(e_ops[m], rho)

        r.integrate(r.t + dt)
        t_idx += 1
          
    return result_list
Esempio n. 13
0
def steady(L,maxiter=100,tol=1e-6,method='solve'):
	"""Steady state for the evolution subject to the 
	supplied Louvillian.
    
    Parameters
    ----------
    L : qobj
        Liouvillian superoperator.
              
    maxiter : int 
        Maximum number of iterations to perform, default = 100.

    tol : float 
        Tolerance used by iterative solver, default = 1e-6.
    
    method : str
        Method for solving linear equations. Direct solver 'solve' (default) or 
        iterative biconjugate gradient method 'bicg'.
    
    Returns
    --------
    ket : qobj
        Ket vector for steady state.
    
    Notes
    -----
    Uses the inverse power method. 
    See any Linear Algebra book with an iterative methods section.
    
    """
	eps=finfo(float).eps
	if (not isoper(L)) & (not issuper(L)):
		raise TypeError('Steady states can only be found for operators or superoperators.')
	rhoss=Qobj()
	sflag=issuper(L)
	if sflag:
		rhoss.dims=L.dims[0]
		rhoss.shape=[prod(rhoss.dims[0]),prod(rhoss.dims[1])]
	else:
		rhoss.dims=[L.dims[0],1]
		rhoss.shape=[prod(rhoss.dims[0]),1]
	n=prod(rhoss.shape)
	L1=L.data+eps*_sp_inf_norm(L)*sp.eye(n,n,format='csr')
	v=randn(n,1)
	it=0
	while (la.norm(L.data*v,np.inf)>tol) and (it<maxiter):
		if method=='bicg':
		    v,check=bicg(L1,v,tol=tol)
		else:
		    v=spsolve(L1,v,use_umfpack=False)
		v=v/la.norm(v,np.inf)
		it+=1
	if it>=maxiter:
		raise ValueError('Failed to find steady state after ' + str(maxiter) +' iterations')
	#normalise according to type of problem
	if sflag:
		trow=sp.eye(rhoss.shape[0],rhoss.shape[0],format='lil')
		trow=trow.reshape((1,n)).tocsr()
		data=v/sum(trow.dot(v))
	else:
		data=data/la.norm(v)
	data=reshape(data,(rhoss.shape[0],rhoss.shape[1])).T
	data=sp.csr_matrix(data)
	rhoss.data=0.5*(data+data.conj().T)
	#data=sp.triu(data,format='csr')#take only upper triangle
	#rhoss.data=0.5*sp.eye(rhoss.shape[0],rhoss.shape[1],format='csr')*(data+data.conj().T) #output should be hermitian, but not guarenteed using iterative meth
	if qset.auto_tidyup:
	    return Qobj(rhoss).tidyup()
	else:
	    return Qobj(rhoss)
Esempio n. 14
0
def steady(L, maxiter=100, tol=1e-6, method='solve'):
    """Steady state for the evolution subject to the 
	supplied Louvillian.
    
    Parameters
    ----------
    L : qobj
        Liouvillian superoperator.
              
    maxiter : int 
        Maximum number of iterations to perform, default = 100.

    tol : float 
        Tolerance used by iterative solver, default = 1e-6.
    
    method : str
        Method for solving linear equations. Direct solver 'solve' (default) or 
        iterative biconjugate gradient method 'bicg'.
    
    Returns
    --------
    ket : qobj
        Ket vector for steady state.
    
    Notes
    -----
    Uses the inverse power method. 
    See any Linear Algebra book with an iterative methods section.
    
    """
    eps = finfo(float).eps
    if (not isoper(L)) & (not issuper(L)):
        raise TypeError(
            'Steady states can only be found for operators or superoperators.')
    rhoss = Qobj()
    sflag = issuper(L)
    if sflag:
        rhoss.dims = L.dims[0]
        rhoss.shape = [prod(rhoss.dims[0]), prod(rhoss.dims[1])]
    else:
        rhoss.dims = [L.dims[0], 1]
        rhoss.shape = [prod(rhoss.dims[0]), 1]
    n = prod(rhoss.shape)
    L1 = L.data + eps * sp_inf_norm(L) * sp.eye(n, n, format='csr')
    v = randn(n, 1)
    it = 0
    while (la.norm(L.data * v, inf) > tol) and (it < maxiter):
        if method == 'bicg':
            v, check = bicg(L1, v, tol=tol)
        else:
            v = spsolve(L1, v, use_umfpack=False)
        v = v / la.norm(v, inf)
        it += 1
    if it >= maxiter:
        raise ValueError('Failed to find steady state after ' + str(maxiter) +
                         ' iterations')
    #normalise according to type of problem
    if sflag:
        trow = sp.eye(rhoss.shape[0], rhoss.shape[0], format='lil')
        trow = trow.reshape((1, n)).tocsr()
        data = v / sum(trow.dot(v))
    else:
        data = data / la.norm(v)
    data = reshape(data, (rhoss.shape[0], rhoss.shape[1])).T
    data = sp.csr_matrix(data)
    rhoss.data = 0.5 * (data + data.conj().T)
    #data=sp.triu(data,format='csr')#take only upper triangle
    #rhoss.data=0.5*sp.eye(rhoss.shape[0],rhoss.shape[1],format='csr')*(data+data.conj().T) #output should be hermitian, but not guarenteed using iterative meth
    if qset.auto_tidyup:
        return Qobj(rhoss).tidyup()
    else:
        return Qobj(rhoss)
Esempio n. 15
0
def floquet_markov_mesolve(R, ekets, rho0, tlist, e_ops, opt=None):
    """
    Solve the dynamics for the system using the Floquet-Markov master equation.   
    """

    if opt == None:
        opt = Odeoptions()

    if opt.tidy:
        R.tidyup()

    #
    # check initial state
    #
    if isket(rho0):
        # Got a wave function as initial state: convert to density matrix.
        rho0 = ket2dm(rho0)

    #
    # prepare output array
    #
    n_tsteps = len(tlist)
    dt = tlist[1] - tlist[0]

    output = Odedata()
    output.times = tlist

    if isinstance(e_ops, FunctionType):
        n_expt_op = 0
        expt_callback = True

    elif isinstance(e_ops, list):

        n_expt_op = len(e_ops)
        expt_callback = False

        if n_expt_op == 0:
            output.states = []
        else:
            output.expect = []
            output.num_expect = n_expt_op
            for op in e_ops:
                if op.isherm:
                    output.expect.append(zeros(n_tsteps))
                else:
                    output.expect.append(zeros(n_tsteps, dtype=complex))

    else:
        raise TypeError("Expectation parameter must be a list or a function")

    #
    # transform the initial density matrix and the e_ops opterators to the
    # eigenbasis: from computational basis to the floquet basis
    #
    if ekets != None:
        rho0 = rho0.transform(ekets, True)
        if isinstance(e_ops, list):
            for n in arange(len(e_ops)):  # not working
                e_ops[n] = e_ops[n].transform(ekets)  #

    #
    # setup integrator
    #
    initial_vector = mat2vec(rho0.full())
    r = scipy.integrate.ode(cyq_ode_rhs)
    r.set_f_params(R.data.data, R.data.indices, R.data.indptr)
    r.set_integrator('zvode',
                     method=opt.method,
                     order=opt.order,
                     atol=opt.atol,
                     rtol=opt.rtol,
                     max_step=opt.max_step)
    r.set_initial_value(initial_vector, tlist[0])

    #
    # start evolution
    #
    rho = Qobj(rho0)

    t_idx = 0
    for t in tlist:
        if not r.successful():
            break

        rho.data = vec2mat(r.y)

        if expt_callback:
            # use callback method
            e_ops(t, Qobj(rho))
        else:
            # calculate all the expectation values, or output rho if no operators
            if n_expt_op == 0:
                output.states.append(Qobj(rho))  # copy psi/rho
            else:
                for m in range(0, n_expt_op):
                    output.expect[m][t_idx] = expect(e_ops[m],
                                                     rho)  # basis OK?

        r.integrate(r.t + dt)
        t_idx += 1

    return output
Esempio n. 16
0
def generic_ode_solve(r, psi0, tlist, expt_ops, opt, state_vectorize):
    """
    Internal function for solving ODEs.
    """
    
    #
    # prepare output array
    # 
    n_tsteps  = len(tlist)
    dt        = tlist[1]-tlist[0]
       
    output = Odedata()
    output.times = tlist
        
    if isinstance(expt_ops, FunctionType):
        n_expt_op = 0
        expt_callback = True
        
    elif isinstance(expt_ops, list):
  
        n_expt_op = len(expt_ops)
        expt_callback = False

        if n_expt_op == 0:
            output.states = []
        else:
            output.expect = []
            output.num_expect = n_expt_op
            for op in expt_ops:
                if op.isherm and psi0.isherm:
                    output.expect.append(zeros(n_tsteps))
                else:
                    output.expect.append(zeros(n_tsteps,dtype=complex))

    else:
        raise TypeError("Expectation parameter must be a list or a function")
   
    #
    # start evolution
    #
    psi = Qobj(psi0)

    t_idx = 0
    for t in tlist:
        if not r.successful():
            break;

        psi.data = state_vectorize(r.y)

        if expt_callback:
            # use callback method
            expt_ops(t, Qobj(psi))
        else:
            # calculate all the expectation values, or output rho if no operators
            if n_expt_op == 0:
                output.states.append(Qobj(psi)) # copy psi/rho
            else:
                for m in range(0, n_expt_op):
                    output.expect[m][t_idx] = expect(expt_ops[m], psi)

        r.integrate(r.t + dt)
        t_idx += 1
        
    if not opt.rhs_reuse and odeconfig.tdname != None:
        try:
            os.remove(odeconfig.tdname+".pyx")
        except:
            print('Error removing '+str(odeconfig.tdname)+".pyx file")
            pass

    return output
Esempio n. 17
0
def generic_ode_solve(r, psi0, tlist, expt_ops, opt, state_vectorize):
    """
    Internal function for solving ODEs.
    """

    #
    # prepare output array
    #
    n_tsteps = len(tlist)
    dt = tlist[1] - tlist[0]

    output = Odedata()
    output.times = tlist

    if isinstance(expt_ops, FunctionType):
        n_expt_op = 0
        expt_callback = True

    elif isinstance(expt_ops, list):

        n_expt_op = len(expt_ops)
        expt_callback = False

        if n_expt_op == 0:
            output.states = []
        else:
            output.expect = []
            output.num_expect = n_expt_op
            for op in expt_ops:
                if op.isherm and psi0.isherm:
                    output.expect.append(zeros(n_tsteps))
                else:
                    output.expect.append(zeros(n_tsteps, dtype=complex))

    else:
        raise TypeError("Expectation parameter must be a list or a function")

    #
    # start evolution
    #
    psi = Qobj(psi0)

    t_idx = 0
    for t in tlist:
        if not r.successful():
            break

        psi.data = state_vectorize(r.y)

        if expt_callback:
            # use callback method
            expt_ops(t, Qobj(psi))
        else:
            # calculate all the expectation values, or output rho if no operators
            if n_expt_op == 0:
                output.states.append(Qobj(psi))  # copy psi/rho
            else:
                for m in range(0, n_expt_op):
                    output.expect[m][t_idx] = expect(expt_ops[m], psi)

        r.integrate(r.t + dt)
        t_idx += 1

    if not opt.rhs_reuse and odeconfig.tdname != None:
        try:
            os.remove(odeconfig.tdname + ".pyx")
        except:
            print('Error removing ' + str(odeconfig.tdname) + ".pyx file")
            pass

    return output