def test_second_q_ops_with_active_space(self):
        """Tests that the correct second quantized operator is created if an active space
        transformer is provided."""
        expected_num_of_sec_quant_ops = 7
        expected_fermionic_op_path = self.get_resource_path(
            'H2_631g_ferm_op_active_space', 'problems/second_quantization/'
            'electronic/resources')
        expected_fermionic_op = read_expected_file(expected_fermionic_op_path)
        driver = HDF5Driver(
            hdf5_input=self.get_resource_path('H2_631g.hdf5', 'transformers'))
        trafo = ActiveSpaceTransformer(num_electrons=2,
                                       num_molecular_orbitals=2)

        electronic_structure_problem = ElectronicStructureProblem(
            driver, [trafo])
        second_quantized_ops = electronic_structure_problem.second_q_ops()
        electr_sec_quant_op = second_quantized_ops[0]

        with self.subTest(
                "Check expected length of the list of second quantized operators."
        ):
            assert len(second_quantized_ops) == expected_num_of_sec_quant_ops
        with self.subTest(
                "Check types in the list of second quantized operators."):
            for second_quantized_op in second_quantized_ops:
                assert isinstance(second_quantized_op, SecondQuantizedOp)
        with self.subTest(
                "Check components of electronic second quantized operator."):
            assert all(s[0] == t[0] and np.isclose(s[1], t[1]) for s, t in zip(
                expected_fermionic_op, electr_sec_quant_op.to_list()))
    def test_second_q_ops_without_transformers(self):
        """Tests that the list of second quantized operators is created if no transformers
        provided."""
        expected_num_of_sec_quant_ops = 7
        expected_fermionic_op_path = self.get_resource_path(
            "H2_631g_ferm_op_two_ints",
            "problems/second_quantization/electronic/resources",
        )
        expected_fermionic_op = read_expected_file(expected_fermionic_op_path)

        driver = HDF5Driver(hdf5_input=self.get_resource_path("H2_631g.hdf5", "transformers"))
        electronic_structure_problem = ElectronicStructureProblem(driver)

        second_quantized_ops = electronic_structure_problem.second_q_ops()
        electr_sec_quant_op = second_quantized_ops[0]
        with self.subTest("Check expected length of the list of second quantized operators."):
            assert len(second_quantized_ops) == expected_num_of_sec_quant_ops
        with self.subTest("Check types in the list of second quantized operators."):
            for second_quantized_op in second_quantized_ops:
                assert isinstance(second_quantized_op, SecondQuantizedOp)
        with self.subTest("Check components of electronic second quantized operator."):
            assert all(
                s[0] == t[0] and np.isclose(s[1], t[1])
                for s, t in zip(expected_fermionic_op, electr_sec_quant_op.to_list())
            )
    def test_second_q_ops_with_active_space(self):
        """Tests that the correct second quantized operator is created if an active space
        transformer is provided."""
        expected_num_of_sec_quant_ops = 7
        expected_fermionic_op_path = self.get_resource_path(
            "H2_631g_ferm_op_active_space",
            "problems/second_quantization/electronic/resources",
        )
        expected_fermionic_op = read_expected_file(expected_fermionic_op_path)

        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", category=DeprecationWarning)
            driver = LegacyHDF5Driver(hdf5_input=self.get_resource_path(
                "H2_631g.hdf5", "transformers/second_quantization/electronic"))
            trafo = LegacyActiveSpaceTransformer(num_electrons=2,
                                                 num_molecular_orbitals=2)

            electronic_structure_problem = ElectronicStructureProblem(
                driver, [trafo])
            second_quantized_ops = electronic_structure_problem.second_q_ops()
            electr_sec_quant_op = second_quantized_ops[0]

        with self.subTest("Check that the correct properties are/aren't None"):
            with warnings.catch_warnings():
                warnings.filterwarnings("ignore", category=DeprecationWarning)
                # legacy driver used, molecule_data should not be None
                self.assertIsNotNone(
                    electronic_structure_problem.molecule_data)
                # transformer used, molecule_data_transformed should not be None
                self.assertIsNotNone(
                    electronic_structure_problem.molecule_data_transformed)
            # converted properties should never be None
            self.assertIsNotNone(electronic_structure_problem.grouped_property)
            self.assertIsNotNone(
                electronic_structure_problem.grouped_property_transformed)

        with self.subTest(
                "Check that the deprecated molecule_data property is not None"
        ):
            with warnings.catch_warnings():
                warnings.filterwarnings("ignore", category=DeprecationWarning)
                self.assertIsNotNone(
                    electronic_structure_problem.molecule_data)
        with self.subTest(
                "Check expected length of the list of second quantized operators."
        ):
            assert len(second_quantized_ops) == expected_num_of_sec_quant_ops
        with self.subTest(
                "Check types in the list of second quantized operators."):
            for second_quantized_op in second_quantized_ops:
                assert isinstance(second_quantized_op, SecondQuantizedOp)
        with self.subTest(
                "Check components of electronic second quantized operator."):
            assert all(s[0] == t[0] and np.isclose(s[1], t[1]) for s, t in zip(
                expected_fermionic_op, electr_sec_quant_op.to_list()))
    def test_molecular_problem_sector_locator_z2_symmetry(self):
        """ Test mapping to qubit operator with z2 symmetry tapering and two qubit reduction """

        driver = HDF5Driver(hdf5_input=self.get_resource_path(
            'test_driver_hdf5.hdf5', 'drivers/hdf5d'))
        problem = ElectronicStructureProblem(driver)

        mapper = JordanWignerMapper()
        qubit_conv = QubitConverter(mapper,
                                    two_qubit_reduction=True,
                                    z2symmetry_reduction='auto')
        qubit_op = qubit_conv.convert(
            problem.second_q_ops()[0],
            self.num_particles,
            sector_locator=problem.symmetry_sector_locator)
        self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)
 def test_sector_locator_h2o(self):
     """Test sector locator."""
     driver = PySCFDriver(
         atom=
         "O 0.0000 0.0000 0.1173; H 0.0000 0.07572 -0.4692;H 0.0000 -0.07572 -0.4692",
         basis="sto-3g",
     )
     es_problem = ElectronicStructureProblem(driver)
     qubit_conv = QubitConverter(mapper=ParityMapper(),
                                 two_qubit_reduction=True,
                                 z2symmetry_reduction="auto")
     qubit_conv.convert(
         es_problem.second_q_ops()[0],
         num_particles=es_problem.num_particles,
         sector_locator=es_problem.symmetry_sector_locator,
     )
     self.assertListEqual(qubit_conv.z2symmetries.tapering_values, [1, -1])
    def test_excitation_preserving(self):
        """Test the excitation preserving wavefunction on a chemistry example."""

        driver = HDF5Driver(
            self.get_resource_path("test_driver_hdf5.hdf5", "drivers/hdf5d"))

        converter = QubitConverter(ParityMapper())

        problem = ElectronicStructureProblem(driver)

        _ = problem.second_q_ops()

        num_particles = (
            problem.molecule_data_transformed.num_alpha,
            problem.molecule_data_transformed.num_beta,
        )

        num_spin_orbitals = problem.molecule_data_transformed.num_molecular_orbitals * 2

        optimizer = SLSQP(maxiter=100)

        initial_state = HartreeFock(num_spin_orbitals, num_particles,
                                    converter)

        wavefunction = ExcitationPreserving(num_spin_orbitals)
        wavefunction.compose(initial_state, front=True, inplace=True)

        solver = VQE(
            ansatz=wavefunction,
            optimizer=optimizer,
            quantum_instance=QuantumInstance(
                BasicAer.get_backend("statevector_simulator"),
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )

        gsc = GroundStateEigensolver(converter, solver)

        result = gsc.solve(problem)
        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=4)
    def test_second_q_ops_without_transformers(self):
        """Tests that the list of second quantized operators is created if no transformers
        provided."""
        expected_num_of_sec_quant_ops = 7
        expected_fermionic_op_path = self.get_resource_path(
            "H2_631g_ferm_op_two_ints",
            "problems/second_quantization/electronic/resources",
        )
        expected_fermionic_op = read_expected_file(expected_fermionic_op_path)

        driver = HDF5Driver(hdf5_input=self.get_resource_path(
            "H2_631g.hdf5", "transformers/second_quantization/electronic"))
        electronic_structure_problem = ElectronicStructureProblem(driver)

        second_quantized_ops = electronic_structure_problem.second_q_ops()
        electr_sec_quant_op = second_quantized_ops[
            electronic_structure_problem.main_property_name]
        second_quantized_ops = list(second_quantized_ops.values())

        with self.subTest("Check that the correct properties are/aren't None"):
            with warnings.catch_warnings():
                warnings.filterwarnings("ignore", category=DeprecationWarning)
                # new driver used, molecule_data* should be None
                self.assertIsNone(electronic_structure_problem.molecule_data)
                self.assertIsNone(
                    electronic_structure_problem.molecule_data_transformed)
            # converted properties should never be None
            self.assertIsNotNone(electronic_structure_problem.grouped_property)
            self.assertIsNotNone(
                electronic_structure_problem.grouped_property_transformed)

        with self.subTest(
                "Check expected length of the list of second quantized operators."
        ):
            assert len(second_quantized_ops) == expected_num_of_sec_quant_ops
        with self.subTest(
                "Check types in the list of second quantized operators."):
            for second_quantized_op in second_quantized_ops:
                assert isinstance(second_quantized_op, SecondQuantizedOp)
        with self.subTest(
                "Check components of electronic second quantized operator."):
            assert all(s[0] == t[0] and np.isclose(s[1], t[1]) for s, t in zip(
                expected_fermionic_op, electr_sec_quant_op.to_list()))
 def test_sector_locator_homonuclear(self):
     """Test sector locator."""
     molecule = Molecule(geometry=[("Li", [0.0, 0.0, 0.0]),
                                   ("Li", [0.0, 0.0, 2.771])],
                         charge=0,
                         multiplicity=1)
     freeze_core_transformer = FreezeCoreTransformer(True)
     driver = ElectronicStructureMoleculeDriver(
         molecule,
         basis="sto3g",
         driver_type=ElectronicStructureDriverType.PYSCF)
     es_problem = ElectronicStructureProblem(
         driver, transformers=[freeze_core_transformer])
     qubit_conv = QubitConverter(mapper=ParityMapper(),
                                 two_qubit_reduction=True,
                                 z2symmetry_reduction="auto")
     qubit_conv.convert(
         es_problem.second_q_ops()[0],
         num_particles=es_problem.num_particles,
         sector_locator=es_problem.symmetry_sector_locator,
     )
     self.assertListEqual(qubit_conv.z2symmetries.tapering_values, [-1, 1])
Exemple #9
0
class TestHoppingOpsBuilder(QiskitNatureTestCase):
    """Tests Hopping Operators builder."""
    def setUp(self):
        super().setUp()
        algorithm_globals.random_seed = 8
        try:
            self.driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.75',
                                      unit=UnitsType.ANGSTROM,
                                      charge=0,
                                      spin=0,
                                      basis='sto3g')
        except QiskitNatureError:
            self.skipTest('PYSCF driver does not appear to be installed')

        self.qubit_converter = QubitConverter(JordanWignerMapper())
        self.electronic_structure_problem = ElectronicStructureProblem(
            self.driver)
        self.electronic_structure_problem.second_q_ops()
        self.q_molecule = self.electronic_structure_problem.molecule_data

    def test_build_hopping_operators(self):
        """Tests that the correct hopping operator is built from QMolecule."""
        # TODO extract it somewhere
        expected_hopping_operators = ({
            'E_0':
            PauliSumOp(SparsePauliOp(
                [[True, True, False, False, False, False, False, False],
                 [True, True, False, False, False, True, False, False],
                 [True, True, False, False, True, False, False, False],
                 [True, True, False, False, True, True, False, False]],
                coeffs=[1. + 0.j, 0. - 1.j, 0. + 1.j, 1. + 0.j]),
                       coeff=1.0),
            'Edag_0':
            PauliSumOp(SparsePauliOp(
                [[True, True, False, False, False, False, False, False],
                 [True, True, False, False, False, True, False, False],
                 [True, True, False, False, True, False, False, False],
                 [True, True, False, False, True, True, False, False]],
                coeffs=[-1. + 0.j, 0. - 1.j, 0. + 1.j, -1. + 0.j]),
                       coeff=1.0),
            'E_1':
            PauliSumOp(SparsePauliOp(
                [[False, False, True, True, False, False, False, False],
                 [False, False, True, True, False, False, False, True],
                 [False, False, True, True, False, False, True, False],
                 [False, False, True, True, False, False, True, True]],
                coeffs=[1. + 0.j, 0. - 1.j, 0. + 1.j, 1. + 0.j]),
                       coeff=1.0),
            'Edag_1':
            PauliSumOp(SparsePauliOp(
                [[False, False, True, True, False, False, False, False],
                 [False, False, True, True, False, False, False, True],
                 [False, False, True, True, False, False, True, False],
                 [False, False, True, True, False, False, True, True]],
                coeffs=[-1. + 0.j, 0. - 1.j, 0. + 1.j, -1. + 0.j]),
                       coeff=1.0),
            'E_2':
            PauliSumOp(SparsePauliOp(
                [[True, True, True, True, False, False, False, False],
                 [True, True, True, True, False, False, False, True],
                 [True, True, True, True, False, False, True, False],
                 [True, True, True, True, False, False, True, True],
                 [True, True, True, True, False, True, False, False],
                 [True, True, True, True, False, True, False, True],
                 [True, True, True, True, False, True, True, False],
                 [True, True, True, True, False, True, True, True],
                 [True, True, True, True, True, False, False, False],
                 [True, True, True, True, True, False, False, True],
                 [True, True, True, True, True, False, True, False],
                 [True, True, True, True, True, False, True, True],
                 [True, True, True, True, True, True, False, False],
                 [True, True, True, True, True, True, False, True],
                 [True, True, True, True, True, True, True, False],
                 [True, True, True, True, True, True, True, True]],
                coeffs=[
                    1. + 0.j, 0. - 1.j, 0. + 1.j, 1. + 0.j, 0. - 1.j,
                    -1. + 0.j, 1. + 0.j, 0. - 1.j, 0. + 1.j, 1. + 0.j,
                    -1. + 0.j, 0. + 1.j, 1. + 0.j, 0. - 1.j, 0. + 1.j, 1. + 0.j
                ]),
                       coeff=1.0),
            'Edag_2':
            PauliSumOp(SparsePauliOp(
                [[True, True, True, True, False, False, False, False],
                 [True, True, True, True, False, False, False, True],
                 [True, True, True, True, False, False, True, False],
                 [True, True, True, True, False, False, True, True],
                 [True, True, True, True, False, True, False, False],
                 [True, True, True, True, False, True, False, True],
                 [True, True, True, True, False, True, True, False],
                 [True, True, True, True, False, True, True, True],
                 [True, True, True, True, True, False, False, False],
                 [True, True, True, True, True, False, False, True],
                 [True, True, True, True, True, False, True, False],
                 [True, True, True, True, True, False, True, True],
                 [True, True, True, True, True, True, False, False],
                 [True, True, True, True, True, True, False, True],
                 [True, True, True, True, True, True, True, False],
                 [True, True, True, True, True, True, True, True]],
                coeffs=[
                    1. + 0.j, 0. + 1.j, 0. - 1.j, 1. + 0.j, 0. + 1.j,
                    -1. + 0.j, 1. + 0.j, 0. + 1.j, 0. - 1.j, 1. + 0.j,
                    -1. + 0.j, 0. - 1.j, 1. + 0.j, 0. + 1.j, 0. - 1.j, 1. + 0.j
                ]),
                       coeff=1.0)
        }, {
            'E_0': [],
            'Edag_0': [],
            'E_1': [],
            'Edag_1': [],
            'E_2': [],
            'Edag_2': []
        }, {
            'E_0': ((0, ), (1, )),
            'Edag_0': ((1, ), (0, )),
            'E_1': ((2, ), (3, )),
            'Edag_1': ((3, ), (2, )),
            'E_2': ((0, 2), (1, 3)),
            'Edag_2': ((1, 3), (0, 2))
        })

        hopping_operators = _build_qeom_hopping_ops(self.q_molecule,
                                                    self.qubit_converter)
        self.assertEqual(hopping_operators, expected_hopping_operators)
class TestGroundStateEigensolver(QiskitNatureTestCase):
    """Test GroundStateEigensolver"""
    def setUp(self):
        super().setUp()
        warnings.filterwarnings("ignore",
                                category=DeprecationWarning,
                                module=".*drivers.*")
        self.driver = HDF5Driver(
            self.get_resource_path("test_driver_hdf5.hdf5",
                                   "drivers/second_quantization/hdf5d"))
        self.seed = 56
        algorithm_globals.random_seed = self.seed

        self.reference_energy = -1.1373060356951838

        self.qubit_converter = QubitConverter(JordanWignerMapper())
        self.electronic_structure_problem = ElectronicStructureProblem(
            self.driver)

        self.num_spin_orbitals = 4
        self.num_particles = (1, 1)

    def test_npme(self):
        """Test NumPyMinimumEigensolver"""
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_npme_with_default_filter(self):
        """Test NumPyMinimumEigensolver with default filter"""
        solver = NumPyMinimumEigensolverFactory(
            use_default_filter_criterion=True)
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    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)

    def test_vqe_uccsd_with_callback(self):
        """Test VQE UCCSD with callback."""
        def callback(nfev, parameters, energy, stddev):
            # pylint: disable=unused-argument
            print(f"iterations {nfev}: energy: {energy}")

        solver = VQEUCCFactory(
            quantum_instance=QuantumInstance(
                BasicAer.get_backend("statevector_simulator")),
            callback=callback,
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        with contextlib.redirect_stdout(io.StringIO()) as out:
            res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)
        for idx, line in enumerate(out.getvalue().split("\n")):
            if line.strip():
                self.assertTrue(
                    line.startswith(f"iterations {idx+1}: energy: "))

    def test_vqe_ucc_custom(self):
        """Test custom ansatz in Factory use case"""
        solver = VQEUCCFactory(quantum_instance=QuantumInstance(
            BasicAer.get_backend("statevector_simulator")))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_aux_ops_reusability(self):
        """Test that the auxiliary operators can be reused"""
        # Regression test against #1475
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)

        modes = 4
        h_1 = np.eye(modes, dtype=complex)
        h_2 = np.zeros((modes, modes, modes, modes))
        aux_ops = list(
            ElectronicEnergy([
                OneBodyElectronicIntegrals(ElectronicBasis.MO, (h_1, None)),
                TwoBodyElectronicIntegrals(ElectronicBasis.MO,
                                           (h_2, None, None, None)),
            ], ).second_q_ops().values())
        aux_ops_copy = copy.deepcopy(aux_ops)

        _ = calc.solve(self.electronic_structure_problem)

        assert all(
            frozenset(a.to_list()) == frozenset(b.to_list())
            for a, b in zip(aux_ops, aux_ops_copy))

    def test_list_based_aux_ops(self):
        """Test the list based aux ops variant"""
        msg_ref = (
            "List-based `aux_operators` are deprecated as of version 0.3.0 and support "
            "for them will be removed no sooner than 3 months after the release. Instead, "
            "use dict-based `aux_operators`. You can switch to the dict-based interface "
            "immediately, by setting `qiskit_nature.settings.dict_aux_operators` to `True`."
        )
        with warnings.catch_warnings(record=True) as c_m:
            warnings.simplefilter("always")
            settings.dict_aux_operators = False
            try:
                solver = NumPyMinimumEigensolverFactory()
                calc = GroundStateEigensolver(self.qubit_converter, solver)
                res = calc.solve(self.electronic_structure_problem)
                self.assertAlmostEqual(res.total_energies[0],
                                       self.reference_energy,
                                       places=6)
                self.assertTrue(
                    np.all(
                        isinstance(aux_op, dict)
                        for aux_op in res.aux_operator_eigenvalues))
                aux_op_eigenvalue = res.aux_operator_eigenvalues[0]
                self.assertAlmostEqual(aux_op_eigenvalue[0][0], 2.0, places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[1][1], 0.0, places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[2][0], 0.0, places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[2][1], 0.0, places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[3][0], 0.0, places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[3][1], 0.0, places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[4][0], 0.0, places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[4][1], 0.0, places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[5][0],
                                       -1.3889487,
                                       places=6)
                self.assertAlmostEqual(aux_op_eigenvalue[5][1], 0.0, places=6)
            finally:
                settings.dict_aux_operators = True
            msg = str(c_m[0].message)
            self.assertEqual(msg, msg_ref)

    def _setup_evaluation_operators(self):
        # first we run a ground state calculation
        solver = VQEUCCFactory(quantum_instance=QuantumInstance(
            BasicAer.get_backend("statevector_simulator")))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)

        # now we decide that we want to evaluate another operator
        # for testing simplicity, we just use some pre-constructed auxiliary operators
        second_q_ops = self.electronic_structure_problem.second_q_ops()
        # Remove main op to leave just aux ops
        second_q_ops.pop(self.electronic_structure_problem.main_property_name)
        aux_ops_dict = self.qubit_converter.convert_match(second_q_ops)
        return calc, res, aux_ops_dict

    def test_eval_op_single(self):
        """Test evaluating a single additional operator"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because in this test we test a single operator evaluation
        add_aux_op = aux_ops["ParticleNumber"][0]

        # now we have the ground state calculation evaluate it
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res[0], complex)
        self.assertAlmostEqual(add_aux_op_res[0].real, 2, places=6)

    def test_eval_op_single_none(self):
        """Test evaluating a single `None` operator"""
        calc, res, _ = self._setup_evaluation_operators()
        # we filter the list because in this test we test a single operator evaluation
        add_aux_op = None

        # now we have the ground state calculation evaluate it
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsNone(add_aux_op_res)

    def test_eval_op_list(self):
        """Test evaluating a list of additional operators"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            "number of particles": 2,
            "s^2": 0,
            "magnetization": 0
        }
        add_aux_op = [
            aux_ops["ParticleNumber"],
            aux_ops["AngularMomentum"],
            aux_ops["Magnetization"],
        ]

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, list)
        # in this list we require that the order of the results remains unchanged
        for idx, expected in enumerate(expected_results.values()):
            self.assertAlmostEqual(add_aux_op_res[idx][0].real,
                                   expected,
                                   places=6)

    def test_eval_op_list_none(self):
        """Test evaluating a list of additional operators incl. `None`"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            "number of particles": 2,
            "s^2": 0,
            "magnetization": 0
        }
        add_aux_op = [
            aux_ops["ParticleNumber"],
            aux_ops["AngularMomentum"],
            aux_ops["Magnetization"],
        ] + [None]

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, list)
        # in this list we require that the order of the results remains unchanged
        for idx, expected in enumerate(expected_results.values()):
            self.assertAlmostEqual(add_aux_op_res[idx][0].real,
                                   expected,
                                   places=6)
        self.assertIsNone(add_aux_op_res[-1])

    def test_eval_op_dict(self):
        """Test evaluating a dict of additional operators"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            "number of particles": 2,
            "s^2": 0,
            "magnetization": 0
        }
        add_aux_op = [
            aux_ops["ParticleNumber"],
            aux_ops["AngularMomentum"],
            aux_ops["Magnetization"],
        ]
        # now we convert it into a dictionary
        add_aux_op = dict(zip(expected_results.keys(), add_aux_op))

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, dict)
        for name, expected in expected_results.items():
            self.assertAlmostEqual(add_aux_op_res[name][0].real,
                                   expected,
                                   places=6)

    def test_eval_op_dict_none(self):
        """Test evaluating a dict of additional operators incl. `None`"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            "number of particles": 2,
            "s^2": 0,
            "magnetization": 0
        }
        add_aux_op = [
            aux_ops["ParticleNumber"],
            aux_ops["AngularMomentum"],
            aux_ops["Magnetization"],
        ]
        # now we convert it into a dictionary
        add_aux_op = dict(zip(expected_results.keys(), add_aux_op))
        add_aux_op["None"] = None

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, dict)
        for name, expected in expected_results.items():
            self.assertAlmostEqual(add_aux_op_res[name][0].real,
                                   expected,
                                   places=6)
        self.assertIsNone(add_aux_op_res["None"])

    @slow_test
    def test_eval_op_qasm(self):
        """Regression tests against https://github.com/Qiskit/qiskit-nature/issues/53."""
        solver = VQEUCCFactory(
            optimizer=SLSQP(maxiter=100),
            expectation=PauliExpectation(),
            quantum_instance=QuantumInstance(
                backend=BasicAer.get_backend("qasm_simulator"),
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res_qasm = calc.solve(self.electronic_structure_problem)

        hamiltonian = self.electronic_structure_problem.second_q_ops()[
            self.electronic_structure_problem.main_property_name]
        qubit_op = self.qubit_converter.map(hamiltonian)

        ansatz = solver.get_solver(self.electronic_structure_problem,
                                   self.qubit_converter).ansatz
        circuit = ansatz.assign_parameters(res_qasm.raw_result.optimal_point)
        mean = calc.evaluate_operators(circuit, qubit_op)

        self.assertAlmostEqual(res_qasm.eigenenergies[0], mean[0].real)

    @unittest.skipUnless(optionals.HAS_AER,
                         "qiskit-aer is required to run this test")
    def test_eval_op_qasm_aer(self):
        """Regression tests against https://github.com/Qiskit/qiskit-nature/issues/53."""

        backend = qiskit.providers.aer.Aer.get_backend("aer_simulator")

        solver = VQEUCCFactory(
            optimizer=SLSQP(maxiter=100),
            expectation=AerPauliExpectation(),
            include_custom=True,
            quantum_instance=QuantumInstance(
                backend=backend,
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res_qasm = calc.solve(self.electronic_structure_problem)

        hamiltonian = self.electronic_structure_problem.second_q_ops()[
            self.electronic_structure_problem.main_property_name]
        qubit_op = self.qubit_converter.map(hamiltonian)

        ansatz = solver.get_solver(self.electronic_structure_problem,
                                   self.qubit_converter).ansatz
        circuit = ansatz.assign_parameters(res_qasm.raw_result.optimal_point)
        mean = calc.evaluate_operators(circuit, qubit_op)

        self.assertAlmostEqual(res_qasm.eigenenergies[0], mean[0].real)

    def _prepare_uccsd_hf(self, qubit_converter):
        initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles,
                                    qubit_converter)
        ansatz = UCCSD(
            qubit_converter,
            self.num_particles,
            self.num_spin_orbitals,
            initial_state=initial_state,
        )

        return ansatz

    def test_uccsd_hf(self):
        """uccsd hf test"""
        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SLSQP(maxiter=100)
        backend = BasicAer.get_backend("statevector_simulator")
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            quantum_instance=QuantumInstance(backend=backend),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)

        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=6)

    @slow_test
    def test_uccsd_hf_qasm(self):
        """uccsd hf test with qasm simulator."""
        qubit_converter = QubitConverter(ParityMapper())
        ansatz = self._prepare_uccsd_hf(qubit_converter)

        backend = BasicAer.get_backend("qasm_simulator")

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            expectation=PauliExpectation(),
            quantum_instance=QuantumInstance(
                backend=backend,
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )

        gsc = GroundStateEigensolver(qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0], -1.138, places=2)

    @slow_test
    @unittest.skipUnless(optionals.HAS_AER,
                         "qiskit-aer is required to run this test")
    def test_uccsd_hf_aer_statevector(self):
        """uccsd hf test with Aer statevector"""

        backend = qiskit.providers.aer.Aer.get_backend(
            "aer_simulator_statevector")

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SLSQP(maxiter=100)
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            quantum_instance=QuantumInstance(backend=backend),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=6)

    @slow_test
    @unittest.skipUnless(optionals.HAS_AER,
                         "qiskit-aer is required to run this test")
    def test_uccsd_hf_aer_qasm(self):
        """uccsd hf test with Aer qasm simulator."""

        backend = qiskit.providers.aer.Aer.get_backend("aer_simulator")

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            expectation=PauliExpectation(group_paulis=False),
            quantum_instance=QuantumInstance(
                backend=backend,
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0], -1.131, places=2)

    @slow_test
    @unittest.skipUnless(optionals.HAS_AER,
                         "qiskit-aer is required to run this test")
    def test_uccsd_hf_aer_qasm_snapshot(self):
        """uccsd hf test with Aer qasm simulator snapshot."""

        backend = qiskit.providers.aer.Aer.get_backend("aer_simulator")

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            expectation=AerPauliExpectation(),
            quantum_instance=QuantumInstance(backend=backend),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=3)

    def test_freeze_core_z2_symmetry_compatibility(self):
        """Regression test against #192.

        An issue arose when the FreezeCoreTransformer was combined with the automatic Z2Symmetry
        reduction. This regression test ensures that this behavior remains fixed.
        """
        driver = HDF5Driver(hdf5_input=self.get_resource_path(
            "LiH_sto3g.hdf5", "transformers/second_quantization/electronic"))
        problem = ElectronicStructureProblem(driver, [FreezeCoreTransformer()])
        qubit_converter = QubitConverter(
            ParityMapper(),
            two_qubit_reduction=True,
            z2symmetry_reduction="auto",
        )

        solver = NumPyMinimumEigensolverFactory()
        gsc = GroundStateEigensolver(qubit_converter, solver)

        result = gsc.solve(problem)
        self.assertAlmostEqual(result.total_energies[0], -7.882, places=2)

    def test_total_dipole(self):
        """Regression test against #198.

        An issue with calculating the dipole moment that had division None/float.
        """
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_dipole_moment_in_debye[0],
                               0.0,
                               places=1)

    def test_print_result(self):
        """Regression test against #198 and general issues with printing results."""
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        with contextlib.redirect_stdout(io.StringIO()) as out:
            print(res)
        # do NOT change the below! Lines have been truncated as to not force exact numerical matches
        expected = """\
            === GROUND STATE ENERGY ===

            * Electronic ground state energy (Hartree): -1.857
              - computed part:      -1.857
            ~ Nuclear repulsion energy (Hartree): 0.719
            > Total ground state energy (Hartree): -1.137

            === MEASURED OBSERVABLES ===

              0:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000

            === DIPOLE MOMENTS ===

            ~ Nuclear dipole moment (a.u.): [0.0  0.0  1.38

              0:
              * Electronic dipole moment (a.u.): [0.0  0.0  -1.38
                - computed part:      [0.0  0.0  -1.38
              > Dipole moment (a.u.): [0.0  0.0  0.0]  Total: 0.
                             (debye): [0.0  0.0  0.0]  Total: 0.
        """
        for truth, expected in zip(out.getvalue().split("\n"),
                                   expected.split("\n")):
            assert truth.strip().startswith(expected.strip())

    def test_default_initial_point(self):
        """Test when using the default initial point."""

        solver = VQEUCCFactory(quantum_instance=QuantumInstance(
            BasicAer.get_backend("statevector_simulator")))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)

        np.testing.assert_array_equal(solver.initial_point.to_numpy_array(),
                                      [0.0, 0.0, 0.0])
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_vqe_ucc_factory_with_user_initial_point(self):
        """Test VQEUCCFactory when using it with a user defined initial point."""

        initial_point = np.asarray(
            [1.28074029e-19, 5.92226076e-08, 1.11762559e-01])
        solver = VQEUCCFactory(
            quantum_instance=QuantumInstance(
                BasicAer.get_backend("statevector_simulator")),
            initial_point=initial_point,
            optimizer=SLSQP(maxiter=1),
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        np.testing.assert_array_almost_equal(res.raw_result.optimal_point,
                                             initial_point)

    def test_vqe_ucc_factory_with_mp2(self):
        """Test when using MP2InitialPoint to generate the initial point."""

        informed_start = MP2InitialPoint()

        solver = VQEUCCFactory(
            quantum_instance=QuantumInstance(
                BasicAer.get_backend("statevector_simulator")),
            initial_point=informed_start,
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)

        np.testing.assert_array_almost_equal(
            solver.initial_point.to_numpy_array(), [0.0, 0.0, -0.07197145])
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)
class TestUCCSDHartreeFock(QiskitNatureTestCase):
    """Test for these extensions."""
    @unittest.skipIf(not _optionals.HAS_PYSCF, "pyscf not available.")
    def setUp(self):
        super().setUp()
        self.driver = PySCFDriver(atom="H 0 0 0.735; H 0 0 0", basis="631g")

        self.qubit_converter = QubitConverter(ParityMapper(),
                                              two_qubit_reduction=True)

        self.electronic_structure_problem = ElectronicStructureProblem(
            self.driver, [FreezeCoreTransformer()])

        self.num_spin_orbitals = 8
        self.num_particles = (1, 1)

        # because we create the initial state and ansatzes early, we need to ensure the qubit
        # converter already ran such that convert_match works as expected
        _ = self.qubit_converter.convert(
            self.electronic_structure_problem.second_q_ops()[0],
            self.num_particles)

        self.reference_energy_pUCCD = -1.1434447924298028
        self.reference_energy_UCCD0 = -1.1476045878481704
        self.reference_energy_UCCD0full = -1.1515491334334347
        # reference energy of UCCSD/VQE with tapering everywhere
        self.reference_energy_UCCSD = -1.1516142309717594
        # reference energy of UCCSD/VQE when no tapering on excitations is used
        self.reference_energy_UCCSD_no_tap_exc = -1.1516142309717594
        # excitations for succ
        self.reference_singlet_double_excitations = [
            [0, 1, 4, 5],
            [0, 1, 4, 6],
            [0, 1, 4, 7],
            [0, 2, 4, 6],
            [0, 2, 4, 7],
            [0, 3, 4, 7],
        ]
        # groups for succ_full
        self.reference_singlet_groups = [
            [[0, 1, 4, 5]],
            [[0, 1, 4, 6], [0, 2, 4, 5]],
            [[0, 1, 4, 7], [0, 3, 4, 5]],
            [[0, 2, 4, 6]],
            [[0, 2, 4, 7], [0, 3, 4, 6]],
            [[0, 3, 4, 7]],
        ]

    @slow_test
    def test_uccsd_hf_qpUCCD(self):
        """paired uccd test"""
        self.skipTest(
            "Temporarily skip test until the changes done by "
            "https://github.com/Qiskit/qiskit-terra/pull/7551 are handled properly."
        )
        optimizer = SLSQP(maxiter=100)

        initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles,
                                    self.qubit_converter)

        ansatz = PUCCD(
            self.qubit_converter,
            self.num_particles,
            self.num_spin_orbitals,
            initial_state=initial_state,
        )

        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            quantum_instance=QuantumInstance(
                backend=BasicAer.get_backend("statevector_simulator")),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)

        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy_pUCCD,
                               places=6)

    @slow_test
    def test_uccsd_hf_qUCCD0(self):
        """singlet uccd test"""
        self.skipTest(
            "Temporarily skip test until the changes done by "
            "https://github.com/Qiskit/qiskit-terra/pull/7551 are handled properly."
        )
        optimizer = SLSQP(maxiter=100)

        initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles,
                                    self.qubit_converter)

        ansatz = SUCCD(
            self.qubit_converter,
            self.num_particles,
            self.num_spin_orbitals,
            initial_state=initial_state,
        )

        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            quantum_instance=QuantumInstance(
                backend=BasicAer.get_backend("statevector_simulator")),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)

        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy_UCCD0,
                               places=6)

    @unittest.skip(
        "Skip until https://github.com/Qiskit/qiskit-nature/issues/91 is closed."
    )
    def test_uccsd_hf_qUCCD0full(self):
        """singlet full uccd test"""
        optimizer = SLSQP(maxiter=100)

        initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles,
                                    self.qubit_converter)

        # TODO: add `full` option
        ansatz = SUCCD(
            self.qubit_converter,
            self.num_particles,
            self.num_spin_orbitals,
            initial_state=initial_state,
        )

        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            quantum_instance=QuantumInstance(
                backend=BasicAer.get_backend("statevector_simulator")),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)

        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy_UCCD0full,
                               places=6)
Exemple #12
0
    def test_h2_bopes_sampler_auxiliaries(self):
        """Test BOPES Sampler on H2"""
        # Molecule
        dof = partial(Molecule.absolute_distance, atom_pair=(1, 0))
        m = Molecule(
            geometry=[["H", [0.0, 0.0, 1.0]], ["H", [0.0, 0.45, 1.0]]],
            degrees_of_freedom=[dof],
        )
        driver = ElectronicStructureMoleculeDriver(
            m, driver_type=ElectronicStructureDriverType.PYSCF)
        problem = ElectronicStructureProblem(driver)

        qubit_converter = QubitConverter(JordanWignerMapper(),
                                         z2symmetry_reduction=None)
        quantum_instance = QuantumInstance(
            backend=qiskit.providers.aer.Aer.get_backend(
                "aer_simulator_statevector"),
            seed_simulator=self.seed,
            seed_transpiler=self.seed,
        )
        solver = VQE(quantum_instance=quantum_instance)
        me_gsc = GroundStateEigensolver(qubit_converter, solver)

        # Sets up the auxiliary operators

        def build_hamiltonian(
                current_problem: BaseProblem) -> SecondQuantizedOp:
            """Returns the SecondQuantizedOp H(R) where H is the electronic hamiltonian and R is
            the current nuclear coordinates. This gives the electronic energies."""
            hamiltonian_name = current_problem.main_property_name
            hamiltonian_op = current_problem.second_q_ops().get(
                hamiltonian_name, None)
            return hamiltonian_op

        aux = {
            "PN":
            problem.second_q_ops()["ParticleNumber"],  # SecondQuantizedOp
            "EN": build_hamiltonian,  # Callable
            "IN": PauliOp(Pauli("IIII"), 1.0),  # PauliOp
        }
        # Note that the first item is defined once for R=0.45.
        # The second item is a function of the problem giving the electronic energy.
        # At each step, a perturbation is applied to the molecule degrees of freedom which updates
        # the aux_operators.
        # The third item is the identity written as a PauliOp, yielding the norm of the eigenstates.

        # Sets up the BOPESSampler
        sampler = BOPESSampler(me_gsc)

        # absolute internuclear distance in Angstrom
        points = [0.7, 1.0, 1.3]
        results = sampler.sample(problem, points, aux_operators=aux)
        points_run = results.points

        particle_numbers = []
        total_energies = []
        norm_eigenstates = []

        for results_point in list(results.raw_results.values()):
            aux_op_dict = results_point.raw_result.aux_operator_eigenvalues
            particle_numbers.append(aux_op_dict["PN"][0])
            total_energies.append(aux_op_dict["EN"][0] +
                                  results_point.nuclear_repulsion_energy)
            norm_eigenstates.append(aux_op_dict["IN"][0])

        points_run_reference = [0.7, 1.0, 1.3]
        particle_numbers_reference = [2, 2, 2]
        total_energies_reference = [-1.136, -1.101, -1.035]
        norm_eigenstates_reference = [1, 1, 1]

        np.testing.assert_array_almost_equal(points_run, points_run_reference)
        np.testing.assert_array_almost_equal(particle_numbers,
                                             particle_numbers_reference,
                                             decimal=2)
        np.testing.assert_array_almost_equal(
            total_energies,
            total_energies_reference,
            decimal=2,
        )
        np.testing.assert_array_almost_equal(
            norm_eigenstates,
            norm_eigenstates_reference,
            decimal=2,
        )
Exemple #13
0
class TestHoppingOpsBuilder(QiskitNatureTestCase):
    """Tests Hopping Operators builder."""

    @unittest.skipIf(not _optionals.HAS_PYSCF, "pyscf not available.")
    def setUp(self):
        super().setUp()
        algorithm_globals.random_seed = 8
        self.driver = PySCFDriver(
            atom="H .0 .0 .0; H .0 .0 0.75",
            unit=UnitsType.ANGSTROM,
            charge=0,
            spin=0,
            basis="sto3g",
        )

        self.qubit_converter = QubitConverter(JordanWignerMapper())
        self.electronic_structure_problem = ElectronicStructureProblem(self.driver)
        self.electronic_structure_problem.second_q_ops()
        self.particle_number = (
            self.electronic_structure_problem.grouped_property_transformed.get_property(
                "ParticleNumber"
            )
        )

    def test_build_hopping_operators(self):
        """Tests that the correct hopping operator is built from QMolecule."""
        # TODO extract it somewhere
        expected_hopping_operators = (
            {
                "E_0": PauliSumOp.from_list(
                    [("IIXX", 1), ("IIYX", 1j), ("IIXY", -1j), ("IIYY", 1)]
                ),
                "Edag_0": PauliSumOp.from_list(
                    [("IIXX", -1), ("IIYX", 1j), ("IIXY", -1j), ("IIYY", -1)]
                ),
                "E_1": PauliSumOp.from_list(
                    [("XXII", 1), ("YXII", 1j), ("XYII", -1j), ("YYII", 1)]
                ),
                "Edag_1": PauliSumOp.from_list(
                    [("XXII", -1), ("YXII", 1j), ("XYII", -1j), ("YYII", -1)]
                ),
                "E_2": PauliSumOp.from_list(
                    [
                        ("XXXX", 1),
                        ("YXXX", 1j),
                        ("XYXX", -1j),
                        ("YYXX", 1),
                        ("XXYX", 1j),
                        ("YXYX", -1),
                        ("XYYX", 1),
                        ("YYYX", 1j),
                        ("XXXY", -1j),
                        ("YXXY", 1),
                        ("XYXY", -1),
                        ("YYXY", -1j),
                        ("XXYY", 1),
                        ("YXYY", 1j),
                        ("XYYY", -1j),
                        ("YYYY", 1),
                    ]
                ),
                "Edag_2": PauliSumOp.from_list(
                    [
                        ("XXXX", 1),
                        ("YXXX", -1j),
                        ("XYXX", 1j),
                        ("YYXX", 1),
                        ("XXYX", -1j),
                        ("YXYX", -1),
                        ("XYYX", 1),
                        ("YYYX", -1j),
                        ("XXXY", 1j),
                        ("YXXY", 1),
                        ("XYXY", -1),
                        ("YYXY", 1j),
                        ("XXYY", 1),
                        ("YXYY", -1j),
                        ("XYYY", 1j),
                        ("YYYY", 1),
                    ]
                ),
            },
            {"E_0": [], "Edag_0": [], "E_1": [], "Edag_1": [], "E_2": [], "Edag_2": []},
            {
                "E_0": ((0,), (1,)),
                "Edag_0": ((1,), (0,)),
                "E_1": ((2,), (3,)),
                "Edag_1": ((3,), (2,)),
                "E_2": ((0, 2), (1, 3)),
                "Edag_2": ((1, 3), (0, 2)),
            },
        )

        hopping_operators = _build_qeom_hopping_ops(self.particle_number, self.qubit_converter)
        self.assertEqual(hopping_operators, expected_hopping_operators)
Exemple #14
0
class TestGroundStateEigensolver(QiskitNatureTestCase):
    """ Test GroundStateEigensolver """
    def setUp(self):
        super().setUp()
        self.driver = HDF5Driver(
            self.get_resource_path('test_driver_hdf5.hdf5', 'drivers/hdf5d'))
        self.seed = 700
        algorithm_globals.random_seed = self.seed

        self.reference_energy = -1.1373060356951838

        self.qubit_converter = QubitConverter(JordanWignerMapper())
        self.electronic_structure_problem = ElectronicStructureProblem(
            self.driver)

        self.num_spin_orbitals = 4
        self.num_particles = (1, 1)

    def test_npme(self):
        """ Test NumPyMinimumEigensolver """
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_npme_with_default_filter(self):
        """ Test NumPyMinimumEigensolver with default filter """
        solver = NumPyMinimumEigensolverFactory(
            use_default_filter_criterion=True)
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    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)

    def test_vqe_ucc_custom(self):
        """ Test custom ansatz in Factory use case """
        solver = VQEUCCFactory(
            QuantumInstance(BasicAer.get_backend('statevector_simulator')))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_aux_ops_reusability(self):
        """ Test that the auxiliary operators can be reused """
        # Regression test against #1475
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)

        modes = 4
        h_1 = np.eye(modes, dtype=complex)
        h_2 = np.zeros((modes, modes, modes, modes))
        aux_ops = [build_ferm_op_from_ints(h_1, h_2)]
        aux_ops_copy = copy.deepcopy(aux_ops)

        _ = calc.solve(self.electronic_structure_problem)
        assert all(
            frozenset(a.to_list()) == frozenset(b.to_list())
            for a, b in zip(aux_ops, aux_ops_copy))

    def _setup_evaluation_operators(self):
        # first we run a ground state calculation
        solver = VQEUCCFactory(
            QuantumInstance(BasicAer.get_backend('statevector_simulator')))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)

        # now we decide that we want to evaluate another operator
        # for testing simplicity, we just use some pre-constructed auxiliary operators
        _, *aux_ops = self.qubit_converter.convert_match(
            self.electronic_structure_problem.second_q_ops())
        return calc, res, aux_ops

    def test_eval_op_single(self):
        """ Test evaluating a single additional operator """
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because in this test we test a single operator evaluation
        add_aux_op = aux_ops[0][0]

        # now we have the ground state calculation evaluate it
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res[0], complex)
        self.assertAlmostEqual(add_aux_op_res[0].real, 2, places=6)

    def test_eval_op_single_none(self):
        """ Test evaluating a single `None` operator """
        calc, res, _ = self._setup_evaluation_operators()
        # we filter the list because in this test we test a single operator evaluation
        add_aux_op = None

        # now we have the ground state calculation evaluate it
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsNone(add_aux_op_res)

    def test_eval_op_list(self):
        """ Test evaluating a list of additional operators """
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            'number of particles': 2,
            's^2': 0,
            'magnetization': 0
        }
        add_aux_op = aux_ops[0:3]

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, list)
        # in this list we require that the order of the results remains unchanged
        for idx, expected in enumerate(expected_results.values()):
            self.assertAlmostEqual(add_aux_op_res[idx][0].real,
                                   expected,
                                   places=6)

    def test_eval_op_list_none(self):
        """ Test evaluating a list of additional operators incl. `None` """
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            'number of particles': 2,
            's^2': 0,
            'magnetization': 0
        }
        add_aux_op = aux_ops[0:3] + [None]

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, list)
        # in this list we require that the order of the results remains unchanged
        for idx, expected in enumerate(expected_results.values()):
            self.assertAlmostEqual(add_aux_op_res[idx][0].real,
                                   expected,
                                   places=6)
        self.assertIsNone(add_aux_op_res[-1])

    def test_eval_op_dict(self):
        """ Test evaluating a dict of additional operators """
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            'number of particles': 2,
            's^2': 0,
            'magnetization': 0
        }
        add_aux_op = aux_ops[0:3]
        # now we convert it into a dictionary
        add_aux_op = dict(zip(expected_results.keys(), add_aux_op))

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, dict)
        for name, expected in expected_results.items():
            self.assertAlmostEqual(add_aux_op_res[name][0].real,
                                   expected,
                                   places=6)

    def test_eval_op_dict_none(self):
        """ Test evaluating a dict of additional operators incl. `None` """
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            'number of particles': 2,
            's^2': 0,
            'magnetization': 0
        }
        add_aux_op = aux_ops[0:3]
        # now we convert it into a dictionary
        add_aux_op = dict(zip(expected_results.keys(), add_aux_op))
        add_aux_op['None'] = None

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, dict)
        for name, expected in expected_results.items():
            self.assertAlmostEqual(add_aux_op_res[name][0].real,
                                   expected,
                                   places=6)
        self.assertIsNone(add_aux_op_res['None'])

    @slow_test
    def test_eval_op_qasm(self):
        """Regression tests against https://github.com/Qiskit/qiskit-nature/issues/53."""
        solver = VQEUCCFactory(
            optimizer=SLSQP(maxiter=100),
            expectation=PauliExpectation(),
            quantum_instance=QuantumInstance(
                backend=BasicAer.get_backend('qasm_simulator'),
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res_qasm = calc.solve(self.electronic_structure_problem)

        hamiltonian = self.electronic_structure_problem.second_q_ops()[0]
        qubit_op = self.qubit_converter.map(hamiltonian)

        ansatz = solver.get_solver(self.electronic_structure_problem,
                                   self.qubit_converter).ansatz
        circuit = ansatz.assign_parameters(res_qasm.raw_result.optimal_point)
        mean = calc.evaluate_operators(circuit, qubit_op)

        self.assertAlmostEqual(res_qasm.eigenenergies[0], mean[0].real)

    def test_eval_op_qasm_aer(self):
        """Regression tests against https://github.com/Qiskit/qiskit-nature/issues/53."""
        try:
            # pylint: disable=import-outside-toplevel
            # pylint: disable=unused-import
            from qiskit import Aer
            backend = Aer.get_backend('qasm_simulator')
        except ImportError as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return

        solver = VQEUCCFactory(
            optimizer=SLSQP(maxiter=100),
            expectation=AerPauliExpectation(),
            include_custom=True,
            quantum_instance=QuantumInstance(
                backend=backend,
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res_qasm = calc.solve(self.electronic_structure_problem)

        hamiltonian = self.electronic_structure_problem.second_q_ops()[0]
        qubit_op = self.qubit_converter.map(hamiltonian)

        ansatz = solver.get_solver(self.electronic_structure_problem,
                                   self.qubit_converter).ansatz
        circuit = ansatz.assign_parameters(res_qasm.raw_result.optimal_point)
        mean = calc.evaluate_operators(circuit, qubit_op)

        self.assertAlmostEqual(res_qasm.eigenenergies[0], mean[0].real)

    def _prepare_uccsd_hf(self, qubit_converter):
        initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles,
                                    qubit_converter)
        ansatz = UCCSD(qubit_converter,
                       self.num_particles,
                       self.num_spin_orbitals,
                       initial_state=initial_state)

        return ansatz

    def test_uccsd_hf(self):
        """ uccsd hf test """
        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SLSQP(maxiter=100)
        backend = BasicAer.get_backend('statevector_simulator')
        solver = VQE(ansatz=ansatz,
                     optimizer=optimizer,
                     quantum_instance=QuantumInstance(backend=backend))

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)

        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=6)

    @slow_test
    def test_uccsd_hf_qasm(self):
        """ uccsd hf test with qasm_simulator. """
        qubit_converter = QubitConverter(ParityMapper())
        ansatz = self._prepare_uccsd_hf(qubit_converter)

        backend = BasicAer.get_backend('qasm_simulator')

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(ansatz=ansatz,
                     optimizer=optimizer,
                     expectation=PauliExpectation(),
                     quantum_instance=QuantumInstance(
                         backend=backend,
                         seed_simulator=algorithm_globals.random_seed,
                         seed_transpiler=algorithm_globals.random_seed))

        gsc = GroundStateEigensolver(qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0], -1.138, places=2)

    def test_uccsd_hf_aer_statevector(self):
        """ uccsd hf test with Aer statevector """
        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

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SLSQP(maxiter=100)
        solver = VQE(ansatz=ansatz,
                     optimizer=optimizer,
                     quantum_instance=QuantumInstance(backend=backend))

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=6)

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

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(ansatz=ansatz,
                     optimizer=optimizer,
                     expectation=PauliExpectation(),
                     quantum_instance=QuantumInstance(
                         backend=backend,
                         seed_simulator=algorithm_globals.random_seed,
                         seed_transpiler=algorithm_globals.random_seed))

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0], -1.138, places=2)

    @slow_test
    def test_uccsd_hf_aer_qasm_snapshot(self):
        """ uccsd hf test with Aer qasm_simulator snapshot. """
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
            backend = Aer.get_backend('qasm_simulator')
        except ImportError as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(ansatz=ansatz,
                     optimizer=optimizer,
                     expectation=AerPauliExpectation(),
                     quantum_instance=QuantumInstance(backend=backend))

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=3)