def test_uccsd_excitations(self, expected_result_idx, num_orbitals, num_particles,
                               active_occupied=None, active_unoccupied=None,
                               same_spin_doubles=True,
                               method_singles='both', method_doubles='ucc',
                               excitation_type='sd'
                               ):
        """ Test generated excitation lists in conjunction with active space """

        excitations = UCCSD.compute_excitation_lists(
            num_orbitals=num_orbitals, num_particles=num_particles,
            active_occ_list=active_occupied, active_unocc_list=active_unoccupied,
            same_spin_doubles=same_spin_doubles,
            method_singles=method_singles, method_doubles=method_doubles,
            excitation_type=excitation_type)

        self.assertListEqual(list(excitations), self.EXCITATION_RESULTS[expected_result_idx])
Example #2
0
def _compute_mp2(qmolecule, threshold):
    terms = {}
    mp2_delta = 0

    num_orbitals = qmolecule.num_orbitals
    ints = qmolecule.mo_eri_ints
    o_e = qmolecule.orbital_energies

    # Orbital indexes given by this method are numbered according to the blocked spin ordering
    _, doubles = UCCSD.compute_excitation_lists(
        [qmolecule.num_alpha, qmolecule.num_beta],
        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 enumerate(doubles):
        idxs = doubles[n]
        i = idxs[0] % num_orbitals  # Since spins are same drop to MO indexing
        j = idxs[2] % num_orbitals
        a_i = idxs[1] % num_orbitals
        b = idxs[3] % num_orbitals

        tiajb = ints[i, a_i, j, b]
        tibja = ints[i, b, j, a_i]

        num = (2 * tiajb - tibja)
        denom = o_e[b] + o_e[a_i] - o_e[i] - o_e[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
Example #3
0
    def build_hopping_operators(
        self,
        excitations: Union[str, List[List[int]]] = 'sd'
    ) -> Tuple[Dict[str, PauliSumOp], Dict[str, List[bool]], Dict[str,
                                                                  List[Any]]]:
        """Builds the product of raising and lowering operators (basic excitation operators)

        Args:
            excitations: The excitations to be included in the eom pseudo-eigenvalue problem.
                If a string ('s', 'd' or 'sd') then all excitations of the given type will be used.
                Otherwise a list of custom excitations can directly be provided.

        Returns:
            A tuple containing the hopping operators, the types of commutativities and the
            excitation indices.
        """

        num_alpha, num_beta = self._molecule_info['num_particles']
        num_orbitals = self._molecule_info['num_orbitals']

        if isinstance(excitations, str):
            se_list, de_list = UCCSD.compute_excitation_lists(
                [num_alpha, num_beta],
                num_orbitals,
                excitation_type=excitations)
            excitations_list = se_list + de_list
        else:
            excitations_list = excitations

        size = len(excitations_list)

        # # get all to-be-processed index
        # mus, nus = np.triu_indices(size)

        # build all hopping operators
        hopping_operators: Dict[str, PauliSumOp] = {}
        type_of_commutativities: Dict[str, List[bool]] = {}
        excitation_indices = {}
        to_be_executed_list = []
        for idx in range(size):
            to_be_executed_list += [
                excitations_list[idx],
                list(reversed(excitations_list[idx]))
            ]
            hopping_operators['E_{}'.format(idx)] = None
            hopping_operators['Edag_{}'.format(idx)] = None
            type_of_commutativities['E_{}'.format(idx)] = None
            type_of_commutativities['Edag_{}'.format(idx)] = None
            excitation_indices['E_{}'.format(idx)] = excitations_list[idx]
            excitation_indices['Edag_{}'.format(idx)] = list(
                reversed(excitations_list[idx]))

        result = parallel_map(self._build_single_hopping_operator,
                              to_be_executed_list,
                              task_args=(num_alpha + num_beta, num_orbitals,
                                         self._qubit_mapping,
                                         self._two_qubit_reduction,
                                         self._molecule_info['z2_symmetries']),
                              num_processes=algorithm_globals.num_processes)

        for key, res in zip(hopping_operators.keys(), result):
            hopping_operators[key] = res[0]
            type_of_commutativities[key] = res[1]

        return hopping_operators, type_of_commutativities, excitation_indices