Python: Select all
    def expectation_value_multi_site(self, ops, sites, opstr=None, str_on_first=True):
        r"""Expectation value  ``<psi|op_1 op_2 ... op_n |psi>/<psi|psi>`` of
        tensor products of single site operators.
        Given the MPS in canonical form, it calculates the expectation value of
        a tensor product of single-site operators.
        For example the contraction of three one-site operators on sites `i`
        `i+1` `i+2` would look like::
            |          .--S--B[i]---B[i+1]--B[i+2]--.
            |          |     |      |       |       |
            |          |    op1    op2     op3      |
            |          |     |      |       |       |
            |          |     |      |       |       |
            |          .--S--B*[i]--B*[i+1]-B*[i+2]-.
    Parameters
            ----------
            ops : List of { :class:`~tenpy.linalg.np_conserved.Array` | str }
                sList of one-site operators. This method calculates the
                expectation value of the n-sites operator given by their tensor
                product.
            sites : List of int
                List of site indices.
                ``ops[x]`` acts on site ``sites[x]``.
                Is sorted before use, i.e. the order is ignored.
            opstr : None | (list of) { :class:`~tenpy.linalg.np_conserved.Array` | str }
                Ignored by default (``None``).
        """
        ops = npc.to_iterable_arrays(ops)
        sites = np.sort(sites)
        initial_site = sites[0]
        m = len(sites)
        op = self.get_op(ops, 0)
        theta = self.get_theta(initial_site, 1)
        C = npc.tensordot(op, theta, axes=['p*', 'p0'])
        C = npc.tensordot(theta.conj(), C, axes = [['p0*', 'vL*'],['p', 'vL']])
        for i in range(m-1):
            B = self.get_B(initial_site+i+1, form ='B')
            C = npc.tensordot(C, B,  axes=['vR', 'vL'])
            op = self.get_op(ops, i+1)
            C = npc.tensordot(op, C, axes=['p*','p'])
            if i == m-2:
                C_exp = npc.inner(B.conj(), C, axes=[['vL*','p*','vR*'],['vR*','p','vR']])
                break
            else:
                C = npc.tensordot(B.conj(), C, axes=[['vL*','p*'],['vR*','p']])
        return np.real_if_close(C_exp)