def absorb_lm(self, nt, if_sqrt, which_vb): # which_vb does NOT count physical bond tensor = self.tensors[nt].copy() if if_sqrt: if which_vb is 'all': tensor = tm.absorb_matrices2tensor(tensor, [ np.diag(np.sqrt(self.lm[self.pos_lm[nt][n]])) for n in range(0, self.nVirtual) ], [n + 1 for n in range(0, self.nVirtual)]) elif type(which_vb) is int: tensor = tm.absorb_matrix2tensor( tensor, np.diag(np.sqrt(self.lm[self.pos_lm[nt][which_vb]])), which_vb + 1) else: tensor = tm.absorb_matrices2tensor(tensor, [ np.diag(np.sqrt(self.lm[self.pos_lm[nt][n]])) for n in which_vb ], [n + 1 for n in which_vb]) else: if which_vb is 'all': tensor = tm.absorb_matrices2tensor(tensor, [ np.diag(self.lm[self.pos_lm[nt][n]]) for n in range(0, self.nVirtual) ], [n + 1 for n in range(0, self.nVirtual)]) elif type(which_vb) is int: tensor = tm.absorb_matrix2tensor( tensor, np.diag(self.lm[self.pos_lm[nt][which_vb]]), which_vb + 1) else: tensor = tm.absorb_matrices2tensor( tensor, [np.diag(self.lm[self.pos_lm[nt][n]]) for n in which_vb], [n + 1 for n in which_vb]) return tensor
def one_bond_so_transformation(self, nt1, vb1, nt2, vb2): # Super-orthogonal transformation on one virtual bond # vb does NOT count the physical bond if self._is_debug: if self.pos_lm[nt1][vb1] != self.pos_lm[nt2][vb2]: bf.print_error( 'In one_bond_so_transformation, the two virtual bonds must' 'correspond to the same lambda') m1 = self.bond_env_matrix_simple(nt1, vb1) m2 = self.bond_env_matrix_simple(nt2, vb2) flag = False if self._is_debug: _lm = self.lm[self.pos_lm[nt1][vb1]].copy() flag = (self.chi == self.tensors[nt1].shape[vb1 + 1]) u1, u2, self.lm[self.pos_lm[nt1] [vb1]] = tm.transformation_from_env_mats( m1, m2, self.lm[self.pos_lm[nt1][vb1]], self.chi, norm_way=1)[:3] if self._is_debug and flag: _tmp = u1.dot(np.diag(self.lm[self.pos_lm[nt1][vb1]])).dot(u2.T) err = np.linalg.norm(tm.off_diagonal_mat(_tmp).reshape(-1, )) if err > 1e-10: print( 'Warning of the transformations from environment: not diagonal (%g)' % err) _tmp = np.diag(_tmp) _tmp = _tmp / np.linalg.norm(_tmp) err = np.linalg.norm(_tmp - self.lm[self.pos_lm[nt1][vb1]]) if err > 1e-10: print( 'Warning of the transformations from environment: not recover lm (%g)' % err) print(self.lm[self.pos_lm[nt1][vb1]]) self.tensors[nt1] = tm.absorb_matrix2tensor(self.tensors[nt1], u1, vb1 + 1) self.tensors[nt2] = tm.absorb_matrix2tensor(self.tensors[nt2], u2, vb2 + 1) self.tensors[nt1] /= max(abs(self.tensors[nt1].reshape(-1, 1))) self.tensors[nt2] /= max(abs(self.tensors[nt2].reshape(-1, 1))) # self.lm[self.pos_lm[nt1][vb1]] = tm.normalize_tensor(self.lm[self.pos_lm[nt1][vb1]])[0] return m1, m2