def _compute_mp2(qmolecule, threshold): terms = {} mp2_delta = 0 num_particles = qmolecule.num_alpha + qmolecule.num_beta num_orbitals = qmolecule.num_orbitals ints = qmolecule.mo_eri_ints oe = qmolecule.orbital_energies # Orbital indexes given by this method are numbered according to the blocked spin ordering singles, doubles = UCCSD.compute_excitation_lists(num_particles, num_orbitals * 2, same_spin_doubles=True) # doubles is list of [from, to, from, to] in spin orbital indexing where alpha runs # from 0 to num_orbitals-1, and beta from num_orbitals to num_orbitals*2-1 for n in range(len(doubles)): idxs = doubles[n] i = idxs[0] % num_orbitals # Since spins are same drop to MO indexing j = idxs[2] % num_orbitals a = idxs[1] % num_orbitals b = idxs[3] % num_orbitals tiajb = ints[i, a, j, b] tibja = ints[i, b, j, a] num = (2 * tiajb - tibja) denom = oe[b] + oe[a] - oe[i] - oe[j] coeff = -num / denom coeff = coeff if abs(coeff) > threshold else 0 e_delta = coeff * tiajb e_delta = e_delta if abs(e_delta) > threshold else 0 terms[_list_to_str(idxs)] = (coeff, e_delta) mp2_delta += e_delta return terms, mp2_delta
def __init__(self, operator, num_orbitals, num_particles, qubit_mapping=None, two_qubit_reduction=False, active_occupied=None, active_unoccupied=None, is_eom_matrix_symmetric=True, se_list=None, de_list=None, z2_symmetries=None, untapered_op=None): """Constructor. Args: operator (WeightedPauliOperator): qubit operator num_orbitals (int): total number of spin orbitals num_particles (Union(list, int)): number of particles, if it is a list, the first number is alpha and the second number if beta. qubit_mapping (str): qubit mapping type two_qubit_reduction (bool): two qubit reduction is applied or not active_occupied (list): list of occupied orbitals to include, indices are 0 to n where n is num particles // 2 active_unoccupied (list): list of unoccupied orbitals to include, indices are 0 to m where m is (num_orbitals - num particles) // 2 is_eom_matrix_symmetric (bool): is EoM matrix symmetric se_list (list[list]): single excitation list, overwrite the setting in active space de_list (list[list]): double excitation list, overwrite the setting in active space z2_symmetries (Z2Symmetries): represent the Z2 symmetries untapered_op (WeightedPauliOperator): if the operator is tapered, we need untapered operator to build element of EoM matrix """ self._operator = operator self._num_orbitals = num_orbitals self._num_particles = num_particles self._qubit_mapping = qubit_mapping self._two_qubit_reduction = two_qubit_reduction self._active_occupied = active_occupied self._active_unoccupied = active_unoccupied se_list_default, de_list_default = UCCSD.compute_excitation_lists( self._num_particles, self._num_orbitals, self._active_occupied, self._active_unoccupied) if se_list is None: self._se_list = se_list_default else: self._se_list = se_list logger.info("Use user-specified single excitation list: %s", self._se_list) if de_list is None: self._de_list = de_list_default else: self._de_list = de_list logger.info("Use user-specified double excitation list: %s", self._de_list) self._z2_symmetries = z2_symmetries if z2_symmetries is not None \ else Z2Symmetries([], [], []) self._untapered_op = untapered_op if untapered_op is not None else operator self._is_eom_matrix_symmetric = is_eom_matrix_symmetric