Beispiel #1
0
    def energy_1x1(self, state, env_c4v):
        r"""
        :param state: wavefunction
        :param env_c4v: CTM c4v symmetric environment
        :type state: IPEPS
        :type env_c4v: ENV_C4V
        :return: energy per site
        :rtype: float

        We assume 1x1 C4v iPEPS which tiles the lattice with a bipartite pattern composed 
        of two tensors A, and B=RA, where R rotates approriately the physical Hilbert space 
        of tensor A on every "odd" site::

            1x1 C4v => rotation P => BIPARTITE

            A A A A                  A B A B
            A A A A                  B A B A
            A A A A                  A B A B
            A A A A                  B A B A

        Due to C4v symmetry it is enough to construct a single reduced density matrix 
        :py:func:`ctm.one_site_c4v.rdm_c4v.rdm2x2` of a 2x2 plaquette. Afterwards, 
        the energy per site `e` is computed by evaluating a single plaquette term :math:`h_p`
        containing two nearest-neighbour terms :math:`\bf{S}.\bf{S}` and `h4_p` as:

        .. math::

            e = \langle \mathcal{h_p} \rangle = Tr(\rho_{2x2} \mathcal{h_p})

        """
        rdm2x2 = rdm_c4v.rdm2x2(state, env_c4v)
        energy_per_site = torch.einsum('ijklabcd,ijklabcd', rdm2x2,
                                       self.hp_rot)
        return energy_per_site
Beispiel #2
0
    def energy_1x1_plaqette(self, state, env_c4v):
        r"""
        :param state: wavefunction
        :param env_c4v: CTM c4v symmetric environment
        :type state: IPEPS
        :type env_c4v: ENV_C4V
        :return: energy per site
        :rtype: float

        For 1-site invariant c4v iPEPS it's enough to construct a single reduced
        density matrix of a 2x2 plaquette. Afterwards, the energy per site `e` is 
        computed by evaluating individual terms in the Hamiltonian through
        :math:`\langle \mathcal{O} \rangle = Tr(\rho_{2x2} \mathcal{O})`
        
        .. math:: 

            e = -(\langle h2_{<\bf{0},\bf{x}>} \rangle + \langle h2_{<\bf{0},\bf{y}>} \rangle)
            + q\langle h4_{\bf{0}} \rangle - h_x \langle h4_{\bf{0}} \rangle

        """
        rdm2x2 = rdm_c4v.rdm2x2(state, env_c4v)
        energy_per_site = torch.einsum('ijklabcd,ijklabcd', rdm2x2, self.hp)

        # From individual contributions
        # eSx= torch.einsum('ijklajkl,ia',rdm2x2,self.sx)
        # eSzSz= torch.einsum('ijklabkl,ijab',rdm2x1,self.szsz)
        # eSzSzSzSz= torch.einsum('ijklabcd,ijklabcd',rdm2x2,self.szszszsz)
        # energy_per_site = -2*eSzSz - self.hx*eSx + self.q*eSzSzSzSz
        return energy_per_site
Beispiel #3
0
    def eval_obs(self, state, env_c4v):
        r"""
        :param state: wavefunction
        :param env_c4v: CTM c4v symmetric environment
        :type state: IPEPS
        :type env_c4v: ENV_C4V
        :return:  expectation values of observables, labels of observables
        :rtype: list[float], list[str]

        Computes the following observables in order

            1. :math:`\langle 2S^z \rangle,\ \langle 2S^x \rangle` for each site in the unit cell

        TODO 2site observable SzSz
        """
        obs = dict()
        with torch.no_grad():
            rdm1x1 = rdm_c4v.rdm1x1(state, env_c4v)
            for label, op in self.obs_ops.items():
                obs[f"{label}"] = torch.trace(rdm1x1 @ op)
            obs["sx"] = 0.5 * (obs["sp"] + obs["sm"])

            rdm2x2 = rdm_c4v.rdm2x2(state, env_c4v)
            obs["SzSzSzSz"] = torch.einsum('ijklabcd,ijklabcd', rdm2x2,
                                           self.szszszsz)

        # prepare list with labels and values
        obs_labels = [lc for lc in ["sz", "sx"]]
        obs_labels += ["SzSzSzSz"]
        obs_values = [obs[label] for label in obs_labels]
        return obs_values, obs_labels
Beispiel #4
0
    def energy_1x1(self, state, env_c4v, **kwargs):
        r"""
        :param state: wavefunction
        :param env_c4v: CTM c4v symmetric environment
        :type state: IPEPS
        :type env_c4v: ENV_C4V
        :return: energy per site
        :rtype: float

        We assume 1x1 C4v iPEPS which tiles the lattice with a bipartite pattern composed 
        of two tensors A, and B=RA, where R rotates approriately the physical Hilbert space 
        of tensor A on every "odd" site::

            1x1 C4v => rotation P => BIPARTITE

            A A A A                  A B A B
            A A A A                  B A B A
            A A A A                  A B A B
            A A A A                  B A B A

        Due to C4v symmetry it is enough to construct a single reduced density matrix 
        :py:func:`ctm.one_site_c4v.rdm_c4v.rdm2x2` of a 2x2 plaquette. Afterwards, 
        the energy per site `e` is computed by evaluating a single plaquette term :math:`h_p`
        containing two nearest-nighbour terms :math:`\bf{S}.\bf{S}` and two next-nearest 
        neighbour :math:`\bf{S}.\bf{S}`, as:

        .. math::

            e = \langle \mathcal{h_p} \rangle = Tr(\rho_{2x2} \mathcal{h_p})
        
        """
        rdm2x2= rdm_c4v.rdm2x2(state,env_c4v,sym_pos_def=True,\
            verbosity=cfg.ctm_args.verbosity_rdm)
        energy_per_site = torch.einsum('ijklabcd,ijklabcd', rdm2x2, self.hp)
        if abs(self.j3) > 0:
            rdm3x1= rdm_c4v.rdm3x1(state,env_c4v,sym_pos_def=True,\
                force_cpu=False,verbosity=cfg.ctm_args.verbosity_rdm)
            ss_3x1 = torch.einsum('ijab,ijab', rdm3x1, self.SS)
            energy_per_site = energy_per_site + 2 * self.j3 * ss_3x1

        energy_per_site = _cast_to_real(energy_per_site)
        return energy_per_site
Beispiel #5
0
    def energy_1x1(self, state, env_c4v, **kwargs):
        r"""
        :param state: wavefunction
        :param env_c4v: CTM c4v symmetric environment
        :type state: IPEPS
        :type env_c4v: ENV_C4V
        :return: energy per site
        :rtype: float

        We assume 1x1 C4v iPEPS which tiles the lattice with a bipartite pattern composed 
        of two tensors A, and B=RA, where R rotates approriately the physical Hilbert space 
        of tensor A on every "odd" site::

            1x1 C4v => rotation P => BIPARTITE

            A A A A                  A B A B
            A A A A                  B A B A
            A A A A                  A B A B
            A A A A                  B A B A

        Due to C4v symmetry it is enough to construct a single reduced density matrix 
        :py:func:`ctm.one_site_c4v.rdm_c4v.rdm2x2` of a 2x2 plaquette. Afterwards, 
        the energy per site `e` is computed by evaluating a single plaquette term :math:`h_p`
        containing two nearest-nighbour terms :math:`\bf{S}.\bf{S}` and two next-nearest 
        neighbour :math:`\bf{S}.\bf{S}`, as:

        .. math::

            e = \langle \mathcal{h_p} \rangle = Tr(\rho_{2x2} \mathcal{h_p})
        
        """
        rdm2x2 = rdm_c4v.rdm2x2(state, env_c4v, cfg.ctm_args.verbosity_rdm)
        energy_per_site = torch.einsum('ijklabcd,ijklabcd', rdm2x2, self.hp)
        # id2= torch.eye(4,dtype=self.dtype,device=self.device)
        # id2= id2.view(2,2,2,2).contiguous()
        # print(f"rdm2x1 {torch.einsum('ijklabcd,ijab,klcd',rdm2x2,self.h2_rot,id2)}"\
        #    + f" rdm1x2 {torch.einsum('ijklabcd,ikac,jlbd',rdm2x2,self.h2_rot,id2)}"\
        #    + f" rdm_0cc3_diag {torch.einsum('ijklabcd,ilad,jkbc',rdm2x2,self.h2,id2)}"\
        #    + f" rdm_c12c_diag {torch.einsum('ijklabcd,jkbc,ilad',rdm2x2,self.h2,id2)}")
        return energy_per_site