Exemple #1
0
            def get_solver(self, problem, qubit_converter):
                particle_number = cast(
                    ParticleNumber,
                    problem.grouped_property_transformed.get_property(
                        ParticleNumber),
                )
                num_spin_orbitals = particle_number.num_spin_orbitals
                num_particles = (particle_number.num_alpha,
                                 particle_number.num_beta)

                initial_state = HartreeFock(num_spin_orbitals, num_particles,
                                            qubit_converter)
                ansatz = UCC(
                    qubit_converter=qubit_converter,
                    num_particles=num_particles,
                    num_spin_orbitals=num_spin_orbitals,
                    excitations="d",
                    initial_state=initial_state,
                )
                vqe = VQE(
                    ansatz=ansatz,
                    quantum_instance=self.minimum_eigensolver.quantum_instance,
                    optimizer=L_BFGS_B(),
                )
                return vqe
Exemple #2
0
    def test_custom_excitations(self, num_spin_orbitals, num_particles, excitations):
        """Tests if an error is raised when the excitations have a wrong format"""
        converter = QubitConverter(JordanWignerMapper())

        # pylint: disable=unused-argument
        def custom_excitations(num_spin_orbitals, num_particles):
            return excitations

        with self.assertRaises(QiskitNatureError):
            ansatz = UCC(
                qubit_converter=converter,
                num_particles=num_particles,
                num_spin_orbitals=num_spin_orbitals,
                excitations=custom_excitations,
            )
            ansatz.excitation_ops()
 def test_vqe_uccsd(self):
     """Test VQE UCCSD case"""
     solver = VQEUCCFactory(
         quantum_instance=QuantumInstance(BasicAer.get_backend("statevector_simulator")),
         ansatz=UCC(excitations="d"),
     )
     calc = GroundStateEigensolver(self.qubit_converter, solver)
     res = calc.solve(self.electronic_structure_problem)
     self.assertAlmostEqual(res.total_energies[0], self.reference_energy, places=6)
Exemple #4
0
    def test_ucc_ansatz(self, excitations, num_spin_orbitals, num_particles,
                        expect):
        """Tests the UCC Ansatz."""
        converter = QubitConverter(JordanWignerMapper())

        ansatz = UCC(qubit_converter=converter,
                     num_particles=num_particles,
                     num_spin_orbitals=num_spin_orbitals,
                     excitations=excitations)

        assert_ucc_like_ansatz(self, ansatz, num_spin_orbitals, expect)
Exemple #5
0
    def test_transpile_no_parameters(self):
        """Test transpilation without parameters"""

        num_spin_orbitals = 8
        num_particles = (2, 2)
        qubit_converter = QubitConverter(mapper=JordanWignerMapper())

        ansatz = UCC(
            num_spin_orbitals=num_spin_orbitals,
            num_particles=num_particles,
            qubit_converter=qubit_converter,
            excitations="s",
        )

        ansatz = transpile(ansatz, optimization_level=3)
        self.assertEqual(ansatz.num_qubits, 8)
Exemple #6
0
            def get_solver(self, problem, qubit_converter):
                q_molecule_transformed = cast(
                    QMolecule, problem.molecule_data_transformed)
                num_molecular_orbitals = q_molecule_transformed.num_molecular_orbitals
                num_particles = (q_molecule_transformed.num_alpha,
                                 q_molecule_transformed.num_beta)
                num_spin_orbitals = 2 * num_molecular_orbitals

                initial_state = HartreeFock(num_spin_orbitals, num_particles,
                                            qubit_converter)
                ansatz = UCC(qubit_converter=qubit_converter,
                             num_particles=num_particles,
                             num_spin_orbitals=num_spin_orbitals,
                             excitations='d',
                             initial_state=initial_state)
                vqe = VQE(ansatz=ansatz,
                          quantum_instance=self._quantum_instance,
                          optimizer=L_BFGS_B())
                return vqe
Exemple #7
0
def _build_qeom_hopping_ops(
    particle_number: ParticleNumber,
    qubit_converter: QubitConverter,
    excitations: Union[str, int, List[int],
                       Callable[[int, Tuple[int, int]],
                                List[Tuple[Tuple[int, ...],
                                           Tuple[int, ...]]]], ] = "sd",
) -> Tuple[Dict[str, PauliSumOp], Dict[str, List[bool]], Dict[str, Tuple[Tuple[
        int, ...], Tuple[int, ...]]], ]:
    """Builds the product of raising and lowering operators (basic excitation operators)

    Args:
        particle_number: the `ParticleNumber` property containing relevant sector information.
        qubit_converter: the `QubitConverter` to use for mapping and symmetry reduction. The Z2
                         symmetries stored in this instance are the basis for the commutativity
                         information returned by this method.
        excitations: the types of excitations to consider. The simple cases for this input are:
            - a `str` containing any of the following characters: `s`, `d`, `t` or `q`.
            - a single, positive `int` denoting the excitation type (1 == `s`, etc.).
            - a list of positive integers.
            - and finally a callable which can be used to specify a custom list of excitations.
              For more details on how to write such a function refer to the default method,
              :meth:`generate_fermionic_excitations`.

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

    num_alpha, num_beta = particle_number.num_alpha, particle_number.num_beta
    num_spin_orbitals = particle_number.num_spin_orbitals

    excitations_list: List[Tuple[Tuple[int, ...], Tuple[int, ...]]]
    if isinstance(excitations,
                  (str, int)) or (isinstance(excitations, list) and all(
                      isinstance(exc, int) for exc in excitations)):
        ansatz = UCC(qubit_converter, (num_alpha, num_beta), num_spin_orbitals,
                     excitations)
        excitations_list = ansatz._get_excitation_list()
    else:
        excitations_list = cast(List[Tuple[Tuple[int, ...], Tuple[int, ...]]],
                                excitations)

    size = len(excitations_list)

    # build all hopping operators
    hopping_operators: Dict[str, PauliSumOp] = {}
    type_of_commutativities: Dict[str, List[bool]] = {}
    excitation_indices: Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]] = {}
    to_be_executed_list = []
    for idx in range(size):
        to_be_executed_list += [
            excitations_list[idx], excitations_list[idx][::-1]
        ]
        hopping_operators[f"E_{idx}"] = None
        hopping_operators[f"Edag_{idx}"] = None
        type_of_commutativities[f"E_{idx}"] = None
        type_of_commutativities[f"Edag_{idx}"] = None
        excitation_indices[f"E_{idx}"] = excitations_list[idx]
        excitation_indices[f"Edag_{idx}"] = excitations_list[idx][::-1]

    result = parallel_map(
        _build_single_hopping_operator,
        to_be_executed_list,
        task_args=(num_spin_orbitals, qubit_converter),
        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
Exemple #8
0
    def test_build_ucc(self):
        """Test building UCC"""
        ucc = UCC()

        with self.subTest("Check defaulted construction"):
            self.assertIsNone(ucc.num_particles)
            self.assertIsNone(ucc.num_spin_orbitals)
            self.assertIsNone(ucc.excitations)
            self.assertIsNone(ucc.qubit_converter)
            self.assertIsNone(ucc.operators)
            self.assertEqual(ucc.num_qubits, 0)
            with self.assertRaises(ValueError):
                _ = ucc.data

        with self.subTest("Set num particles"):
            ucc.num_particles = (1, 1)
            self.assertEqual(ucc.num_particles, (1, 1))
            self.assertIsNone(ucc.operators)
            with self.assertRaises(ValueError):
                _ = ucc.data

        with self.subTest("Set num spin orbitals"):
            ucc.num_spin_orbitals = 4
            self.assertEqual(ucc.num_spin_orbitals, 4)
            self.assertIsNone(ucc.operators)
            with self.assertRaises(ValueError):
                _ = ucc.data

        with self.subTest("Set excitations"):
            ucc.excitations = "sd"
            self.assertEqual(ucc.excitations, "sd")
            self.assertIsNone(ucc.operators)
            with self.assertRaises(ValueError):
                _ = ucc.data

        with self.subTest("Set qubit converter to complete build"):
            converter = QubitConverter(JordanWignerMapper())
            ucc.qubit_converter = converter
            self.assertEqual(ucc.qubit_converter, converter)
            self.assertIsNotNone(ucc.operators)
            self.assertEqual(len(ucc.operators), 3)
            self.assertEqual(ucc.num_qubits, 4)
            self.assertIsNotNone(ucc.data)

        with self.subTest("Set custom operators"):
            self.assertEqual(len(ucc.operators), 3)
            ucc.operators = ucc.operators[:2]
            self.assertEqual(len(ucc.operators), 2)
            self.assertEqual(ucc.num_qubits, 4)

        with self.subTest("Reset operators back to as per UCC"):
            ucc.operators = None
            self.assertEqual(ucc.num_qubits, 4)
            self.assertIsNotNone(ucc.operators)
            self.assertEqual(len(ucc.operators), 3)

        with self.subTest("Set num particles to include 0"):
            ucc.num_particles = (1, 0)
            self.assertEqual(ucc.num_particles, (1, 0))
            self.assertIsNotNone(ucc.operators)
            self.assertEqual(len(ucc.operators), 1)

        with self.subTest("Change num particles"):
            ucc.num_particles = (1, 1)
            self.assertIsNotNone(ucc.operators)
            self.assertEqual(len(ucc.operators), 3)

        with self.subTest("Change num spin orbitals"):
            ucc.num_spin_orbitals = 6
            self.assertIsNotNone(ucc.operators)
            self.assertEqual(len(ucc.operators), 8)

        with self.subTest("Change excitations"):
            ucc.excitations = "s"
            self.assertIsNotNone(ucc.operators)
            self.assertEqual(len(ucc.operators), 4)

        with self.subTest("Change qubit converter"):
            ucc.qubit_converter = QubitConverter(ParityMapper(),
                                                 two_qubit_reduction=True)
            # Has not been used to convert so we need to force it to do two qubit reduction
            ucc.qubit_converter.force_match(ucc.num_particles)
            self.assertIsNotNone(ucc.operators)
            self.assertEqual(ucc.num_qubits, 4)