def rdm( self, string: str, brawfn: Optional['Wavefunction'] = None ) -> Union[complex, numpy.ndarray]: """ Returns rank-1 RDM. The operator order is specified by string. Note that, if the entire RDM is requested for N-broken wave function, this returns a packed format. Args: string (str) - character strings that specify the quantity to be computed brawfn (Wavefunction) - bra-side wave function for transition RDM (optional) Returns: Resulting RDM in numpy.ndarray or element in complex """ rank = len(string.split()) // 2 if any(char.isdigit() for char in string): result = self.apply(sparse_hamiltonian.SparseHamiltonian(string)) if brawfn is None: return vdot(self, result) return vdot(brawfn, result) fqe_ops_utils.validate_rdm_string(string) rdm = list(self._compute_rdm(rank, brawfn)) return wick(string, rdm, self._conserve_spin)
def expectationValue( self, ops: Union['fqe_operator.FqeOperator', 'hamiltonian.Hamiltonian'], brawfn: 'Wavefunction' = None) -> Union[complex, numpy.ndarray]: """Calculates expectation values given operators Args: ops (FqeOperator or Hamiltonian) - operator for which the expectation value is \ computed brawfn (Wavefunction) - bra-side wave function for transition quantity (optional) Returns: (complex or numpy.ndarray) - resulting expectation value or RDM """ if isinstance(ops, fqe_operator.FqeOperator): if brawfn: return ops.contract(brawfn, self) return ops.contract(self, self) if isinstance(ops, str): if any(char.isdigit() for char in ops): ops = sparse_hamiltonian.SparseHamiltonian(ops) else: return self.rdm(ops, brawfn=brawfn) if not isinstance(ops, hamiltonian.Hamiltonian): raise TypeError('Expected an Fqe Hamiltonian or Operator' \ ' but recieved {}'.format(type(ops))) workwfn = self.apply(ops) if brawfn: return vdot(brawfn, workwfn) return vdot(self, workwfn)
def contract(self, brastate: "Wavefunction", ketstate: "Wavefunction") -> complex: """Given two wavefunctions, generate the expectation value of the operator according to its representation. Args: brastate: Wavefunction on the bra side. ketstate: Wavefunction on the ket side. """ out = copy.deepcopy(ketstate) for (nele, nab), sector in out._civec.items(): nalpha, nbeta = alpha_beta_electrons(nele, nab) if nalpha < nbeta: if not (nele, nbeta - nalpha) in out._civec.keys(): raise ValueError( "The wavefunction space is not closed under " "time reversal.") sector2 = out._civec[(nele, nbeta - nalpha)] tmp = np.copy(sector.coeff) phase = (-1)**(nbeta * (nalpha + 1)) phase2 = (-1)**(nalpha * (nbeta + 1)) sector.coeff = sector2.coeff.T.conj() * phase2 sector2.coeff = tmp.T.conj() * phase elif nalpha > nbeta: if not (nele, nbeta - nalpha) in out._civec.keys(): raise ValueError( "The wavefunction space is not closed under " "time reversal.") elif nalpha == nbeta: sector.coeff = sector.coeff.T.conj() return vdot(brastate, out)
def contract(self, brastate: "Wavefunction", ketstate: "Wavefunction") -> complex: """Given two wavefunctions, generate the expectation value of the operator according to its representation. Args: brastate: Wavefunction on the bra side. ketstate: Wavefunction on the ket side. """ out = copy.deepcopy(ketstate) for _, sector in out._civec.items(): sector.scale((sector.nalpha() - sector.nbeta()) * 0.5) return vdot(brastate, out)
def vdot(wfn1: 'wavefunction.Wavefunction', wfn2: 'wavefunction.Wavefunction') -> complex: """Calculate the inner product of two wavefunctions using conjugation on the elements of wfn1. Args: wfn1 (wavefunction.Wavefunction) - wavefunction corresponding to the \ conjugate row vector wfn2 (wavefunction.Wavefunction) - wavefunction corresponding to the \ coumn vector Returns: (complex) - scalar as result of the dot product """ return util.vdot(wfn1, wfn2)