def test_convert(self): """Test the legacy-conversion method.""" legacy_file_path = self.get_resource_path( "test_driver_hdf5_legacy.hdf5", "drivers/second_quantization/hdf5d") with self.subTest("replace=True"): with TemporaryDirectory() as tmp_dir: tmp_file = Path(tmp_dir) / "tmp.hdf5" shutil.copy(legacy_file_path, tmp_file) driver = HDF5Driver(tmp_file) # replacing file won't trigger deprecation on run driver.convert(replace=True) msg_mol_ref = ( "The HDF5Driver.run with legacy HDF5 file method is deprecated as of version 0.4.0 " "and will be removed no sooner than 3 months after the release " ". Your HDF5 file contains the legacy QMolecule object! You should " "consider converting it to the new property framework. See also HDF5Driver.convert." ) with self.subTest("replace=False"): with TemporaryDirectory() as tmp_dir: tmp_file = Path(tmp_dir) / "tmp.hdf5" new_file_name = Path(tmp_dir) / "tmp_new.hdf5" shutil.copy(legacy_file_path, tmp_file) driver = HDF5Driver(tmp_file) # not replacing file will trigger deprecation on run driver.convert(replace=False) with warnings.catch_warnings(record=True) as c_m: warnings.simplefilter("always") driver.run() self.assertEqual(str(c_m[0].message), msg_mol_ref) # using new file won't trigger deprecation HDF5Driver(new_file_name).run()
def setUp(self): super().setUp() driver = HDF5Driver(hdf5_input=self.get_resource_path( "test_driver_hdf5.hdf5", "drivers/second_quantization/hdf5d")) temp_qmolecule = driver.run() file, self.save_file = tempfile.mkstemp(suffix=".hdf5") os.close(file) # pylint: disable=no-member temp_qmolecule.save(self.save_file) # Tests are run on self.qmolecule which is from new saved HDF5 file # so save is tested based on getting expected values as per original driver = HDF5Driver(hdf5_input=self.save_file) self.qmolecule = driver.run()
def test_convert(self): """Test the legacy-conversion method.""" legacy_file_path = self.get_resource_path( "test_driver_hdf5_legacy.hdf5", "drivers/second_quantization/hdf5d") with self.subTest("replace=True"): # pylint: disable=consider-using-with tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".hdf5") tmp_file.close() os.unlink(tmp_file.name) shutil.copy(legacy_file_path, tmp_file.name) try: driver = HDF5Driver(tmp_file.name) # replacing file won't trigger deprecation on run driver.convert(replace=True) driver.run() finally: os.unlink(tmp_file.name) msg_mol_ref = ( "The HDF5Driver.run with legacy HDF5 file method is deprecated as of version 0.4.0 " "and will be removed no sooner than 3 months after the release " ". Your HDF5 file contains the legacy QMolecule object! You should " "consider converting it to the new property framework. See also HDF5Driver.convert." ) with self.subTest("replace=False"): # pylint: disable=consider-using-with tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".hdf5") tmp_file.close() new_file_name = pathlib.Path(tmp_file.name).with_name( str(pathlib.Path(tmp_file.name).stem) + "_new.hdf5") os.unlink(tmp_file.name) shutil.copy(legacy_file_path, tmp_file.name) try: driver = HDF5Driver(tmp_file.name) # not replacing file will trigger deprecation on run driver.convert(replace=False) with warnings.catch_warnings(record=True) as c_m: warnings.simplefilter("always") driver.run() self.assertEqual(str(c_m[0].message), msg_mol_ref) # using new file won't trigger deprecation HDF5Driver(new_file_name).run() finally: os.unlink(tmp_file.name) os.unlink(new_file_name)
def test_unpaired_electron_active_space(self): """Test an active space with an unpaired electron.""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "BeH_sto3g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() trafo = ActiveSpaceTransformer(num_electrons=(2, 1), num_molecular_orbitals=3) driver_result_reduced = trafo.transform(driver_result) expected = HDF5Driver(hdf5_input=self.get_resource_path( "BeH_sto3g_reduced.hdf5", "transformers/second_quantization/electronic")).run() self.assertDriverResult(driver_result_reduced, expected)
def test_build_fermionic_op_from_ints_one(self): """Tests that the correct FermionicOp is built from 1-body integrals.""" expected_num_of_terms_ferm_op = 16 expected_fermionic_op_path = self.get_resource_path( "H2_631g_ferm_op_one_int", "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" ) ) driver_result = driver.run() electronic_energy = cast(ElectronicEnergy, driver_result.get_property(ElectronicEnergy)) reduced = ElectronicEnergy( [electronic_energy.get_electronic_integral(ElectronicBasis.MO, 1)] ) fermionic_op = reduced.second_q_ops()[0] with self.subTest("Check type of fermionic operator"): assert isinstance(fermionic_op, FermionicOp) with self.subTest("Check expected number of terms in a fermionic operator."): assert len(fermionic_op) == expected_num_of_terms_ferm_op with self.subTest("Check expected content of a fermionic operator."): assert all( s[0] == t[0] and np.isclose(s[1], t[1]) for s, t in zip(fermionic_op.to_list(), expected_fermionic_op) )
def test_no_deep_copy(self): """Test that objects are not being deeply copied. This is a regression test against the fix applied by https://github.com/Qiskit/qiskit-nature/pull/659 """ driver = HDF5Driver(hdf5_input=self.get_resource_path( "H2_631g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() trafo = ActiveSpaceTransformer(num_electrons=2, num_molecular_orbitals=2) driver_result_reduced = trafo.transform(driver_result) active_transform = np.asarray([ [0.32774803333032304, 0.12166492852424596], [0.27055282555225113, 1.7276386116201712], [0.32774803333032265, -0.12166492852424832], [0.2705528255522547, -1.727638611620168], ]) self.assertTrue( np.allclose( driver_result_reduced.get_property( "ElectronicBasisTransform").coeff_alpha, active_transform, ))
def test_freeze_core(self): """Test the `freeze_core` convenience argument.""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "LiH_sto3g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() trafo = FreezeCoreTransformer(freeze_core=True) driver_result_reduced = trafo.transform(driver_result) expected = HDF5Driver(hdf5_input=self.get_resource_path( "LiH_sto3g_reduced.hdf5", "transformers/second_quantization/electronic")).run() self.assertDriverResult(driver_result_reduced, expected, dict_key="FreezeCoreTransformer")
def test_no_freeze_core(self): """Test the disabled `freeze_core` convenience argument. Regression test against https://github.com/Qiskit/qiskit-nature/issues/652 """ driver = HDF5Driver(hdf5_input=self.get_resource_path( "LiH_sto3g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() trafo = FreezeCoreTransformer(freeze_core=False) driver_result_reduced = trafo.transform(driver_result) electronic_energy = driver_result_reduced.get_property( "ElectronicEnergy") electronic_energy_exp = driver_result.get_property("ElectronicEnergy") with self.subTest("MO 1-electron integrals"): np.testing.assert_array_almost_equal( electronic_energy.get_electronic_integral( ElectronicBasis.MO, 1).to_spin(), electronic_energy_exp.get_electronic_integral( ElectronicBasis.MO, 1).to_spin(), ) with self.subTest("MO 2-electron integrals"): np.testing.assert_array_almost_equal( electronic_energy.get_electronic_integral( ElectronicBasis.MO, 2).to_spin(), electronic_energy_exp.get_electronic_integral( ElectronicBasis.MO, 2).to_spin(), ) with self.subTest("Inactive energy"): self.assertAlmostEqual( electronic_energy._shift["FreezeCoreTransformer"], 0.0)
def test_freeze_core_with_remove_orbitals(self): """Test the `freeze_core` convenience argument in combination with `remove_orbitals`.""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "BeH_sto3g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() trafo = FreezeCoreTransformer(freeze_core=True, remove_orbitals=[4, 5]) driver_result_reduced = trafo.transform(driver_result) expected = HDF5Driver(hdf5_input=self.get_resource_path( "BeH_sto3g_reduced.hdf5", "transformers/second_quantization/electronic")).run() expected.get_property("ParticleNumber")._num_spin_orbitals = 6 self.assertDriverResult(driver_result_reduced, expected, dict_key="FreezeCoreTransformer")
def setUp(self): """Setup.""" super().setUp() driver = HDF5Driver(hdf5_input=self.get_resource_path( "test_driver_hdf5.hdf5", "drivers/second_quantization/hdf5d")) self.prop = cast(ElectronicEnergy, driver.run().get_property(ElectronicEnergy)) self.prop.get_electronic_integral(ElectronicBasis.MO, 1).set_truncation(2)
def setUp(self) -> None: """Setup expected object.""" super().setUp() driver = HDF5Driver( self.get_resource_path( "BeH_sto3g_reduced.hdf5", "transformers/second_quantization/electronic")) self.expected = driver.run()
def setUp(self): """Setup.""" super().setUp() driver = HDF5Driver( hdf5_input=self.get_resource_path( "test_driver_hdf5.hdf5", "drivers/second_quantization/hdf5d" ) ) self.prop = driver.run().get_property(ElectronicDipoleMoment)
def setUp(self): super().setUp() driver = HDF5Driver(hdf5_input=self.get_resource_path( "test_driver_hdf5.hdf5", "drivers/second_quantization/hdf5d")) self.driver_result = driver.run() particle_number = cast(ParticleNumber, self.driver_result.get_property(ParticleNumber)) self.num_particles = (particle_number.num_alpha, particle_number.num_beta) self.h2_op = self.driver_result.second_q_ops()["ElectronicEnergy"]
def test_error_raising(self, num_electrons, num_molecular_orbitals, active_orbitals, message): """Test errors are being raised in certain scenarios.""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "H2_sto3g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() with self.assertRaises(QiskitNatureError, msg=message): ActiveSpaceTransformer( num_electrons=num_electrons, num_molecular_orbitals=num_molecular_orbitals, active_orbitals=active_orbitals, ).transform(driver_result)
def test_mapping(self): """Test mapping to qubit operator""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "test_driver_hdf5.hdf5", "drivers/second_quantization/hdf5d")) driver_result = driver.run() fermionic_op = driver_result.second_q_ops()[0] mapper = JordanWignerMapper() qubit_op = mapper.map(fermionic_op) # 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, TestJordanWignerMapper.REF_H2)
def test_full_active_space(self, kwargs): """test that transformer has no effect when all orbitals are active.""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "H2_sto3g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() driver_result.get_property( "ElectronicEnergy")._shift["ActiveSpaceTransformer"] = 0.0 for prop in iter(driver_result.get_property("ElectronicDipoleMoment")): prop._shift["ActiveSpaceTransformer"] = 0.0 trafo = ActiveSpaceTransformer(**kwargs) driver_result_reduced = trafo.transform(driver_result) self.assertDriverResult(driver_result_reduced, driver_result)
def test_active_space_for_q_molecule_v2(self): """Test based on QMolecule v2 (mo_occ not available).""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "H2_sto3g_v2.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() driver_result.get_property( "ElectronicEnergy")._shift["ActiveSpaceTransformer"] = 0.0 for prop in iter(driver_result.get_property("ElectronicDipoleMoment")): prop._shift["ActiveSpaceTransformer"] = 0.0 trafo = ActiveSpaceTransformer(num_electrons=2, num_molecular_orbitals=2) driver_result_reduced = trafo.transform(driver_result) self.assertDriverResult(driver_result_reduced, driver_result)
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_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/second_quantization/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()[problem.main_property_name], self.num_particles, sector_locator=problem.symmetry_sector_locator, ) self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)
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/second_quantization/electronic")) 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[ 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_excitation_preserving(self): """Test the excitation preserving wavefunction on a chemistry example.""" driver = HDF5Driver( self.get_resource_path("test_driver_hdf5.hdf5", "drivers/second_quantization/hdf5d")) converter = QubitConverter(ParityMapper()) problem = ElectronicStructureProblem(driver) _ = problem.second_q_ops() particle_number = cast( ParticleNumber, problem.grouped_property_transformed.get_property(ParticleNumber)) num_particles = (particle_number.num_alpha, particle_number.num_beta) num_spin_orbitals = particle_number.num_spin_orbitals 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_full_active_space(self, kwargs): """Test that transformer has no effect when all orbitals are active.""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "H2_sto3g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() # The references which we compare too were produced by the `ActiveSpaceTransformer` and, # thus, the key here needs to stay the same as in that test case. driver_result.get_property( "ElectronicEnergy")._shift["ActiveSpaceTransformer"] = 0.0 for prop in iter(driver_result.get_property("ElectronicDipoleMoment")): prop._shift["ActiveSpaceTransformer"] = 0.0 trafo = FreezeCoreTransformer(**kwargs) driver_result_reduced = trafo.transform(driver_result) self.assertDriverResult(driver_result_reduced, driver_result, dict_key="FreezeCoreTransformer")
def setUp(self): super().setUp() algorithm_globals.random_seed = 42 driver = HDF5Driver(hdf5_input=self.get_resource_path( "test_driver_hdf5.hdf5", "drivers/second_quantization/hdf5d")) problem = ElectronicStructureProblem(driver) second_q_ops = [problem.second_q_ops()[problem.main_property_name]] converter = QubitConverter(mapper=ParityMapper(), two_qubit_reduction=True) num_particles = ( problem.grouped_property_transformed.get_property( "ParticleNumber").num_alpha, problem.grouped_property_transformed.get_property( "ParticleNumber").num_beta, ) self.qubit_op = converter.convert(second_q_ops[0], num_particles) self.aux_ops = converter.convert_match(second_q_ops[1:]) self.reference_energy = -1.857275027031588
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_numpy_integer(self): """Tests that numpy integer objects do not cause issues in `isinstance` checks. This is a regression test against the fix applied by https://github.com/Qiskit/qiskit-nature/pull/712 """ driver = HDF5Driver(hdf5_input=self.get_resource_path( "H2_631g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() particle_number = driver_result.get_property("ParticleNumber") particle_number.num_alpha = np.int64(particle_number.num_alpha) particle_number.num_beta = np.int64(particle_number.num_beta) particle_number.num_spin_orbitals = np.int64( particle_number.num_spin_orbitals) driver_result.add_property(particle_number) trafo = ActiveSpaceTransformer( num_electrons=particle_number.num_particles, num_molecular_orbitals=2) _ = trafo.transform(driver_result)
def test_tuple_num_electrons_with_manual_orbitals(self): """Regression test against https://github.com/Qiskit/qiskit-nature/issues/434.""" driver = HDF5Driver(hdf5_input=self.get_resource_path( "H2_631g.hdf5", "transformers/second_quantization/electronic")) driver_result = driver.run() trafo = ActiveSpaceTransformer( num_electrons=(1, 1), num_molecular_orbitals=2, active_orbitals=[0, 1], ) driver_result_reduced = trafo.transform(driver_result) expected = ElectronicStructureDriverResult() expected.add_property( ElectronicEnergy( [ OneBodyElectronicIntegrals( ElectronicBasis.MO, (np.asarray([[-1.24943841, 0.0], [0.0, -0.547816138] ]), None), ), TwoBodyElectronicIntegrals( ElectronicBasis.MO, ( 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]], ], ]), None, None, None, ), ), ], energy_shift={"ActiveSpaceTransformer": 0.0}, )) expected.add_property( ElectronicDipoleMoment([ DipoleMoment( "x", [ OneBodyElectronicIntegrals(ElectronicBasis.MO, (np.zeros((2, 2)), None)) ], shift={"ActiveSpaceTransformer": 0.0}, ), DipoleMoment( "y", [ OneBodyElectronicIntegrals(ElectronicBasis.MO, (np.zeros((2, 2)), None)) ], shift={"ActiveSpaceTransformer": 0.0}, ), DipoleMoment( "z", [ OneBodyElectronicIntegrals( ElectronicBasis.MO, ( np.asarray([[0.69447435, -1.01418298], [-1.01418298, 0.69447435]]), None, ), ) ], shift={"ActiveSpaceTransformer": 0.0}, ), ])) self.assertDriverResult(driver_result_reduced, expected)
def setUp(self): super().setUp() driver = HDF5Driver(hdf5_input=self.get_resource_path( "test_driver_hdf5.hdf5", "drivers/second_quantization/hdf5d")) self.driver_result = driver.run()
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")) driver_result = driver.run() trafo = ActiveSpaceTransformer(num_electrons=2, num_molecular_orbitals=2, active_orbitals=[0, 2]) driver_result_reduced = trafo.transform(driver_result) expected = ElectronicStructureDriverResult() expected.add_property( ElectronicEnergy( [ OneBodyElectronicIntegrals( ElectronicBasis.MO, ( np.asarray([[-1.24943841, -0.16790838], [-0.16790838, -0.18307469]]), None, ), ), TwoBodyElectronicIntegrals( ElectronicBasis.MO, ( 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]], ], ]), None, None, None, ), ), ], energy_shift={"ActiveSpaceTransformer": 0.0}, )) expected.add_property( ElectronicDipoleMoment([ DipoleMoment( "x", [ OneBodyElectronicIntegrals(ElectronicBasis.MO, (np.zeros((2, 2)), None)) ], shift={"ActiveSpaceTransformer": 0.0}, ), DipoleMoment( "y", [ OneBodyElectronicIntegrals(ElectronicBasis.MO, (np.zeros((2, 2)), None)) ], shift={"ActiveSpaceTransformer": 0.0}, ), DipoleMoment( "z", [ OneBodyElectronicIntegrals( ElectronicBasis.MO, (np.asarray([[0.69447435, 0.0], [0.0, 0.69447435] ]), None), ) ], shift={"ActiveSpaceTransformer": 0.0}, ), ])) self.assertDriverResult(driver_result_reduced, expected)