Exemplo n.º 1
0
    def _transl2fermi(self, tensor: Tensor):
        """Translate a tensor object in terms of the fermion operators.

        This is an internally utility.  The resulted tensor has the internal
        fermion drudge object as its owner.
        """
        return Tensor(self._ph_dr, tensor.subst_all(self._defs).terms)
Exemplo n.º 2
0
    def eval_vev(self, tensor: Tensor):
        r"""Evaluate the vacuum expectation value.

        The VEV facility works *as if* we do substitution

        .. math::

            P_p &= c_{p \downarrow} c_{p \uparrow} \\
            P^\dag_p &= c^\dag_{p \uparrow} c^\dag_{p \downarrow} \\
            N_p &= c^\dag_{p \uparrow} c_{p \uparrow}
                + c^\dag_{p \downarrow} c_{p \downarrow} \\

        for :math:`p` in either particle or hole range and evaluate the
        expectation value with respect to the Fermi vacuum.
        """

        transled = self._transl2fermi(tensor)
        res = self._ph_dr.eval_fermi_vev(transled)
        return Tensor(self, res.terms)
Exemplo n.º 3
0
    def eval_agp(self, tensor: Tensor, zlist):
        r"""Evaluate the vacuum expectation value.

        The AGP expectation value facility works *as if* we do substitution
        Takes as input the list of z matrices

        .. math::

            \langle P^\dag_p P_q \rangle &= A^{(0)}_{pq} \\
            \langle P^\dag_p N_r P_q \rangle &= A^{(1)}_{pqr} \\
            \langle P^\dag_p P^\dag_q P_rP_s\rangle &= A^{(0)}_{pqrs} \\

        """

        num_ = self.cartan
        pdag_ = self.raise_
        p_ = self.lower

        def get_vev_of_term(term):
            """Return the vev mapping of the term"""
            vecs = term.vecs
            t_amp = term.amp
            pdag_cnt = 0
            p_cnt = 0
            n_cnt = 0

            pdag_indlist = []
            p_indlist = []
            n_indlist = []

            if len(vecs) == 0:
                return [
                    Term(sums=term.sums, amp=t_amp * zlist[0][0], vecs=vecs)
                ]

            # Classify the indices into pdag, n, and p indicies
            for i in vecs:
                if i.base == pdag_:
                    pdag_indlist.extend(list(i.indices))
                elif i.base == p_:
                    p_indlist.extend(list(i.indices))
                elif i.base == num_:
                    n_indlist.extend(list(i.indices))
                else:
                    return []

            # Count the number of indices
            pdag_cnt = len(pdag_indlist)
            p_cnt = len(p_indlist)

            # First, we extract only the unique N indices
            unique_n_indlist = list(set(n_indlist))
            n_cnt = len(unique_n_indlist)

            # Introduce appropriate power of 2 in amplitude to include the effect
            #   of unique indices only  being considered in N
            ldiff = len(n_indlist) - len(unique_n_indlist)
            t_amp *= 2**(ldiff)

            if pdag_cnt != p_cnt:
                # The expression must have equal number of Pdag's and P_'s
                return []
            elif len(pdag_indlist) != len(set(pdag_indlist)):
                return []
            elif len(p_indlist) != len(set(p_indlist)):
                return []
            else:
                # Combining all the indices
                indcs = pdag_indlist
                indcs.extend(unique_n_indlist)
                indcs.extend(p_indlist)

                # Counting the different number of indices in order
                # to select the right symbol 'asymb'
                idx1 = int(n_cnt)
                idx_ppdag = len(indcs) - n_cnt
                idx2 = int((idx_ppdag / 2))

                asymb = zlist[idx1][idx2]
                t_amp = t_amp * asymb[indcs]

            return [Term(sums=term.sums, amp=t_amp, vecs=())]

        return tensor.bind(get_vev_of_term)
Exemplo n.º 4
0
    def eval_agp(self, tensor: Tensor, zlist):
        r"""Evaluate the vacuum expectation value.

        The AGP expectation value facility works *as if* we do substitution
        Takes as input the list of z matrices

        .. math::

            \langle P^\dag_p P_q \rangle &= A^{(0)}_{pq} \\
            \langle P^\dag_p N_r P_q \rangle &= A^{(1)}_{pqr} \\
            \langle P^\dag_p P^\dag_q P_rP_s\rangle &= A^{(0)}_{pqrs} \\

        """

        num_ = self.cartan
        pdag_ = self.raise_
        p_ = self.lower

        def get_vev_of_term(term):
            """Return the vev mapping of the term"""
            vecs = term.vecs
            t_amp = term.amp
            pdag_cnt = 0
            p_cnt = 0
            n_cnt = 0

            pdag_indlist = []
            p_indlist = []
            n_indlist = []

            if len(vecs) == 0:
                return [Term(sums=term.sums, amp=t_amp, vecs=vecs)]

            for i in vecs:
                if i.base == pdag_:
                    pdag_cnt += 1
                    pdag_indlist.extend(list(i.indices))
                elif i.base == p_:
                    p_cnt += 1
                    p_indlist.extend(list(i.indices))
                elif i.base == num_:
                    n_cnt += 1
                    n_indlist.extend(list(i.indices))
                else:
                    return []

            if pdag_cnt != p_cnt:
                # The expression must have equal number of Pdag's and P_'s
                return []
            elif len(pdag_indlist) != len(set(pdag_indlist)):
                return []
            elif len(p_indlist) != len(set(p_indlist)):
                return []
            else:
                # Combining all the indices
                indcs = pdag_indlist
                indcs.extend(n_indlist)
                indcs.extend(p_indlist)

                # Counting the different number of indices in order
                # to select the right symbol 'asymb'
                idx1 = int(n_cnt)
                idx_ppdag = len(indcs) - n_cnt
                idx2 = int((idx_ppdag / 2))

                asymb = zlist[idx1][idx2]
                t_amp = t_amp * asymb[indcs]

            return [Term(sums=term.sums, amp=t_amp, vecs=())]

        return tensor.bind(get_vev_of_term)
Exemplo n.º 5
0
 def eval_awev (self, tensor: Tensor):
     terms = self._eval_awev (tensor)
     return Tensor (self, terms)