def test_z2_symmetry(self): """Test mapping to qubit operator with z2 symmetry tapering""" z2_sector = [-1, 1, -1] def cb_finder(z2_symmetries: Z2Symmetries, converter: QubitConverter) -> Optional[List[int]]: return z2_sector if not z2_symmetries.is_empty() else None def cb_find_none(_z2_symmetries: Z2Symmetries, converter: QubitConverter) -> 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=cb_find_none) self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW) qubit_op = qubit_conv.convert(self.h2_op, sector_locator=cb_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_qubits_2_py_h2(self): """qubits 2 py h2 test""" num_particles = (1, 1) converter = QubitConverter(ParityMapper(), two_qubit_reduction=True) converter.force_match(num_particles=num_particles) state = HartreeFock(4, num_particles, converter) ref = QuantumCircuit(2) ref.x(0) self.assertEqual(state, ref)
def test_hf_bitstring_mapped(self): """Mapped bitstring test for water""" # Original driver config when creating operator that resulted in symmetries coded # below. The sector [1, -1] is the correct ground sector. # PySCFDriver( # atom="O 0.0000 0.0000 0.1173; H 0.0000 0.07572 -0.4692;H 0.0000 -0.07572 -0.4692", # unit=UnitsType.ANGSTROM, # charge=0, # spin=0, # basis='sto-3g', # hf_method=HFMethodType.RHF) num_spin_orbitals = 14 num_particles = (5, 5) converter = QubitConverter(ParityMapper(), two_qubit_reduction=True) z2symmetries = Z2Symmetries( symmetries=[Pauli("IZZIIIIZZIII"), Pauli("ZZIZIIZZIZII")], sq_paulis=[Pauli("IIIIIIIIXIII"), Pauli("IIIIIIIIIXII")], sq_list=[3, 2], tapering_values=[1, -1], ) with self.subTest("Matched bitsring creation"): converter.force_match(num_particles=num_particles, z2symmetries=z2symmetries) bitstr = hartree_fock_bitstring_mapped( num_spin_orbitals=num_spin_orbitals, num_particles=num_particles, qubit_converter=converter, ) ref_matched = [ True, False, True, True, False, True, False, True, False, False ] self.assertListEqual(bitstr, ref_matched) with self.subTest("Bitsring creation with no tapering"): bitstr = hartree_fock_bitstring_mapped( num_spin_orbitals=num_spin_orbitals, num_particles=num_particles, qubit_converter=converter, match_convert=False, ) ref_notaper = [ True, False, True, False, True, True, False, True, False, True, False, False, ] self.assertListEqual(bitstr, ref_notaper)
def test_uvcc_vscf(self): """uvcc vscf test""" co2_2modes_2modals_2body = [ [ [[[0, 0, 0]], 320.8467332810141], [[[0, 1, 1]], 1760.878530705873], [[[1, 0, 0]], 342.8218290247543], [[[1, 1, 1]], 1032.396323618631], ], [ [[[0, 0, 0], [1, 0, 0]], -57.34003649795117], [[[0, 0, 1], [1, 0, 0]], -56.33205925807966], [[[0, 1, 0], [1, 0, 0]], -56.33205925807966], [[[0, 1, 1], [1, 0, 0]], -60.13032761856809], [[[0, 0, 0], [1, 0, 1]], -65.09576309934431], [[[0, 0, 1], [1, 0, 1]], -62.2363839133389], [[[0, 1, 0], [1, 0, 1]], -62.2363839133389], [[[0, 1, 1], [1, 0, 1]], -121.5533969109279], [[[0, 0, 0], [1, 1, 0]], -65.09576309934431], [[[0, 0, 1], [1, 1, 0]], -62.2363839133389], [[[0, 1, 0], [1, 1, 0]], -62.2363839133389], [[[0, 1, 1], [1, 1, 0]], -121.5533969109279], [[[0, 0, 0], [1, 1, 1]], -170.744837386338], [[[0, 0, 1], [1, 1, 1]], -167.7433236025723], [[[0, 1, 0], [1, 1, 1]], -167.7433236025723], [[[0, 1, 1], [1, 1, 1]], -179.0536532281924], ], ] num_modes = 2 num_modals = [2, 2] vibrational_op_labels = _create_labels(co2_2modes_2modals_2body) vibr_op = VibrationalOp(vibrational_op_labels, num_modes, num_modals) converter = QubitConverter(DirectMapper()) qubit_op = converter.convert_match(vibr_op) init_state = VSCF(num_modals) uvcc_ansatz = UVCC(converter, num_modals, "sd", initial_state=init_state) q_instance = QuantumInstance( BasicAer.get_backend("statevector_simulator"), seed_transpiler=90, seed_simulator=12, ) optimizer = COBYLA(maxiter=1000) algo = VQE(uvcc_ansatz, optimizer=optimizer, quantum_instance=q_instance) vqe_result = algo.compute_minimum_eigenvalue(qubit_op) energy = vqe_result.optimal_value self.assertAlmostEqual(energy, self.reference_energy, places=4)
def test_ucc_ansatz(self, excitations, num_modals, expect): """Tests the UVCC Ansatz.""" converter = QubitConverter(DirectMapper()) ansatz = UVCC(qubit_converter=converter, num_modals=num_modals, excitations=excitations) assert_ucc_like_ansatz(self, ansatz, num_modals, expect)
def setUp(self): super().setUp() self.driver = HDF5Driver( self.get_resource_path("test_driver_hdf5.hdf5", "second_q/drivers/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 setUp(self): super().setUp() algorithm_globals.random_seed = 8 self.driver = _DummyBosonicDriver() self.qubit_converter = QubitConverter(DirectMapper()) self.basis_size = 2 self.truncation_order = 2 self.vibrational_problem = VibrationalStructureProblem( self.driver, self.basis_size, self.truncation_order) self.qubit_converter = QubitConverter(DirectMapper()) self.vibrational_problem.second_q_ops() self.grouped_property_transformed = self.vibrational_problem.grouped_property_transformed self.num_modals = [self.basis_size ] * self.grouped_property_transformed.num_modes
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.reference_energies = [ -1.8427016, -1.8427016 + 0.5943372, -1.8427016 + 0.95788352, -1.8427016 + 1.5969296, ] self.qubit_converter = QubitConverter(JordanWignerMapper()) self.electronic_structure_problem = ElectronicStructureProblem( self.driver) solver = NumPyEigensolver() self.ref = solver self.quantum_instance = QuantumInstance( BasicAer.get_backend("statevector_simulator"), seed_transpiler=90, seed_simulator=12, )
def test_build_uvcc(self): """Test building UVCC""" uvcc = UVCC() with self.subTest("Check defaulted construction"): self.assertIsNone(uvcc.num_modals) self.assertIsNone(uvcc.excitations) self.assertIsNone(uvcc.qubit_converter) self.assertIsNone(uvcc.operators) self.assertIsNone(uvcc.excitation_list) self.assertEqual(uvcc.num_qubits, 0) with self.assertRaises(ValueError): _ = uvcc.data with self.subTest("Set num modals"): uvcc.num_modals = [2, 2] self.assertListEqual(uvcc.num_modals, [2, 2]) self.assertIsNone(uvcc.operators) with self.assertRaises(ValueError): _ = uvcc.data with self.subTest("Set excitations"): uvcc.excitations = "sd" self.assertEqual(uvcc.excitations, "sd") self.assertIsNone(uvcc.operators) with self.assertRaises(ValueError): _ = uvcc.data with self.subTest("Set qubit converter to complete build"): converter = QubitConverter(DirectMapper()) uvcc.qubit_converter = converter self.assertEqual(uvcc.qubit_converter, converter) self.assertIsNotNone(uvcc.operators) self.assertEqual(len(uvcc.operators), 3) self.assertEqual(uvcc.num_qubits, 4) self.assertIsNotNone(uvcc.data) with self.subTest("Set custom operators"): self.assertEqual(len(uvcc.operators), 3) uvcc.operators = uvcc.operators[:2] self.assertEqual(len(uvcc.operators), 2) self.assertEqual(uvcc.num_qubits, 4) with self.subTest("Reset operators back to as per UVCC"): uvcc.operators = None self.assertEqual(uvcc.num_qubits, 4) self.assertIsNotNone(uvcc.operators) self.assertEqual(len(uvcc.operators), 3) with self.subTest("Set num modals differently"): uvcc.num_modals = [3, 3] self.assertEqual(uvcc.num_modals, [3, 3]) self.assertIsNotNone(uvcc.operators) self.assertEqual(len(uvcc.operators), 8) with self.subTest("Change excitations"): uvcc.excitations = "s" self.assertIsNotNone(uvcc.operators) self.assertEqual(len(uvcc.operators), 4)
def test_qubits_6_py_lih(self): """qubits 6 py lih test""" num_particles = (1, 1) converter = QubitConverter(ParityMapper(), two_qubit_reduction=True) z2symmetries = Z2Symmetries( symmetries=[Pauli("ZIZIZIZI"), Pauli("ZZIIZZII")], sq_paulis=[Pauli("IIIIIIXI"), Pauli("IIIIIXII")], sq_list=[2, 3], tapering_values=[1, 1], ) converter.force_match(num_particles=num_particles, z2symmetries=z2symmetries) state = HartreeFock(10, num_particles, converter) ref = QuantumCircuit(6) ref.x([0, 1]) self.assertEqual(state, ref)
def test_transpile_no_parameters(self): """Test transpilation without parameters""" qubit_converter = QubitConverter(mapper=DirectMapper()) ansatz = UVCC(qubit_converter=qubit_converter, num_modals=[2], excitations="s") ansatz = transpile(ansatz, optimization_level=3) self.assertEqual(ansatz.num_qubits, 2)
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" ) main_op, _ = es_problem.second_q_ops() qubit_conv.convert( main_op, num_particles=es_problem.num_particles, sector_locator=es_problem.symmetry_sector_locator, ) self.assertListEqual(qubit_conv.z2symmetries.tapering_values, [1, -1])
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 main_op, _ = self.electronic_structure_problem.second_q_ops() _ = self.qubit_converter.convert( main_op, 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]], ]
def __init__( self, transformation_matrix: np.ndarray, qubit_converter: Optional[QubitConverter] = None, validate: bool = True, rtol: float = 1e-5, atol: float = 1e-8, **circuit_kwargs, ) -> None: r""" Args: transformation_matrix: The matrix :math:`W` that specifies the coefficients of the new creation operators in terms of the original creation operators. Should be either :math:`N \times N` or :math:`N \times 2N`. qubit_converter: The qubit converter. The default behavior is to create one using the call `QubitConverter(JordanWignerMapper())`. validate: Whether to validate the inputs. rtol: Relative numerical tolerance for input validation. atol: Absolute numerical tolerance for input validation. circuit_kwargs: Keyword arguments to pass to the QuantumCircuit initializer. Raises: ValueError: transformation_matrix must be a 2-dimensional array. ValueError: transformation_matrix must have orthonormal rows. ValueError: transformation_matrix does not describe a valid transformation of fermionic ladder operators. If the transformation matrix is :math:`N \times N`, then it should be unitary. If the transformation matrix is :math:`N \times 2N`, then it should have the block form :math:`(W_1 \quad W_2)` where :math:`W_1 W_1^\dagger + W_2 W_2^\dagger = I` and :math:`W_1 W_2^T + W_2 W_1^T = 0`. NotImplementedError: Currently, only the Jordan-Wigner Transform is supported. Please use :class:`qiskit_nature.second_q.mappers.JordanWignerMapper` to construct the qubit mapper. """ if validate: _validate_transformation_matrix(transformation_matrix, rtol=rtol, atol=atol) if qubit_converter is None: qubit_converter = QubitConverter(JordanWignerMapper()) n, _ = transformation_matrix.shape register = QuantumRegister(n) super().__init__(register, **circuit_kwargs) if isinstance(qubit_converter.mapper, JordanWignerMapper): operations = _bogoliubov_transform_jw(register, transformation_matrix) for gate, qubits in operations: self.append(gate, qubits) else: raise NotImplementedError( "Currently, only the Jordan-Wigner Transform is supported. " "Please use " "qiskit_nature.second_q.mappers.JordanWignerMapper " "to construct the qubit mapper.")
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", "second_q/drivers/hdf5d")) problem = ElectronicStructureProblem(driver) mapper = JordanWignerMapper() qubit_conv = QubitConverter(mapper, two_qubit_reduction=True, z2symmetry_reduction="auto") main_op, _ = problem.second_q_ops() qubit_op = qubit_conv.convert( main_op, self.num_particles, sector_locator=problem.symmetry_sector_locator, ) self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)
def test_custom_filter_criterion(self): """Test NumPyEigenSolverFactory with ExcitedStatesEigensolver + Custom filter criterion for doublet states""" driver = PySCFDriver( atom="Be .0 .0 .0; H .0 .0 0.75", unit=UnitsType.ANGSTROM, charge=0, spin=1, basis="sto3g", ) transformer = ActiveSpaceTransformer( num_electrons=(1, 2), num_molecular_orbitals=4, ) # We define an ActiveSpaceTransformer to reduce the duration of this test example. converter = QubitConverter(JordanWignerMapper(), z2symmetry_reduction="auto") esp = ElectronicStructureProblem(driver, [transformer]) expected_spin = 0.75 # Doublet states expected_num_electrons = 3 # 1 alpha electron + 2 beta electrons # pylint: disable=unused-argument def custom_filter_criterion(eigenstate, eigenvalue, aux_values): num_particles_aux = aux_values["ParticleNumber"][0] total_angular_momentum_aux = aux_values["AngularMomentum"][0] return np.isclose(expected_spin, total_angular_momentum_aux) and np.isclose( expected_num_electrons, num_particles_aux) solver = NumPyEigensolverFactory( filter_criterion=custom_filter_criterion) esc = ExcitedStatesEigensolver(converter, solver) results = esc.solve(esp) # filter duplicates from list computed_energies = [results.computed_energies[0]] for comp_energy in results.computed_energies[1:]: if not np.isclose(comp_energy, computed_energies[-1]): computed_energies.append(comp_energy) ref_energies = [ -2.6362023196223254, -2.2971398524128923, -2.2020252702733165, -2.1044859216523752, -1.696132447109807, -1.6416831059956618, ] for idx, energy in enumerate(ref_energies): self.assertAlmostEqual(computed_energies[idx], energy, places=3)
def setUp(self): super().setUp() algorithm_globals.random_seed = 42 driver = HDF5Driver(hdf5_input=self.get_resource_path( "test_driver_hdf5.hdf5", "second_q/drivers/hdf5d")) problem = ElectronicStructureProblem(driver) main_op, aux_ops = problem.second_q_ops() 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(main_op, num_particles) self.aux_ops = converter.convert_match(aux_ops) self.reference_energy = -1.857275027031588
def test_succd_ansatz(self, num_spin_orbitals, num_particles, expect): """Tests the SUCCD Ansatz.""" converter = QubitConverter(JordanWignerMapper()) ansatz = SUCCD( qubit_converter=converter, num_particles=num_particles, num_spin_orbitals=num_spin_orbitals, ) assert_ucc_like_ansatz(self, ansatz, num_spin_orbitals, expect)
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" ) main_op, _ = es_problem.second_q_ops() qubit_conv.convert( main_op, num_particles=es_problem.num_particles, sector_locator=es_problem.symmetry_sector_locator, ) self.assertListEqual(qubit_conv.z2symmetries.tapering_values, [-1, 1])
def test_mp2_initial_point_with_real_molecules( self, atom, ): """Test MP2InitialPoint with real molecules.""" from pyscf import gto # pylint: disable=import-error # Compute the PySCF result pyscf_mol = gto.M(atom=atom, basis="sto3g", verbose=0) pyscf_mp = pyscf_mol.MP2().run(verbose=0) driver = PySCFDriver(atom=atom, basis="sto3g") problem = ElectronicStructureProblem(driver) problem.second_q_ops() grouped_property = problem.grouped_property_transformed particle_number = grouped_property.get_property(ParticleNumber) num_particles = (particle_number.num_alpha, particle_number.num_beta) num_spin_orbitals = particle_number.num_spin_orbitals qubit_converter = QubitConverter(mapper=JordanWignerMapper()) initial_state = HartreeFock( num_spin_orbitals=num_spin_orbitals, num_particles=num_particles, qubit_converter=qubit_converter, ) ansatz = UCC( num_spin_orbitals=num_spin_orbitals, num_particles=num_particles, excitations="sd", qubit_converter=qubit_converter, initial_state=initial_state, ) mp2_initial_point = MP2InitialPoint() mp2_initial_point.grouped_property = grouped_property mp2_initial_point.ansatz = ansatz with self.subTest("Test the MP2 energy correction."): np.testing.assert_almost_equal(mp2_initial_point.energy_correction, pyscf_mp.e_corr, decimal=4) with self.subTest("Test the total MP2 energy."): np.testing.assert_almost_equal(mp2_initial_point.total_energy, pyscf_mp.e_tot, decimal=4) with self.subTest("Test the T2 amplitudes."): mp2_initial_point.compute() np.testing.assert_array_almost_equal( mp2_initial_point.t2_amplitudes, pyscf_mp.t2, decimal=4)
def test_puccd_ansatz_generalized(self, num_spin_orbitals, num_particles, expect): """Tests the generalized PUCCD Ansatz.""" converter = QubitConverter(JordanWignerMapper()) ansatz = PUCCD( qubit_converter=converter, num_particles=num_particles, num_spin_orbitals=num_spin_orbitals, generalized=True, ) assert_ucc_like_ansatz(self, ansatz, num_spin_orbitals, expect)
def test_succd_ansatz_with_singles(self, num_spin_orbitals, num_particles, include_singles, expect): """Tests the SUCCD Ansatz with included single excitations.""" converter = QubitConverter(JordanWignerMapper()) ansatz = SUCCD( qubit_converter=converter, num_particles=num_particles, num_spin_orbitals=num_spin_orbitals, include_singles=include_singles, ) assert_ucc_like_ansatz(self, ansatz, num_spin_orbitals, expect)
def test_oh_uhf_parity(self): """oh uhf parity test""" driver = PySCFDriver( atom=self.o_h, unit=UnitsType.ANGSTROM, charge=0, spin=1, basis="sto-3g", method=MethodType.UHF, ) result = self._run_driver(driver, converter=QubitConverter(ParityMapper())) self._assert_energy_and_dipole(result, "oh")
def test_ucc_ansatz(self, excitations, num_spin_orbitals, num_particles, expect): """Tests the UCC Ansatz.""" converter = QubitConverter(JordanWignerMapper()) ansatz = UCC( qubit_converter=converter, num_particles=num_particles, num_spin_orbitals=num_spin_orbitals, excitations=excitations, ) assert_ucc_like_ansatz(self, ansatz, num_spin_orbitals, expect)
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)
def test_diagonalizing_bogoliubov_transform(self): """Test diagonalizing Bogoliubov transform.""" hermitian_part = np.array( [[0.0, 1.0, 0.0], [1.0, 0.0, 1.0], [0.0, 1.0, 0.0]], dtype=complex) antisymmetric_part = np.array( [[0.0, 1.0j, 0.0], [-1.0j, 0.0, 1.0j], [0.0, -1.0j, 0.0]], dtype=complex) quad_ham = QuadraticHamiltonian(hermitian_part, antisymmetric_part) ( transformation_matrix, orbital_energies, transformed_constant, ) = quad_ham.diagonalizing_bogoliubov_transform() # test that the transformation diagonalizes the Hamiltonian left = transformation_matrix[:, :3] right = transformation_matrix[:, 3:] full_transformation_matrix = np.block([[left, right], [right.conj(), left.conj()]]) eye = np.eye(3, dtype=complex) majorana_basis = np.block([[eye, eye], [1j * eye, -1j * eye] ]) / np.sqrt(2) basis_change = majorana_basis @ full_transformation_matrix @ majorana_basis.T.conj( ) majorana_matrix, majorana_constant = quad_ham.majorana_form() canonical = basis_change @ majorana_matrix @ basis_change.T zero = np.zeros((3, 3)) diagonal = np.diag(orbital_energies) expected = np.block([[zero, diagonal], [-diagonal, zero]]) np.testing.assert_allclose(orbital_energies, np.sort(orbital_energies)) np.testing.assert_allclose(canonical, expected, atol=1e-7) np.testing.assert_allclose( transformed_constant, majorana_constant - 0.5 * np.sum(orbital_energies)) # confirm eigenvalues match with Jordan-Wigner transformed Hamiltonian hamiltonian_jw = (QubitConverter(mapper=JordanWignerMapper()).convert( quad_ham.to_fermionic_op()).primitive.to_matrix()) eigs, _ = np.linalg.eigh(hamiltonian_jw) expected_eigs = np.array([ np.sum(orbital_energies[list(occupied_orbitals)]) + transformed_constant for occupied_orbitals in [(), (0, ), ( 1, ), (2, ), (0, 1), (0, 2), (1, 2), (0, 1, 2)] ]) np.testing.assert_allclose(np.sort(eigs), np.sort(expected_eigs), atol=1e-7)
def test_oh_rohf_bk(self): """oh rohf bk test""" driver = PySCFDriver( atom=self.o_h, unit=UnitsType.ANGSTROM, charge=0, spin=1, basis="sto-3g", method=MethodType.ROHF, ) result = self._run_driver(driver, converter=QubitConverter( BravyiKitaevMapper())) self._assert_energy_and_dipole(result, "oh")
def _run_driver( driver: ElectronicStructureDriver, converter: QubitConverter = QubitConverter(JordanWignerMapper()), transformers: Optional[List[BaseTransformer]] = None, ): problem = ElectronicStructureProblem(driver, transformers) solver = NumPyMinimumEigensolver() gsc = GroundStateEigensolver(converter, solver) result = gsc.solve(problem) return result
def test_oh_rohf_parity_2q(self): """oh rohf parity 2q test""" driver = PySCFDriver( atom=self.o_h, unit=UnitsType.ANGSTROM, charge=0, spin=1, basis="sto-3g", method=MethodType.ROHF, ) result = self._run_driver( driver, converter=QubitConverter(ParityMapper(), two_qubit_reduction=True)) self._assert_energy_and_dipole(result, "oh")
def test_bogoliubov_transform(self, n_orbitals, num_conserving): """Test Bogoliubov transform.""" converter = QubitConverter(JordanWignerMapper()) hamiltonian = random_quadratic_hamiltonian( n_orbitals, num_conserving=num_conserving, seed=5740) ( transformation_matrix, orbital_energies, transformed_constant, ) = hamiltonian.diagonalizing_bogoliubov_transform() matrix = converter.map(hamiltonian.to_fermionic_op()).to_matrix() bog_circuit = BogoliubovTransform(transformation_matrix, qubit_converter=converter) for initial_state in range(2**n_orbitals): state = Statevector.from_int(initial_state, dims=2**n_orbitals) final_state = np.array(state.evolve(bog_circuit)) occupied_orbitals = [ i for i in range(n_orbitals) if initial_state >> i & 1 ] eig = np.sum( orbital_energies[occupied_orbitals]) + transformed_constant np.testing.assert_allclose(matrix @ final_state, eig * final_state, atol=1e-8)