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
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
def energy_1x1(self,state,env_c4v): rdm2x1 = rdm_c4v.rdm2x1(state, env_c4v) energy = torch.einsum('ijab,ijab',rdm2x1,self.h2_rot) return energy