def test_z2_symmetry(self):
        """Test mapping to qubit operator with z2 symmetry tapering"""
        z2_sector = [-1, 1, -1]

        def finder(z2_symmetries: Z2Symmetries) -> Optional[List[int]]:
            return z2_sector if not z2_symmetries.is_empty() else None

        def find_none(_z2_symmetries: Z2Symmetries) -> Optional[List[int]]:
            return None

        mapper = JordanWignerMapper()
        qubit_conv = QubitConverter(mapper, z2symmetry_reduction="auto")

        with self.subTest(
                "Locator returns None, should be untapered operator"):
            qubit_op = qubit_conv.convert(self.h2_op, sector_locator=find_none)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        qubit_op = qubit_conv.convert(self.h2_op, sector_locator=finder)
        self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)
            self.assertIsNone(qubit_conv.num_particles)
            self.assertListEqual(qubit_conv.z2symmetries.tapering_values,
                                 z2_sector)
    def test_two_qubit_reduction_and_z2_symmetry(self):
        """Test mapping to qubit operator with z2 symmetry tapering and two qubit reduction"""
        z2_sector = [-1]

        def cb_finder(z2_symmetries: Z2Symmetries,
                      converter: QubitConverter) -> Optional[List[int]]:
            return z2_sector if not z2_symmetries.is_empty() else None

        mapper = ParityMapper()
        qubit_conv = QubitConverter(mapper,
                                    two_qubit_reduction=True,
                                    z2symmetry_reduction="auto")
        qubit_op = qubit_conv.convert(self.h2_op,
                                      self.num_particles,
                                      sector_locator=cb_finder)
        self.assertEqual(qubit_op,
                         TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)
        self.assertEqual(qubit_conv.num_particles, self.num_particles)
        self.assertListEqual(qubit_conv.z2symmetries.tapering_values,
                             z2_sector)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)
            self.assertListEqual(qubit_conv.z2symmetries.tapering_values,
                                 z2_sector)

        with self.subTest("Change setting"):
            qubit_conv.z2symmetry_reduction = [1]
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertNotEqual(
                qubit_op, TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)
            qubit_conv.z2symmetry_reduction = [-1]
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)

        with self.subTest("Specify sector upfront"):
            qubit_conv = QubitConverter(mapper,
                                        two_qubit_reduction=True,
                                        z2symmetry_reduction=z2_sector)
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)

        with self.subTest("Specify sector upfront, but invalid content"):
            with self.assertRaises(ValueError):
                _ = QubitConverter(mapper,
                                   two_qubit_reduction=True,
                                   z2symmetry_reduction=[5])

        with self.subTest("Specify sector upfront, but invalid length"):
            qubit_conv = QubitConverter(mapper,
                                        two_qubit_reduction=True,
                                        z2symmetry_reduction=[-1, 1])
            with self.assertRaises(QiskitNatureError):
                _ = qubit_conv.convert(self.h2_op, self.num_particles)
 def test_fermionic_gaussian_state(self):
     """Test preparing fermionic Gaussian states."""
     n_orbitals = 5
     converter = QubitConverter(JordanWignerMapper())
     quad_ham = random_quadratic_hamiltonian(n_orbitals, seed=5957)
     (
         transformation_matrix,
         orbital_energies,
         transformed_constant,
     ) = quad_ham.diagonalizing_bogoliubov_transform()
     fermionic_op = quad_ham.to_fermionic_op()
     qubit_op = converter.convert(fermionic_op)
     matrix = qubit_op.to_matrix()
     occupied_orbitals_lists = [
         [],
         [0],
         [3],
         [0, 1],
         [2, 4],
         [1, 3, 4],
         range(n_orbitals),
     ]
     for occupied_orbitals in occupied_orbitals_lists:
         circuit = FermionicGaussianState(transformation_matrix,
                                          occupied_orbitals,
                                          qubit_converter=converter)
         final_state = np.array(Statevector(circuit))
         eig = np.sum(
             orbital_energies[occupied_orbitals]) + transformed_constant
         np.testing.assert_allclose(matrix @ final_state,
                                    eig * final_state,
                                    atol=1e-7)
 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_mapping_basic(self):
        """Test mapping to qubit operator"""
        mapper = JordanWignerMapper()
        qubit_conv = QubitConverter(mapper)
        qubit_op = qubit_conv.convert(self.h2_op)

        self.assertIsInstance(qubit_op, PauliSumOp)

        # Note: The PauliSumOp equals, as used in the test below, use the equals of the
        #       SparsePauliOp which in turn uses np.allclose() to determine equality of
        #       coeffs. So the reference operator above will be matched on that basis so
        #       we don't need to worry about tiny precision changes for any reason.

        self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        with self.subTest("Re-use test"):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        with self.subTest("Re-use with different mapper"):
            qubit_conv.mapper = ParityMapper()
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)

        with self.subTest(
                "Set two qubit reduction - no effect without num particles"):
            qubit_conv.two_qubit_reduction = True
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)

        with self.subTest("Force match set num particles"):
            qubit_conv.force_match(self.num_particles)
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
 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])
    def test_two_qubit_reduction(self):
        """Test mapping to qubit operator with two qubit reduction"""
        mapper = ParityMapper()
        qubit_conv = QubitConverter(mapper, two_qubit_reduction=True)

        with self.subTest(
                "Two qubit reduction ignored as no num particles given"):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
            self.assertIsNone(qubit_conv.num_particles)

        with self.subTest("Two qubit reduction, num particles given"):
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)

        with self.subTest("State is reset (Num particles lost)"):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
            self.assertIsNone(qubit_conv.num_particles)

        with self.subTest("Num particles given again"):
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)

        with self.subTest("Set for no two qubit reduction"):
            qubit_conv.two_qubit_reduction = False
            self.assertFalse(qubit_conv.two_qubit_reduction)
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
    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_two_qubit_reduction(self):
        """Test mapping to qubit operator with two qubit reduction"""
        mapper = ParityMapper()
        qubit_conv = QubitConverter(mapper, two_qubit_reduction=True)

        with self.subTest(
                "Two qubit reduction ignored as no num particles given"):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
            self.assertIsNone(qubit_conv.num_particles)

        with self.subTest("Two qubit reduction, num particles given"):
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)

        with self.subTest("State is reset (Num particles lost)"):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
            self.assertIsNone(qubit_conv.num_particles)

        with self.subTest("Num particles given again"):
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)

        with self.subTest("Set for no two qubit reduction"):
            qubit_conv.two_qubit_reduction = False
            self.assertFalse(qubit_conv.two_qubit_reduction)
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)

        # Regression test against https://github.com/Qiskit/qiskit-nature/issues/271
        with self.subTest(
                "Two qubit reduction skipped when operator too small"):
            qubit_conv.two_qubit_reduction = True
            small_op = FermionicOp([("N_0", 1.0), ("E_1", 1.0)],
                                   register_length=2,
                                   display_format="sparse")
            expected_op = 1.0 * (I ^ I) - 0.5 * (I ^ Z) + 0.5 * (Z ^ Z)
            with contextlib.redirect_stderr(io.StringIO()) as out:
                qubit_op = qubit_conv.convert(small_op,
                                              num_particles=self.num_particles)
            self.assertEqual(qubit_op, expected_op)
            self.assertTrue(out.getvalue().strip().startswith(
                "The original qubit operator only contains 2 qubits! "
                "Skipping the requested two-qubit reduction!"))
 def test_slater_determinant(self):
     """Test preparing Slater determinants."""
     n_orbitals = 5
     converter = QubitConverter(JordanWignerMapper())
     quad_ham = random_quadratic_hamiltonian(n_orbitals,
                                             num_conserving=True,
                                             seed=8839)
     (
         transformation_matrix,
         orbital_energies,
         transformed_constant,
     ) = quad_ham.diagonalizing_bogoliubov_transform()
     fermionic_op = quad_ham.to_fermionic_op()
     qubit_op = converter.convert(fermionic_op)
     matrix = qubit_op.to_matrix()
     for n_particles in range(n_orbitals + 1):
         circuit = SlaterDeterminant(transformation_matrix[:n_particles],
                                     qubit_converter=converter)
         final_state = np.array(Statevector(circuit))
         eig = np.sum(orbital_energies[:n_particles]) + transformed_constant
         np.testing.assert_allclose(matrix @ final_state,
                                    eig * final_state,
                                    atol=1e-7)
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
num_spin_orbitals = 2 * problem.molecule_data.num_molecular_orbitals

# setup the classical optimizer for VQE
from qiskit.algorithms.optimizers import L_BFGS_B

optimizer = L_BFGS_B()

# setup the mapper and qubit converter
from qiskit_nature.mappers.second_quantization import ParityMapper
from qiskit_nature.converters.second_quantization import QubitConverter

mapper = ParityMapper()
converter = QubitConverter(mapper=mapper, two_qubit_reduction=True)

# map to qubit operators
qubit_op = converter.convert(main_op, num_particles=num_particles)

# setup the initial state for the ansatz
from qiskit_nature.circuit.library import HartreeFock

init_state = HartreeFock(num_spin_orbitals, num_particles, converter)

# setup the ansatz for VQE
from qiskit.circuit.library import TwoLocal

ansatz = TwoLocal(num_spin_orbitals, ['ry', 'rz'], 'cz')

# add the initial state
ansatz.compose(init_state, front=True)

# set the backend for the quantum computation
    def test_readme_sample(self):
        """ readme sample test """

        # pylint: disable=import-outside-toplevel,redefined-builtin

        def print(*args):
            """ overloads print to log values """
            if args:
                self.log.debug(args[0], *args[1:])

        # --- Exact copy of sample code ----------------------------------------

        from qiskit_nature.drivers import PySCFDriver, UnitsType
        from qiskit_nature.problems.second_quantization.electronic import ElectronicStructureProblem

        # Use PySCF, a classical computational chemistry software
        # package, to compute the one-body and two-body integrals in
        # electronic-orbital basis, necessary to form the Fermionic operator
        driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735',
                             unit=UnitsType.ANGSTROM,
                             basis='sto3g')
        problem = ElectronicStructureProblem(driver)

        # generate the second-quantized operators
        second_q_ops = problem.second_q_ops()
        main_op = second_q_ops[0]

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

        num_spin_orbitals = 2 * problem.molecule_data.num_molecular_orbitals

        # setup the classical optimizer for VQE
        from qiskit.algorithms.optimizers import L_BFGS_B
        optimizer = L_BFGS_B()

        # setup the mapper and qubit converter
        from qiskit_nature.mappers.second_quantization import ParityMapper
        from qiskit_nature.converters.second_quantization import QubitConverter
        mapper = ParityMapper()
        converter = QubitConverter(mapper=mapper, two_qubit_reduction=True)

        # map to qubit operators
        qubit_op = converter.convert(main_op, num_particles=num_particles)

        # setup the initial state for the ansatz
        from qiskit_nature.circuit.library import HartreeFock
        init_state = HartreeFock(num_spin_orbitals, num_particles, converter)

        # setup the ansatz for VQE
        from qiskit.circuit.library import TwoLocal
        ansatz = TwoLocal(num_spin_orbitals, ['ry', 'rz'], 'cz')

        # add the initial state
        ansatz.compose(init_state, front=True)

        # set the backend for the quantum computation
        from qiskit import Aer
        backend = Aer.get_backend('statevector_simulator')

        # setup and run VQE
        from qiskit.algorithms import VQE
        algorithm = VQE(ansatz, optimizer=optimizer, quantum_instance=backend)

        result = algorithm.compute_minimum_eigenvalue(qubit_op)
        print(result.eigenvalue.real)

        electronic_structure_result = problem.interpret(result)
        print(electronic_structure_result)

        # ----------------------------------------------------------------------

        self.assertAlmostEqual(result.eigenvalue.real,
                               -1.8572750301938803,
                               places=6)