Ejemplo n.º 1
0
Archivo: oqs.py Proyecto: binggu56/lime
    def expect(self, rho0, e_ops):

        evecs = self.evecs
        U = self.U
        # transform the intial density matrix to eigenbasis
        rho0_eb = dm2vec(transform(rho0, evecs))
        e_ops = [transform(e, evecs) for e in e_ops]

        if isinstance(U, list):
            # if the propagator is given in list form
            Nt = len(U)
            out = np.zeros((Nt, len(e_ops)), dtype=complex)

            for j, e in enumerate(e_ops):

                rholist = [u.dot(rho0_eb) for u in U]

                out[:, j] = [np.vdot(e, rho) for rho in rholist]

        else:  # if propagator is ndarray
            Nt = U.shape[-1]
            out = np.zeros((Nt, len(e_ops)), dtype=complex)

            rho = np.tensordot(U, rho0_eb, axes=([1], [0]))
            for j, e in enumerate(e_ops):
                out[:, j] = dm2vec(e).dot(rho)

        return out
Ejemplo n.º 2
0
Archivo: oqs.py Proyecto: binggu56/lime
    def correlation_2op_1t(self, rho0, a, b, tau):
        # 2-point correlation function <<I|a G(tau) b|rho0>>

        if self.G is None:
            self.propagator(tau)

        G = self.G

        # unit operator in Liouville space
        idm = dm2vec(identity(self.dim))

        # for _ in [a, b, rho0]:
        #     if _.ndim == 2:
        #         _ = dm2vec(_)

        if rho0.ndim == 2:
            rho0 = dm2vec(rho0)

        corr = idm.dot(a.dot(np.tensordot(G, b.dot(rho0), axes=([1], [0]))))

        return corr
Ejemplo n.º 3
0
Archivo: oqs.py Proyecto: binggu56/lime
 def idm(self, sp=True):
     if sp:
         return dm2vec(identity(
             self.dim))  # identity operator in Liouville space
     else:
         return dm2vec(identity(self.dim).toarray())
Ejemplo n.º 4
0
Archivo: oqs.py Proyecto: binggu56/lime
def _redfield(R,
              rho0,
              evecs=None,
              Nt=1,
              dt=0.005,
              t0=0,
              e_ops=[],
              return_result=True):
    """
    time propagation of the Redfield quantum master equation with RK4

    Input
    -------
    R: 2d array
        Redfield tensor

    rho0: 2d array
        initial density matrix

    Nt: total number of time steps

    dt: time step
    e_ops: list of observable operators

    Returns
    =========
    rho: 2D array
        density matrix at time t = Nt * dt
    """

    N = rho0.shape[0]
    # initialize the density matrix
    if e_ops is None:
        e_ops = []

    # basis transformation
    if evecs is not None:
        rho0 = transform(rho0, evecs)
        e_ops = [transform(e, evecs) for e in e_ops]

    rho = rho0.copy()
    rho = dm2vec(rho).astype(complex)

    # tf = t0 + dt * Nt
    # result = solve_ivp(rhs, t_span=(t0, tf), y0=rho0, vectorized=True, args=(R, ))

    t = t0

    if return_result == False:

        f_obs = open('obs.dat', 'w')
        fmt = '{} ' * (len(e_ops) + 1) + '\n'

        for k in range(Nt):

            # compute observables
            # observables = np.zeros(len(e_ops), dtype=complex)
            # for i, obs_op in enumerate(e_ops):

            observables = [obs_dm(rho, e) for e in e_ops]

            t += dt
            rho = rk4(rho, rhs, dt, R)

            # dipole-dipole auto-corrlation function
            #cor = np.trace(np.matmul(d, rho))

            # take a partial trace to obtain the rho_el

            f_obs.write(fmt.format(t, *observables))

        f_obs.close()
        # f_dm.close()

        return rho

    else:

        rholist = []  # store density matries

        result = Result(dt=dt, Nt=Nt, rho0=rho0)

        observables = np.zeros((Nt, len(e_ops)), dtype=complex)

        for k in range(Nt):

            t += dt
            rho = rk4(rho, rhs, dt, R)

            tmp = np.reshape(rho, (N, N))
            rholist.append(transform(tmp, dag(evecs)))

            observables[k, :] = [obs_dm(tmp, e) for e in e_ops]

        result.observables = observables
        result.rholist = rholist

        return result
Ejemplo n.º 5
0
Archivo: oqs.py Proyecto: binggu56/lime
    def correlation_4op_3t(self, rho0, oplist, signature, tau):
        """
        4-point correlation function <<I|A G(tau3) B G(tau2) C G(tau1) D|rho0>>

        make sure all the operators, density matrix, and the GF are represented
        in the eigenbasis of H.

        Parameters
        ----------
        rho0 : TYPE
            DESCRIPTION.
        oplist : TYPE
            DESCRIPTION.
        signature : str of (lr+-)
            signifies the superoperator transform the operators in the oplist
        tau : TYPE
            DESCRIPTION.

        Raises
        ------
        ValueError
            DESCRIPTION.

        Returns
        -------
        TYPE
            DESCRIPTION.

        """

        if len(oplist) != 4:
            raise ValueError('Number of operators is not 4.')

        a = operator_to_superoperator(oplist[0], signature[0])
        b = operator_to_superoperator(oplist[1], signature[1])
        c = operator_to_superoperator(oplist[2], signature[2])
        d = operator_to_superoperator(oplist[3], signature[3])

        for _ in oplist:
            if issparse(_):
                _ = _.toarray()

        # nmax = max(len(tau3), len(tau2), len(tau1))

        # g = -1j * (tau > 0) * self.propagator(tau)
        # G = np.zeros((self.dim, self.dim, len(tau)))

        # for n, elem in enumerate(g):
        #     G[:,:, n] = g[n]

        if self.G is None:
            self.propagator(tau)

        G = self.G

        # unit operator in Liouville space
        N = self.dim
        idm = self.idm(sp=False)

        # print(d.shape, dm2vec(rho0.toarray()).shape)
        if issparse(rho0):
            rho = d.dot(dm2vec(rho0.toarray()))
        else:
            rho = d.dot(dm2vec(rho0))

        # print(type(rho), rho.shape)

        if issparse(rho): rho = rho.toarray()

        tmp = np.tensordot(G, rho, axes=((1), (0)))
        tmp = c.dot(tmp)
        tmp = np.tensordot(G, tmp, axes=([1], [0]))  # ajk

        # tmp = np.einsum('dcj, ca, abk, b -> djk', G, c, G, rho)
        '''
        Scipy sparse matrix does not support dimensions more than 2, so
        ndarray has to be used for the tensor products.

        This can be improved by using sparse package.
        '''
        tmp = np.tensordot(b.todense(), tmp, axes=([1], [0]))
        # tmp = b.todense().dot(tmp)

        tmp = np.tensordot(G, tmp, axes=([1], [0]))

        return oe.contract('a, ab, bijk -> ijk', idm, a.todense(), tmp)