def test_alpha_beta_electrons(self): """Check to make sure that the correct number of alpha and beta electrons are parsed from the number and multiplicity """ self.assertTupleEqual((1, 1), util.alpha_beta_electrons(2, 0)) self.assertTupleEqual((4, 1), util.alpha_beta_electrons(5, 3)) self.assertTupleEqual((0, 5), util.alpha_beta_electrons(5, -5))
def __init__(self, maxparticle: int, maxspin: int, params: List[List[int]] = None) -> None: """ params are the same as Wavefunction. Args: maxparticle (int) - the maximum particle number difference up to which \ the sectors are to be linked maxspin (int) - the maximum spin number difference up to which the \ sectors are to be linked params (List[List[int]]) - a list of parameter lists. The parameter \ lists are comprised of p[0] (int) - number of particles; p[1] (int) - z component of spin angular momentum; p[2] (int) - number of spatial orbitals """ self._dataset: Dict[Tuple[int, int], 'FciGraph'] = {} self._maxparticle = maxparticle self._maxspin = maxspin self._linked: Set[Tuple[Tuple[int, int], Tuple[int, int]]] = set() if params is not None: for param in params: assert len(param) == 3 nalpha, nbeta = alpha_beta_electrons(param[0], param[1]) self._dataset[(nalpha, nbeta)] = FciGraph(nalpha, nbeta, param[2]) self.link()
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 fci_fermion_operator_representation(norb: int, nele: int, m_s: int) -> 'FermionOperator': """Generate the Full Configuration interaction wavefunction in the openfermion FermionOperator representation with coefficients of 1.0. Args: norb (int) - number of spatial orbitals nele (int) - number of electrons m_s (int) - s_z spin quantum number Returns: FermionOperator """ nalpha, nbeta = alpha_beta_electrons(nele, m_s) gsstr = init_bitstring_groundstate(nalpha) alphadets = lexicographic_bitstring_generator(gsstr, norb) gsstr = init_bitstring_groundstate(nbeta) betadets = lexicographic_bitstring_generator(gsstr, norb) ops = FermionOperator('', 1.0) for bstr in betadets: for astr in alphadets: ops += determinant_to_ops(astr, bstr) return ops - FermionOperator('', 1.0)
def __init__(self, param: Optional[List[List[int]]] = None, broken: Optional[Union[List[str], str]] = None) -> None: """ Args: param (list[list[n, ms, norb]]) - the constructor accepts a list of \ parameter lists. The parameter lists are comprised of p[0] (integer) - number of particles; p[1] (integer) - z component of spin angular momentum; p[2] (integer) - number of spatial orbitals broken (str) - pass in the symmetries that should be preserved by \ the wavefunction. Member Variables: _conserve_spin (Bool) - When this flag is true, the wavefunction \ will maintain a constant m_s _conserve_number (Bool) - When this flag is true, the wavefunction \ will maintain a constant nele _civec (dict[(int, int)] -> FqeData) - This is a dictionary for \ FqeData objects. The key is a tuple defined by the number of \ electrons and the spin projection of the system. """ self._symmetry_map: Dict[Tuple[int, int], Tuple[int, int]] = {} self._conserved: Dict[str, int] = {} self._conserve_spin: bool = False if broken is None or 'spin' not in broken: self._conserve_spin = True self._conserve_number: bool = False if broken is None or 'number' not in broken: self._conserve_number = True self._norb: int = 0 self._civec: Dict[Tuple[int, int], 'FqeData'] = {} if not self._conserve_spin and not self._conserve_number: raise TypeError('Number and spin non-conserving waveunfction is' \ ' the complete Fock space.') if param: user_input_norbs = set([x[2] for x in param]) if len(user_input_norbs) != 1: raise ValueError('Number of orbitals is not consistent') self._norb = list(user_input_norbs)[0] for i in param: nalpha, nbeta = alpha_beta_electrons(i[0], i[1]) self._civec[(i[0], i[1])] = FqeData(nalpha, nbeta, self._norb) if self._conserve_number: self._conserved['n'] = param[0][0] if self._conserve_spin: self._conserved['s_z'] = param[0][1] if not self._conserve_number: self._symmetry_map = map_broken_symmetry( param[0][1], param[0][2])