Exemplo n.º 1
0
 def test_uccsd_adapt(self):
     """ UCCSD test for adaptive features """
     self.var_form_base = UCCSD(self.num_spin_orbitals,
                                self.num_particles,
                                initial_state=self.init_state)
     self.var_form_base.manage_hopping_operators()
     # assert that the excitation pool exists
     self.assertIsNotNone(self.var_form_base.excitation_pool)
     # assert that the hopping ops list has been reset to be empty
     self.assertEqual(self.var_form_base._hopping_ops, [])
Exemplo n.º 2
0
    def test_uccsd_hf_excitations(self):
        """ uccsd tapering test using all double excitations """

        # initial state
        init_state = HartreeFock(
            num_orbitals=self.fermionic_transformation.molecule_info['num_orbitals'],
            qubit_mapping=self.fermionic_transformation._qubit_mapping,
            two_qubit_reduction=self.fermionic_transformation._two_qubit_reduction,
            num_particles=self.fermionic_transformation.molecule_info['num_particles'],
            sq_list=self.fermionic_transformation.molecule_info['z2_symmetries'].sq_list)

        # check singlet excitations
        var_form = UCCSD(
            num_orbitals=self.fermionic_transformation.molecule_info['num_orbitals'],
            num_particles=self.fermionic_transformation.molecule_info['num_particles'],
            active_occupied=None, active_unoccupied=None,
            initial_state=init_state,
            qubit_mapping=self.fermionic_transformation._qubit_mapping,
            two_qubit_reduction=self.fermionic_transformation._two_qubit_reduction,
            num_time_slices=1,
            z2_symmetries=self.fermionic_transformation.molecule_info['z2_symmetries'],
            shallow_circuit_concat=False,
            method_doubles='succ',
            excitation_type='d',
            skip_commute_test=True)

        double_excitations_singlet = var_form._double_excitations
        res = TestUCCSDHartreeFock.excitation_lists_comparator(
            double_excitations_singlet, self.reference_singlet_double_excitations)
        self.assertEqual(res, True)

        # check grouped singlet excitations
        var_form = UCCSD(
            num_orbitals=self.fermionic_transformation.molecule_info['num_orbitals'],
            num_particles=self.fermionic_transformation.molecule_info['num_particles'],
            active_occupied=None, active_unoccupied=None,
            initial_state=init_state,
            qubit_mapping=self.fermionic_transformation._qubit_mapping,
            two_qubit_reduction=self.fermionic_transformation._two_qubit_reduction,
            num_time_slices=1,
            z2_symmetries=self.fermionic_transformation.molecule_info['z2_symmetries'],
            shallow_circuit_concat=False,
            method_doubles='succ_full',
            excitation_type='d',
            skip_commute_test=True)

        double_excitations_singlet_grouped = var_form._double_excitations_grouped
        res_groups = TestUCCSDHartreeFock.group_excitation_lists_comparator(
            double_excitations_singlet_grouped, self.reference_singlet_groups)
        self.assertEqual(res_groups, True)
Exemplo n.º 3
0
    def test_uccsd_hf_qpUCCD(self):
        """ paired uccd test """

        optimizer = SLSQP(maxiter=100)

        initial_state = HartreeFock(
            self.fermionic_transformation.molecule_info['num_orbitals'],
            self.fermionic_transformation.molecule_info['num_particles'],
            qubit_mapping=self.fermionic_transformation._qubit_mapping,
            two_qubit_reduction=self.fermionic_transformation._two_qubit_reduction)

        var_form = UCCSD(
            num_orbitals=self.fermionic_transformation.molecule_info['num_orbitals'],
            num_particles=self.fermionic_transformation.molecule_info['num_particles'],
            active_occupied=None, active_unoccupied=None,
            initial_state=initial_state,
            qubit_mapping=self.fermionic_transformation._qubit_mapping,
            two_qubit_reduction=self.fermionic_transformation._two_qubit_reduction,
            num_time_slices=1,
            shallow_circuit_concat=False,
            method_doubles='pucc',
            excitation_type='d'
        )

        solver = VQE(var_form=var_form, optimizer=optimizer,
                     quantum_instance=QuantumInstance(
                         backend=BasicAer.get_backend('statevector_simulator')))

        gsc = GroundStateEigensolver(self.fermionic_transformation, solver)

        result = gsc.solve(self.driver)

        self.assertAlmostEqual(result.total_energies[0], self.reference_energy_pUCCD, places=6)
    def setUp(self):
        super().setUp()
        self.skipTest("Skip test until refactored.")
        self.reference_energy = -1.1373060356951838

        self.seed = 700
        algorithm_globals.random_seed = self.seed

        self.driver = HDF5Driver(self.get_resource_path('test_driver_hdf5.hdf5',
                                                        'drivers/hdf5d'))
        fermionic_transformation = \
            FermionicTransformation(qubit_mapping=FermionicQubitMappingType.PARITY,
                                    two_qubit_reduction=False)

        self.qubit_op, _ = fermionic_transformation.transform(self.driver)
        self.fermionic_transformation = fermionic_transformation

        self.optimizer = SLSQP(maxiter=100)
        initial_state = HartreeFock(
            fermionic_transformation.molecule_info['num_orbitals'],
            fermionic_transformation.molecule_info['num_particles'],
            qubit_mapping=fermionic_transformation._qubit_mapping,
            two_qubit_reduction=fermionic_transformation._two_qubit_reduction)
        self.var_form = UCCSD(
            num_orbitals=fermionic_transformation.molecule_info['num_orbitals'],
            num_particles=fermionic_transformation.molecule_info['num_particles'],
            initial_state=initial_state,
            qubit_mapping=fermionic_transformation._qubit_mapping,
            two_qubit_reduction=fermionic_transformation._two_qubit_reduction)
Exemplo n.º 5
0
 def get_solver(self, transformation):
     num_orbitals = transformation.molecule_info['num_orbitals']
     num_particles = transformation.molecule_info['num_particles']
     initial_state = HartreeFock(num_orbitals, num_particles)
     var_form = UCCSD(num_orbitals,
                      num_particles,
                      initial_state=initial_state)
     vqe = VQE(var_form=var_form,
               quantum_instance=self._quantum_instance,
               optimizer=L_BFGS_B())
     return vqe
    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])
Exemplo n.º 7
0
    def test_uccsd_hf_qUCCSD(self):
        """ uccsd tapering test using all double excitations """

        fermionic_transformation = FermionicTransformation(
            transformation=FermionicTransformationType.FULL,
            qubit_mapping=FermionicQubitMappingType.PARITY,
            two_qubit_reduction=True,
            freeze_core=True,
            orbital_reduction=[],
            z2symmetry_reduction='auto'
        )

        qubit_op, _ = fermionic_transformation.transform(self.driver)

        # optimizer
        optimizer = SLSQP(maxiter=100)

        # initial state
        init_state = HartreeFock(
            num_orbitals=fermionic_transformation.molecule_info['num_orbitals'],
            qubit_mapping=fermionic_transformation._qubit_mapping,
            two_qubit_reduction=fermionic_transformation._two_qubit_reduction,
            num_particles=fermionic_transformation.molecule_info['num_particles'],
            sq_list=fermionic_transformation.molecule_info['z2_symmetries'].sq_list)

        var_form = UCCSD(
            num_orbitals=fermionic_transformation.molecule_info['num_orbitals'],
            num_particles=fermionic_transformation.molecule_info['num_particles'],
            active_occupied=None, active_unoccupied=None,
            initial_state=init_state,
            qubit_mapping=fermionic_transformation._qubit_mapping,
            two_qubit_reduction=fermionic_transformation._two_qubit_reduction,
            num_time_slices=1,
            z2_symmetries=fermionic_transformation.molecule_info['z2_symmetries'],
            shallow_circuit_concat=False,
            method_doubles='ucc',
            excitation_type='sd',
            skip_commute_test=True)

        solver = VQE(var_form=var_form, optimizer=optimizer,
                     quantum_instance=QuantumInstance(
                         backend=BasicAer.get_backend('statevector_simulator')))

        raw_result = solver.compute_minimum_eigenvalue(qubit_op, None)
        result = fermionic_transformation.interpret(raw_result)

        self.assertAlmostEqual(result.total_energies[0], self.reference_energy_UCCSD, places=6)
 def get_solver(self, transformation):
     num_orbitals = transformation.molecule_info['num_orbitals']
     num_particles = transformation.molecule_info['num_particles']
     qubit_mapping = transformation.qubit_mapping
     two_qubit_reduction = transformation.molecule_info[
         'two_qubit_reduction']
     z2_symmetries = transformation.molecule_info['z2_symmetries']
     initial_state = HartreeFock(num_orbitals, num_particles,
                                 qubit_mapping, two_qubit_reduction,
                                 z2_symmetries.sq_list)
     var_form = UCCSD(num_orbitals=num_orbitals,
                      num_particles=num_particles,
                      initial_state=initial_state,
                      qubit_mapping=qubit_mapping,
                      two_qubit_reduction=two_qubit_reduction,
                      z2_symmetries=z2_symmetries)
     vqe = VQE(var_form=var_form,
               quantum_instance=self._quantum_instance,
               optimizer=L_BFGS_B())
     return vqe
Exemplo n.º 9
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
Exemplo n.º 10
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
Exemplo n.º 11
0
class TestAdaptVQEUCCSD(QiskitNatureTestCase):
    """ Test Adaptive VQE with UCCSD"""
    def setUp(self):
        super().setUp()
        # np.random.seed(50)
        self.seed = 50
        algorithm_globals.random_seed = self.seed
        try:
            self.driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735',
                                      unit=UnitsType.ANGSTROM,
                                      basis='sto3g')
        except QiskitNatureError:
            self.skipTest('PYSCF driver does not appear to be installed')
            return

        molecule = self.driver.run()
        self.num_particles = molecule.num_alpha + molecule.num_beta
        self.num_spin_orbitals = molecule.num_orbitals * 2
        fer_op = FermionicOperator(h1=molecule.one_body_integrals,
                                   h2=molecule.two_body_integrals)
        map_type = 'PARITY'
        qubit_op = fer_op.mapping(map_type)
        self.qubit_op = TwoQubitReduction(
            num_particles=self.num_particles).convert(qubit_op)
        self.num_qubits = self.qubit_op.num_qubits
        self.init_state = HartreeFock(self.num_spin_orbitals,
                                      self.num_particles)
        self.var_form_base = None

    def test_uccsd_adapt(self):
        """ UCCSD test for adaptive features """
        self.var_form_base = UCCSD(self.num_spin_orbitals,
                                   self.num_particles,
                                   initial_state=self.init_state)
        self.var_form_base.manage_hopping_operators()
        # assert that the excitation pool exists
        self.assertIsNotNone(self.var_form_base.excitation_pool)
        # assert that the hopping ops list has been reset to be empty
        self.assertEqual(self.var_form_base._hopping_ops, [])

    def test_vqe_adapt(self):
        """ AdaptVQE test """
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
            backend = Aer.get_backend('statevector_simulator')
        except ImportError as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return

        class CustomFactory(VQEUCCSDFactory):
            """A custom MESFactory"""
            def get_solver(self, transformation):
                num_orbitals = transformation.molecule_info['num_orbitals']
                num_particles = transformation.molecule_info['num_particles']
                initial_state = HartreeFock(num_orbitals, num_particles)
                var_form = UCCSD(num_orbitals,
                                 num_particles,
                                 initial_state=initial_state)
                vqe = VQE(var_form=var_form,
                          quantum_instance=self._quantum_instance,
                          optimizer=L_BFGS_B())
                return vqe

        algorithm = AdaptVQE(FermionicTransformation(),
                             solver=CustomFactory(QuantumInstance(backend)),
                             threshold=0.00001,
                             delta=0.1,
                             max_iterations=1)
        result = algorithm.solve(driver=self.driver)
        self.assertEqual(result.num_iterations, 1)
        self.assertEqual(result.finishing_criterion,
                         'Maximum number of iterations reached')

        algorithm = AdaptVQE(FermionicTransformation(),
                             solver=CustomFactory(QuantumInstance(backend)),
                             threshold=0.00001,
                             delta=0.1)
        result = algorithm.solve(driver=self.driver)
        self.assertAlmostEqual(result.electronic_energies[0],
                               -1.85727503,
                               places=2)
        self.assertEqual(result.num_iterations, 2)
        self.assertAlmostEqual(result.final_max_gradient, 0.0, places=5)
        self.assertEqual(result.finishing_criterion, 'Threshold converged')

    def test_vqe_adapt_check_cyclicity(self):
        """ AdaptVQE index cycle detection """
        param_list = [
            ([1, 1], True),
            ([1, 11], False),
            ([11, 1], False),
            ([1, 12], False),
            ([12, 2], False),
            ([1, 1, 1], True),
            ([1, 2, 1], False),
            ([1, 2, 2], True),
            ([1, 2, 21], False),
            ([1, 12, 2], False),
            ([11, 1, 2], False),
            ([1, 2, 1, 1], True),
            ([1, 2, 1, 2], True),
            ([1, 2, 1, 21], False),
            ([11, 2, 1, 2], False),
            ([1, 11, 1, 111], False),
            ([11, 1, 111, 1], False),
            ([1, 2, 3, 1, 2, 3], True),
            ([1, 2, 3, 4, 1, 2, 3], False),
            ([11, 2, 3, 1, 2, 3], False),
            ([1, 2, 3, 1, 2, 31], False),
            ([1, 2, 3, 4, 1, 2, 3, 4], True),
            ([11, 2, 3, 4, 1, 2, 3, 4], False),
            ([1, 2, 3, 4, 1, 2, 3, 41], False),
            ([1, 2, 3, 4, 5, 1, 2, 3, 4], False),
        ]
        for seq, is_cycle in param_list:
            with self.subTest(msg="Checking index cyclicity in:", seq=seq):
                self.assertEqual(is_cycle, AdaptVQE._check_cyclicity(seq))