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

        For 1-site invariant c4v iPEPS it's enough to construct a 1-site reduced
        density matrix :py:func:`ctm.one_site_c4v.rdm_c4v.rdm1x1`, effectively 
        representing a 2x2 plaquette, and 2-site reduced
        density matrix :py:func:`ctm.one_site_c4v.rdm_c4v.rdm2x1` which represents 
        interaction between two plaquettes of the underlying physical system:
        
        .. math:: 

            e = \langle h1 \rangle_{\rho_{1x1}} + \langle h2 \rangle_{\rho_{2x1}}

        """
        rdm1x1 = rdm_c4v.rdm1x1(state, env)
        rdm2x1 = rdm_c4v.rdm2x1(state, env)
        e1s = torch.einsum('ij,ij', rdm1x1, self.h1)
        e2s = torch.einsum('ijab,ijab', rdm2x1, self.h2)
        energy_per_site = (e1s + e2s) / 4
        return energy_per_site
コード例 #2
0
ファイル: ising.py プロジェクト: tateobori/AD-peps
    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
コード例 #3
0
ファイル: j1j2.py プロジェクト: jurajHasik/peps-torch
    def eval_corrf_SS(self, state, env_c4v, dist, canonical=False):
        Sop_zxy = torch.zeros((3, self.phys_dim, self.phys_dim),
                              dtype=self.dtype,
                              device=self.device)
        Sop_zxy[0, :, :] = self.obs_ops["sz"]
        Sop_zxy[1, :, :] = 0.5 * (self.obs_ops["sp"] + self.obs_ops["sm"])
        Sop_zxy[2, :, :] = -0.5 * (self.obs_ops["sp"] - self.obs_ops["sm"])

        # compute vector of spontaneous magnetization
        if canonical:
            s_vec_zpm = []
            rdm1x1 = rdm_c4v.rdm1x1(state, env_c4v)
            for label in ["sz", "sp", "sm"]:
                op = self.obs_ops[label]
                s_vec_zpm.append(torch.trace(rdm1x1 @ op))
            # 0) transform into zxy basis and normalize
            s_vec_zxy= torch.tensor([s_vec_zpm[0],0.5*(s_vec_zpm[1]+s_vec_zpm[2]),\
                0.5*(s_vec_zpm[1]-s_vec_zpm[2])],dtype=self.dtype,device=self.device)
            s_vec_zxy = s_vec_zxy / torch.norm(s_vec_zxy)
            # 1) build rotation matrix
            R= torch.tensor([[s_vec_zxy[0],-s_vec_zxy[1],0],[s_vec_zxy[1],s_vec_zxy[0],0],[0,0,1]],\
                dtype=self.dtype,device=self.device).t()
            # 2) rotate the vector of operators
            Sop_zxy = torch.einsum('ab,bij->aij', R, Sop_zxy)

        # function generating properly rotated operators on every bi-partite site
        def get_bilat_op(op):
            rot_op = su2.get_rot_op(self.phys_dim,
                                    dtype=self.dtype,
                                    device=self.device)
            op_0 = op
            op_rot = torch.einsum('ki,kl,lj->ij', rot_op, op_0, rot_op)

            def _gen_op(r):
                return op_rot if r % 2 == 0 else op_0

            return _gen_op

        Sz0szR= corrf_c4v.corrf_1sO1sO(state, env_c4v, Sop_zxy[0,:,:], \
            get_bilat_op(Sop_zxy[0,:,:]), dist)
        Sx0sxR = corrf_c4v.corrf_1sO1sO(state, env_c4v, Sop_zxy[1, :, :],
                                        get_bilat_op(Sop_zxy[1, :, :]), dist)
        nSy0SyR = corrf_c4v.corrf_1sO1sO(state, env_c4v, Sop_zxy[2, :, :],
                                         get_bilat_op(Sop_zxy[2, :, :]), dist)

        res = dict({
            "ss": Sz0szR + Sx0sxR - nSy0SyR,
            "szsz": Sz0szR,
            "sxsx": Sx0sxR,
            "sysy": -nSy0SyR
        })
        return res
コード例 #4
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. magnetization
            2. :math:`\langle S^z \rangle,\ \langle S^+ \rangle,\ \langle S^- \rangle`

        where the on-site magnetization is defined as
        
        .. math::
            
            \begin{align*}
            m &= \sqrt{ \langle S^z \rangle^2+\langle S^x \rangle^2+\langle S^y \rangle^2 }
            =\sqrt{\langle S^z \rangle^2+1/4(\langle S^+ \rangle+\langle S^- 
            \rangle)^2 -1/4(\langle S^+\rangle-\langle S^-\rangle)^2} \\
              &=\sqrt{\langle S^z \rangle^2 + 1/2\langle S^+ \rangle \langle S^- \rangle)}
            \end{align*}

        Usual spin components can be obtained through the following relations
        
        .. math::
            
            \begin{align*}
            S^+ &=S^x+iS^y               & S^x &= 1/2(S^+ + S^-)\\
            S^- &=S^x-iS^y\ \Rightarrow\ & S^y &=-i/2(S^+ - S^-)
            \end{align*}
        """
        # TODO optimize/unify ?
        # expect "list" of (observable label, value) pairs ?
        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[f"m"] = sqrt(abs(obs[f"sz"]**2 + obs[f"sp"] * obs[f"sm"]))

            rdm2x1 = rdm_c4v.rdm2x1(state, env_c4v)
            obs[f"SS2x1"] = torch.einsum('ijab,ijab', rdm2x1, self.h2_rot)

        # prepare list with labels and values
        obs_labels = [f"m"] + [f"{lc}"
                               for lc in self.obs_ops.keys()] + [f"SS2x1"]
        obs_values = [obs[label] for label in obs_labels]
        return obs_values, obs_labels
コード例 #5
0
    def eval_obs(self, state, env):
        r"""
        :param state: wavefunction
        :param env_c4v: CTM c4v symmetric environment
        :type state: IPEPS
        :type env: ENV_C4V
        :return:  expectation values of observables, labels of observables
        :rtype: list[float], list[str]

        Computes the following observables in order

            1. average magnetization over the unit cell,
            2. magnetization for each site in the unit cell
            3. :math:`\langle S^z \rangle,\ \langle S^+ \rangle,\ \langle S^- \rangle` 
               for each site in the unit cell

        where the on-site magnetization is defined as
        
        .. math::
            
            \begin{align*}
            m &= \sqrt{ \langle S^z \rangle^2+\langle S^x \rangle^2+\langle S^y \rangle^2 }
            =\sqrt{\langle S^z \rangle^2+1/4(\langle S^+ \rangle+\langle S^- 
            \rangle)^2 -1/4(\langle S^+\rangle-\langle S^-\rangle)^2} \\
              &=\sqrt{\langle S^z \rangle^2 + 1/2\langle S^+ \rangle \langle S^- \rangle)}
            \end{align*}

        Usual spin components can be obtained through the following relations
        
        .. math::
            
            \begin{align*}
            S^+ &=S^x+iS^y               & S^x &= 1/2(S^+ + S^-)\\
            S^- &=S^x-iS^y\ \Rightarrow\ & S^y &=-i/2(S^+ - S^-)
            \end{align*}
        """
        # TODO optimize/unify ?
        # expect "list" of (observable label, value) pairs ?
        obs = dict({"avg_m": 0.})
        with torch.no_grad():
            rdm1x1 = rdm_c4v.rdm1x1(state, env)
            rdm1x1 = rdm1x1.view(2, 2, 2, 2, 2, 2, 2, 2)
            expr_core = 'abc'
            for r in range(4):
                expr = expr_core[:r] + 'i' + expr_core[
                    r:] + expr_core[:r] + 'j' + expr_core[r:] + ',ij'
                for label, op in self.obs_ops.items():
                    obs[f"{label}{r}"] = torch.einsum(expr, rdm1x1, op)
                obs[f"m{r}"] = sqrt(
                    abs(obs[f"sz{r}"]**2 + obs[f"sp{r}"] * obs[f"sm{r}"]))
                obs["avg_m"] += obs[f"m{r}"]
            obs["avg_m"] = obs["avg_m"] / 4

            # for coord,site in state.sites.items():
            #     rdm2x1 = rdm_c4v.rdm2x1(coord,state,env)
            #     rdm1x2 = rdm.rdm1x2(coord,state,env)
            #     obs[f"SS2x1{coord}"]= torch.einsum('ijab,ijab',rdm2x1,self.h2)
            #     obs[f"SS1x2{coord}"]= torch.einsum('ijab,ijab',rdm1x2,self.h2)

        # prepare list with labels and values
        obs_labels=["avg_m"]+[f"m{r}" for r in range(4)]\
            +[f"{lc[1]}{lc[0]}" for lc in list(itertools.product(range(4), self.obs_ops.keys()))]
        # obs_labels += [f"SS2x1{coord}" for coord in state.sites.keys()]
        # obs_labels += [f"SS1x2{coord}" for coord in state.sites.keys()]
        obs_values = [obs[label] for label in obs_labels]
        return obs_values, obs_labels