def _transl2fermi(self, tensor: Tensor): """Translate a tensor object in terms of the fermion operators. This is an internally utility. The resulted tensor has the internal fermion drudge object as its owner. """ return Tensor(self._ph_dr, tensor.subst_all(self._defs).terms)
def eval_vev(self, tensor: Tensor): r"""Evaluate the vacuum expectation value. The VEV facility works *as if* we do substitution .. math:: P_p &= c_{p \downarrow} c_{p \uparrow} \\ P^\dag_p &= c^\dag_{p \uparrow} c^\dag_{p \downarrow} \\ N_p &= c^\dag_{p \uparrow} c_{p \uparrow} + c^\dag_{p \downarrow} c_{p \downarrow} \\ for :math:`p` in either particle or hole range and evaluate the expectation value with respect to the Fermi vacuum. """ transled = self._transl2fermi(tensor) res = self._ph_dr.eval_fermi_vev(transled) return Tensor(self, res.terms)
def eval_agp(self, tensor: Tensor, zlist): r"""Evaluate the vacuum expectation value. The AGP expectation value facility works *as if* we do substitution Takes as input the list of z matrices .. math:: \langle P^\dag_p P_q \rangle &= A^{(0)}_{pq} \\ \langle P^\dag_p N_r P_q \rangle &= A^{(1)}_{pqr} \\ \langle P^\dag_p P^\dag_q P_rP_s\rangle &= A^{(0)}_{pqrs} \\ """ num_ = self.cartan pdag_ = self.raise_ p_ = self.lower def get_vev_of_term(term): """Return the vev mapping of the term""" vecs = term.vecs t_amp = term.amp pdag_cnt = 0 p_cnt = 0 n_cnt = 0 pdag_indlist = [] p_indlist = [] n_indlist = [] if len(vecs) == 0: return [ Term(sums=term.sums, amp=t_amp * zlist[0][0], vecs=vecs) ] # Classify the indices into pdag, n, and p indicies for i in vecs: if i.base == pdag_: pdag_indlist.extend(list(i.indices)) elif i.base == p_: p_indlist.extend(list(i.indices)) elif i.base == num_: n_indlist.extend(list(i.indices)) else: return [] # Count the number of indices pdag_cnt = len(pdag_indlist) p_cnt = len(p_indlist) # First, we extract only the unique N indices unique_n_indlist = list(set(n_indlist)) n_cnt = len(unique_n_indlist) # Introduce appropriate power of 2 in amplitude to include the effect # of unique indices only being considered in N ldiff = len(n_indlist) - len(unique_n_indlist) t_amp *= 2**(ldiff) if pdag_cnt != p_cnt: # The expression must have equal number of Pdag's and P_'s return [] elif len(pdag_indlist) != len(set(pdag_indlist)): return [] elif len(p_indlist) != len(set(p_indlist)): return [] else: # Combining all the indices indcs = pdag_indlist indcs.extend(unique_n_indlist) indcs.extend(p_indlist) # Counting the different number of indices in order # to select the right symbol 'asymb' idx1 = int(n_cnt) idx_ppdag = len(indcs) - n_cnt idx2 = int((idx_ppdag / 2)) asymb = zlist[idx1][idx2] t_amp = t_amp * asymb[indcs] return [Term(sums=term.sums, amp=t_amp, vecs=())] return tensor.bind(get_vev_of_term)
def eval_agp(self, tensor: Tensor, zlist): r"""Evaluate the vacuum expectation value. The AGP expectation value facility works *as if* we do substitution Takes as input the list of z matrices .. math:: \langle P^\dag_p P_q \rangle &= A^{(0)}_{pq} \\ \langle P^\dag_p N_r P_q \rangle &= A^{(1)}_{pqr} \\ \langle P^\dag_p P^\dag_q P_rP_s\rangle &= A^{(0)}_{pqrs} \\ """ num_ = self.cartan pdag_ = self.raise_ p_ = self.lower def get_vev_of_term(term): """Return the vev mapping of the term""" vecs = term.vecs t_amp = term.amp pdag_cnt = 0 p_cnt = 0 n_cnt = 0 pdag_indlist = [] p_indlist = [] n_indlist = [] if len(vecs) == 0: return [Term(sums=term.sums, amp=t_amp, vecs=vecs)] for i in vecs: if i.base == pdag_: pdag_cnt += 1 pdag_indlist.extend(list(i.indices)) elif i.base == p_: p_cnt += 1 p_indlist.extend(list(i.indices)) elif i.base == num_: n_cnt += 1 n_indlist.extend(list(i.indices)) else: return [] if pdag_cnt != p_cnt: # The expression must have equal number of Pdag's and P_'s return [] elif len(pdag_indlist) != len(set(pdag_indlist)): return [] elif len(p_indlist) != len(set(p_indlist)): return [] else: # Combining all the indices indcs = pdag_indlist indcs.extend(n_indlist) indcs.extend(p_indlist) # Counting the different number of indices in order # to select the right symbol 'asymb' idx1 = int(n_cnt) idx_ppdag = len(indcs) - n_cnt idx2 = int((idx_ppdag / 2)) asymb = zlist[idx1][idx2] t_amp = t_amp * asymb[indcs] return [Term(sums=term.sums, amp=t_amp, vecs=())] return tensor.bind(get_vev_of_term)
def eval_awev (self, tensor: Tensor): terms = self._eval_awev (tensor) return Tensor (self, terms)