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
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
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
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
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