Exemplo n.º 1
0
 def setUp(self):
     """Setup."""
     super().setUp()
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=DeprecationWarning)
         qmol = QMolecule()
     qmol.num_molecular_orbitals = 4
     self.prop = Magnetization.from_legacy_driver_result(qmol)
 def setUp(self):
     """Setup."""
     super().setUp()
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=DeprecationWarning)
         qmol = QMolecule()
     qmol.num_molecular_orbitals = 4
     qmol.num_alpha = 2
     qmol.num_beta = 2
     self.prop = ParticleNumber.from_legacy_driver_result(qmol)
Exemplo n.º 3
0
 def setUp(self):
     super().setUp()
     hdf5_file = self.get_resource_path(
         "test_driver_hdf5_legacy.hdf5",
         "drivers/second_quantization/hdf5d")
     # Using QMolecule directly here to avoid the deprecation on HDF5Driver.run method
     # to be triggered and let it be handled on the method test_convert
     # Those deprecation messages are shown only once and this one could prevent
     # the test_convert one to show if called first.
     molecule = QMolecule(hdf5_file)
     molecule.load()
     warnings.filterwarnings("ignore", category=DeprecationWarning)
     self.driver_result = ElectronicStructureDriverResult.from_legacy_driver_result(
         molecule)
     warnings.filterwarnings("default", category=DeprecationWarning)
def _create_all_aux_operators(q_molecule: QMolecule) -> List[FermionicOp]:
    """Generates the common auxiliary operators out of the given QMolecule.

    Args:
        q_molecule: the QMolecule object for which to generate the operators.

    Returns:
        A list of auxiliary FermionicOps. The first three entries will always correspond to the
        particle number, angular momentum and total magnetization operators. If the QMolecule object
        contained dipole integrals, the list will also contain the X, Y and Z dipole operators.
    """
    aux_second_quantized_ops_list = [
        _create_total_particle_num_op(q_molecule),
        _create_total_ang_momentum_op(q_molecule),
        _create_total_magnetization_op(q_molecule),
    ]

    if q_molecule.has_dipole_integrals():
        x_dipole_operator, y_dipole_operator, z_dipole_operator = _create_dipole_ops(
            q_molecule)
        aux_second_quantized_ops_list += [
            x_dipole_operator,
            y_dipole_operator,
            z_dipole_operator,
        ]
    return aux_second_quantized_ops_list
Exemplo n.º 5
0
class TestSecondQuantizedProperty(QiskitNatureTestCase):
    """General Property base class tests."""

    LegacyDriverResult = Union[QMolecule, WatsonHamiltonian]

    @unpack
    @data(
        (QMolecule(), QMolecule, False),
        (QMolecule(), WatsonHamiltonian, True),
        (WatsonHamiltonian([], -1), QMolecule, True),
        (WatsonHamiltonian([], -1), WatsonHamiltonian, False),
    )
    def test_validate_input_type(
        self, result: LegacyDriverResult, type_: Any, raises_: bool
    ) -> None:
        """Test input type validation."""
        raised = False
        try:
            SecondQuantizedProperty._validate_input_type(result, type_)
        except QiskitNatureError:
            raised = True
        finally:
            self.assertEqual(raised, raises_)
    def transform(self, molecule_data: QMolecule) -> QMolecule:
        """Reduces the given `QMolecule` to a given active space.

        Args:
            molecule_data: the `QMolecule` to be transformed.

        Returns:
            A new `QMolecule` instance.

        Raises:
            QiskitNatureError: If more electrons or orbitals are requested than are available, if an
                               uneven number of inactive electrons remains, or if the number of
                               selected active orbital indices does not match
                               `num_molecular_orbitals`.
        """
        try:
            self._check_configuration()
        except QiskitNatureError as exc:
            raise QiskitNatureError(
                "Incorrect Active-Space configuration.") from exc

        # get molecular orbital coefficients
        mo_coeff_full = (molecule_data.mo_coeff, molecule_data.mo_coeff_b)
        self._beta = mo_coeff_full[1] is not None
        # get molecular orbital occupation numbers
        mo_occ_full = self._extract_mo_occupation_vector(molecule_data)
        self._mo_occ_total = mo_occ_full[0] + mo_occ_full[
            1] if self._beta else mo_occ_full[0]

        active_orbs_idxs, inactive_orbs_idxs = self._determine_active_space(
            molecule_data)

        # split molecular orbitals coefficients into active and inactive parts
        self._mo_coeff_inactive = (mo_coeff_full[0][:, inactive_orbs_idxs],
                                   mo_coeff_full[1][:, inactive_orbs_idxs]
                                   if self._beta else None)
        self._mo_coeff_active = (mo_coeff_full[0][:, active_orbs_idxs],
                                 mo_coeff_full[1][:, active_orbs_idxs]
                                 if self._beta else None)
        self._mo_occ_inactive = (mo_occ_full[0][inactive_orbs_idxs],
                                 mo_occ_full[1][inactive_orbs_idxs]
                                 if self._beta else None)

        self._compute_inactive_density_matrix()

        # construct new QMolecule
        molecule_data_reduced = copy.deepcopy(molecule_data)
        # Energies and orbitals
        molecule_data_reduced.num_molecular_orbitals = self._num_molecular_orbitals
        molecule_data_reduced.num_alpha = self._num_particles[0]
        molecule_data_reduced.num_beta = self._num_particles[1]
        molecule_data_reduced.mo_coeff = self._mo_coeff_active[0]
        molecule_data_reduced.mo_coeff_b = self._mo_coeff_active[1]
        molecule_data_reduced.orbital_energies = molecule_data.orbital_energies[
            active_orbs_idxs]
        if self._beta:
            molecule_data_reduced.orbital_energies_b = \
                molecule_data.orbital_energies_b[active_orbs_idxs]
        molecule_data_reduced.kinetic = None
        molecule_data_reduced.overlap = None

        # reduce electronic energy integrals
        self._reduce_to_active_space(
            molecule_data, molecule_data_reduced, 'energy_shift',
            ('hcore', 'hcore_b'), ('mo_onee_ints', 'mo_onee_ints_b'), 'eri',
            ('mo_eri_ints', 'mo_eri_ints_ba', 'mo_eri_ints_bb'))

        # reduce dipole moment integrals
        if molecule_data.has_dipole_integrals():
            self._reduce_to_active_space(molecule_data, molecule_data_reduced,
                                         'x_dip_energy_shift',
                                         ('x_dip_ints', None),
                                         ('x_dip_mo_ints', 'x_dip_mo_ints_b'))
            self._reduce_to_active_space(molecule_data, molecule_data_reduced,
                                         'y_dip_energy_shift',
                                         ('y_dip_ints', None),
                                         ('y_dip_mo_ints', 'y_dip_mo_ints_b'))
            self._reduce_to_active_space(molecule_data, molecule_data_reduced,
                                         'z_dip_energy_shift',
                                         ('z_dip_ints', None),
                                         ('z_dip_mo_ints', 'z_dip_mo_ints_b'))

        return molecule_data_reduced
    def test_minimal_active_space(self):
        """Test a minimal active space manually."""
        driver = HDF5Driver(hdf5_input=self.get_resource_path(
            "H2_631g.hdf5", "transformers/second_quantization/electronic"))
        q_molecule = driver.run()

        trafo = ActiveSpaceTransformer(num_electrons=2,
                                       num_molecular_orbitals=2)
        q_molecule_reduced = trafo.transform(q_molecule)

        expected = QMolecule()
        expected.mo_onee_ints = np.asarray([[-1.24943841, 0.0],
                                            [0.0, -0.547816138]])
        expected.mo_eri_ints = np.asarray([
            [
                [[0.652098466, 0.0], [0.0, 0.433536565]],
                [[0.0, 0.0794483182], [0.0794483182, 0.0]],
            ],
            [
                [[0.0, 0.0794483182], [0.0794483182, 0.0]],
                [[0.433536565, 0.0], [0.0, 0.385524695]],
            ],
        ])

        expected.x_dip_mo_ints = np.zeros((2, 2))
        expected.y_dip_mo_ints = np.zeros((2, 2))
        expected.z_dip_mo_ints = np.asarray([[0.69447435, -1.01418298],
                                             [-1.01418298, 0.69447435]])

        expected.energy_shift["ActiveSpaceTransformer"] = 0.0
        expected.x_dip_energy_shift["ActiveSpaceTransformer"] = 0.0
        expected.y_dip_energy_shift["ActiveSpaceTransformer"] = 0.0
        expected.z_dip_energy_shift["ActiveSpaceTransformer"] = 0.0

        self.assertQMolecule(q_molecule_reduced, expected)
    def test_arbitrary_active_orbitals(self):
        """Test manual selection of active orbital indices."""
        driver = HDF5Driver(hdf5_input=self.get_resource_path(
            "H2_631g.hdf5", "transformers/second_quantization/electronic"))
        q_molecule = driver.run()

        trafo = ActiveSpaceTransformer(num_electrons=2,
                                       num_molecular_orbitals=2,
                                       active_orbitals=[0, 2])
        q_molecule_reduced = trafo.transform(q_molecule)

        expected = QMolecule()
        expected.mo_onee_ints = np.asarray([[-1.24943841, -0.16790838],
                                            [-0.16790838, -0.18307469]])
        expected.mo_eri_ints = np.asarray([
            [
                [[0.65209847, 0.16790822], [0.16790822, 0.53250905]],
                [[0.16790822, 0.10962908], [0.10962908, 0.11981429]],
            ],
            [
                [[0.16790822, 0.10962908], [0.10962908, 0.11981429]],
                [[0.53250905, 0.11981429], [0.11981429, 0.46345617]],
            ],
        ])

        expected.x_dip_mo_ints = np.zeros((2, 2))
        expected.y_dip_mo_ints = np.zeros((2, 2))
        expected.z_dip_mo_ints = np.asarray([[0.69447435, 0.0],
                                             [0.0, 0.69447435]])

        expected.energy_shift["ActiveSpaceTransformer"] = 0.0
        expected.x_dip_energy_shift["ActiveSpaceTransformer"] = 0.0
        expected.y_dip_energy_shift["ActiveSpaceTransformer"] = 0.0
        expected.z_dip_energy_shift["ActiveSpaceTransformer"] = 0.0

        self.assertQMolecule(q_molecule_reduced, expected)