示例#1
0
    def error_deriv(self, Φ, z_step, list_index_aux_stable=None):
        """
        The error associated with losing all flux terms into the k auxiliary and n’ state.
        Where k is in H_t and n' is in S_t.

        .. math::
            \sum_{n \in \mathcal{S}_{t}} \\left\\vert \\frac{\delta_{a} \psi^{(\\vec{k})}_{t,n}}{\delta t_a} \\right\\vert^2

        .. math::
            \sum_{\\vec{k} \in \mathcal{H}_{t}} \\left\\vert \\frac{\delta_{a} \psi^{(\\vec{k})}_{t,n}}{\delta t_a} \\right\\vert^2

        PARAMETERS
        ----------
        1. Φ : np.array
               The current full hierarchy vector
        2. z_step : list
                    the list of noise terms (compressed) for the next timestep
        3. list_index_aux_stable : list
                                   a list relative indices for the stable auxiliaries

        RETURNS
        -------
        1. E2_del_phi : np.array
                        the error associated with losing flux to a component (either
                        hierarchy or state basis element) in H_t direct sum S_t
        """
        if list_index_aux_stable is not None:
            # Error arises for flux only out of the stable auxiliaries
            # --------------------------------------------------------
            Φ_stab = np.zeros(self.n_state * self.n_hier, dtype=np.complex128)
            Φ_stab_v = Φ_stab.view().reshape([self.n_state, self.n_hier], order="F")
            Φ_stab_v[:, list_index_aux_stable] = Φ.view().reshape(
                [self.n_state, self.n_hier], order="F"
            )[:, list_index_aux_stable]
        else:
            Φ_stab = Φ

        list_avg_L2 = [
            operator_expectation(L, Φ[: self.n_state]) for L in self.system.list_L2_coo
        ]

        P1_del_phi = (
            self.eom.K2_k @ Φ_stab + self.eom.K2_kp1 @ Φ_stab + self.eom.K2_km1 @ Φ_stab
        )

        for j in range(len(self.system.list_absindex_L2)):
            P1_del_phi += z_step[j] * self.eom.Z2_k[j] @ Φ_stab
            P1_del_phi += np.conj(list_avg_L2[j]) * self.eom.Z2_kp1[j] @ Φ_stab

        E2_del_phi = np.abs(
            P1_del_phi.reshape([self.n_state, self.n_hier], order="F") / hbar
        )

        return E2_del_phi
示例#2
0
    def error_deriv(self, Φ, z_step, list_index_aux_stable=None):
        """
        The error associated with losing all flux terms into the k auxiliary and n state,
        where k is in A_t and n is in S_t. This corresponds to equation 29 in arXiv:2008.06496

        PARAMETERS
        ----------
        1. Φ : np.array
               The current full hierarchy vector
        2. z_step : list
                    the list of noise terms (compressed) for the next timestep
        3. list_index_aux_stable : list
                                   a list relative indices for the stable auxiliaries

        RETURNS
        -------
        1. E2_del_phi : np.array
                        the error associated with losing flux to a component (either
                        hierarchy or state basis element) in H_t direct sum S_t
        """
        if list_index_aux_stable is not None:
            # Error arises for flux only out of the stable auxiliaries
            # --------------------------------------------------------
            Φ_stab = np.zeros(self.n_state * self.n_hier, dtype=np.complex128)
            Φ_stab_v = Φ_stab.view().reshape([self.n_state, self.n_hier],
                                             order="F")
            Φ_stab_v[:, list_index_aux_stable] = Φ.view().reshape(
                [self.n_state, self.n_hier], order="F")[:,
                                                        list_index_aux_stable]
        else:
            Φ_stab = Φ

        list_avg_L2 = [
            operator_expectation(L, Φ[:self.n_state])
            for L in self.system.list_L2_coo
        ]

        P1_del_phi = (self.eom.K2_k @ Φ_stab + self.eom.K2_kp1 @ Φ_stab +
                      self.eom.K2_km1 @ Φ_stab)

        for j in range(len(self.system.list_absindex_L2)):
            P1_del_phi += z_step[j] * self.eom.Z2_k[j] @ Φ_stab
            P1_del_phi += np.conj(list_avg_L2[j]) * self.eom.Z2_kp1[j] @ Φ_stab

        E2_del_phi = np.abs(
            P1_del_phi.reshape([self.n_state, self.n_hier], order="F") / hbar)

        return E2_del_phi
示例#3
0
def test_calc_deltz_zmem():
    lind_dict = hops.basis.system.param["LIST_L2_COO"]
    lop_list = lind_dict
    lavg_list = [operator_expectation(L2, hops.psi) for L2 in lop_list]
    g_list = hops.basis.system.param["G"]
    w_list = hops.basis.system.param["W"]
    z_mem = np.array([0.0 for g in g_list])
    d_zmem = calc_delta_zmem(
        z_mem,
        lavg_list,
        g_list,
        w_list,
        hops.basis.system.param["LIST_INDEX_L2_BY_NMODE1"],
        np.array(range(len(g_list))),
    )
    assert len(d_zmem) == len(g_list)
    assert d_zmem[0] == 10.0
    assert d_zmem[1] == 5.0
    assert d_zmem[2] == 0
    assert d_zmem[3] == 0
    assert type(d_zmem) == type(np.array([]))
示例#4
0
def test_compress_zmem():
    lind_dict = hops.basis.system.param["LIST_L2_COO"]
    lop_list = lind_dict
    lavg_list = [operator_expectation(L2, hops.psi) for L2 in lop_list]
    g_list = hops.basis.system.param["G"]
    w_list = hops.basis.system.param["W"]
    z_mem = np.array([0.0 for g in g_list])
    z_mem = calc_delta_zmem(
        z_mem,
        lavg_list,
        g_list,
        w_list,
        hops.basis.system.param["LIST_INDEX_L2_BY_NMODE1"],
        range(len(g_list)),
    )
    z_compress = compress_zmem(
        z_mem,
        hops.basis.system.param["LIST_INDEX_L2_BY_NMODE1"],
        hops.basis.system.list_absindex_mode,
    )
    assert len(z_compress) == 2
    assert z_compress[0] == 15.0
    assert z_compress[1] == 0.0
示例#5
0
def test_l_avg_calculation():
    lind_dict = hops.basis.system.param["LIST_L2_COO"]
    lop_list = lind_dict
    lavg_list = [operator_expectation(L2, hops.psi) for L2 in lop_list]
    assert lavg_list[0] == 1.0
    assert lavg_list[1] == 0.0
示例#6
0
            def dsystem_dt(
                Φ,
                z_mem1_tmp,
                z_rnd1_tmp,
                z_rnd2_tmp,
                K2_stable=K2_stable,
                Z2_k=self.Z2_k,
                Z2_kp1=self.Z2_kp1,
                list_L2=list_L2,
                list_index_L2_by_hmode=system.list_index_L2_by_hmode,
                list_mode_absindex_L2=system.param["LIST_INDEX_L2_BY_HMODE"],
                nsys=system.size,
                list_absindex_L2=system.list_absindex_L2,
                list_absindex_mode=system.list_absindex_mode,
                list_g=system.param["G"],
                list_w=system.param["W"],
                list_tuple_index_phi1_L2_mode=list_tuple_index_phi1_L2_mode,
            ):
                """
                This is the core function for calculating the time-evolution of the
                wave function. The logic here becomes slightly complicated because
                we need use both the relative and absolute indices at different points.

                z_hat1_tmp : relative
                z_rnd1_tmp : absolute
                z_rnd2_tmp: absolute
                z_mem1_tmp : absolute
                list_avg_L2 : relative
                Z2_k, Z2_kp1 : relative
                Φ_deriv : relative
                z_mem1_deriv : absolute

                The nonlinear evolution equation used to perform this calculation
                takes the following form:
                ~
                Ψ̇_t^(k)=(-iH-kw+(z~_t)L)ψ_t^(k) + κα(0)Lψ_t^(k-1) - (L†-〈L†〉_t)ψ_t^(k+1)
                with z~ = z^* + ∫ds(a^*)(t-s)〈L†〉
                A super operator notation is implemented in this code.

                PARAMETERS
                ----------
                1. Φ : np.array
                       current full hierarchy
                2. z_mem1_tmp : np.array
                                array of memory values for each mode
                3. z_rnd1_tmp : np.array
                                array of random noise corresponding to NOISE1 for the
                                set of time points required in the integration
                4. z_rnd2_tmp : np.array
                                array of random noise corresponding to NOISE2 for the
                                set of time points required in the integration
                5. K2_stable : np.array
                               the component of the super operator that does not depend
                               on noise
                6. Z2_k : np.array
                          the component of the super operator that is multiplied by
                          noise z and maps the Kth hierarchy to the Kth hierarchy
                7. Z2_kp1 : np.array
                            the component of the super operator that is multiplied by
                            noise z and maps the (K+1) hierarchy to the kth hierarchy
                8. list_L2 : list
                             list of L operators
                9. list_index_L2_by_hmode : list
                                             list of length equal to the number of modes
                                             in the current hierarchy basis and each
                                             entry is an index for the relative list_L2.
                10. list_mode_absindex_L2 : list
                                            list of length equal to the number of
                                            'modes' in the current hierarchy basis and
                                            each entry is an index for the absolute
                                            list_L2.
                11. nsys : int
                          t he current dimension (size) of the system basis
                12. list_absindex_L2 : list
                                       list of length equal to the number of L-operators
                                       in the current system basis where each element
                                       is the index for the absolute list_L2
                13. list_absindex_mode : list
                                         list of length equal to the number of modes in
                                         the current system basis that corresponds to
                                         the absolute index of the modes
                14. list_g : list
                             list of pre exponential factors for bath correlation
                             functions
                15. list_w : list
                             list of exponents for bath correlation functions (w = γ+iΩ)
                16. list_tuple_index_phi1_index_L2 : list
                                                     list of tuples with each tuple
                                                     containing the index of the first
                                                     auxiliary mode (phi1) in the
                                                     hierarchy and the index of the
                                                     corresponding L operator

                RETURNS
                -------
                1. Φ_deriv : np.array
                             the derivative of phi with respect to time
                2. z_mem1_deriv : np.array
                                  the derivative of z_mem with respect to time
                """

                # Construct Noise Terms
                # ---------------------
                z_hat1_tmp = np.conj(
                    z_rnd1_tmp[list_absindex_L2]) + compress_zmem(
                        z_mem1_tmp, list_index_L2_by_hmode, list_absindex_mode)
                z_tmp2 = z_rnd2_tmp[list_absindex_L2]

                # Construct other fluctuating terms
                # ---------------------------------
                list_avg_L2 = [
                    operator_expectation(L, Φ[:nsys]) for L in list_L2
                ]  # <L>
                norm_corr = calc_norm_corr(
                    Φ,
                    z_hat1_tmp,
                    list_avg_L2,
                    list_L2,
                    nsys,
                    list_tuple_index_phi1_L2_mode,
                    np.array(list_g)[np.array(list_absindex_mode)],
                    np.array(list_w)[np.array(list_absindex_mode)],
                )

                # calculate dphi/dt
                # -----------------
                Φ_deriv = K2_stable @ Φ
                Φ_deriv -= norm_corr * Φ
                for j in range(len(list_avg_L2)):
                    # ASSUMING: L = L^*
                    Φ_deriv += (z_hat1_tmp[j] +
                                2 * np.real(z_tmp2[j])) * (Z2_k[j] @ Φ)
                    Φ_deriv += np.conj(list_avg_L2[j]) * (Z2_kp1[j] @ Φ)

                # calculate dz/dt
                # ---------------
                z_mem1_deriv = calc_delta_zmem(
                    z_mem1_tmp,
                    list_avg_L2,
                    list_g,
                    list_w,
                    list_mode_absindex_L2,
                    list_absindex_mode,
                )

                return Φ_deriv, z_mem1_deriv