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_chc_vscf(self): """ chc 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) num_qubits = sum(num_modals) excitations = [] excitations += generate_vibration_excitations(num_excitations=1, num_modals=num_modals) excitations += generate_vibration_excitations(num_excitations=2, num_modals=num_modals) chc_ansatz = CHC(num_qubits, ladder=False, excitations=excitations, initial_state=init_state) backend = QuantumInstance( BasicAer.get_backend('statevector_simulator'), seed_transpiler=2, seed_simulator=2) optimizer = COBYLA(maxiter=1000) algo = VQE(chc_ansatz, optimizer=optimizer, quantum_instance=backend) vqe_result = algo.compute_minimum_eigenvalue(qubit_op) energy = vqe_result.optimal_value self.assertAlmostEqual(energy, self.reference_energy, places=4)
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_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 setUp(self): super().setUp() algorithm_globals.random_seed = 42 driver = HDF5Driver(hdf5_input=self.get_resource_path('test_driver_hdf5.hdf5', 'drivers/hdf5d')) problem = ElectronicStructureProblem(driver) second_q_ops = problem.second_q_ops() converter = QubitConverter(mapper=ParityMapper(), two_qubit_reduction=True) num_particles = (problem.molecule_data_transformed.num_alpha, problem.molecule_data_transformed.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 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.watson_hamiltonian = self.vibrational_problem.molecule_data self.num_modals = [self.basis_size] * self.watson_hamiltonian.num_modes
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 _build_single_hopping_operator( excitation: Tuple[Tuple[int, ...], Tuple[int, ...]], num_spin_orbitals: int, qubit_converter: QubitConverter) -> Tuple[PauliSumOp, List[bool]]: label = ['I'] * num_spin_orbitals for occ in excitation[0]: label[occ] = '+' for unocc in excitation[1]: label[unocc] = '-' fer_op = FermionicOp((''.join(label), 4.0**len(excitation[0]))) qubit_op: PauliSumOp = qubit_converter.convert_match(fer_op) z2_symmetries = qubit_converter.z2symmetries commutativities = [] if not z2_symmetries.is_empty(): for symmetry in z2_symmetries.symmetries: symmetry_op = PauliSumOp.from_list([(symmetry.to_label(), 1.0)]) commuting = qubit_op.primitive.table.commutes_with_all( symmetry_op.primitive.table) anticommuting = qubit_op.primitive.table.anticommutes_with_all( symmetry_op.primitive.table) if commuting != anticommuting: # only one of them is True if commuting: commutativities.append(True) elif anticommuting: commutativities.append(False) else: raise QiskitNatureError( "Symmetry {} is nor commute neither anti-commute " "to exciting operator.".format(symmetry.to_label())) return qubit_op, commutativities
def __init__(self, num_spin_orbitals: int, num_particles: Tuple[int, int], qubit_converter: QubitConverter) -> None: """ Args: num_spin_orbitals: The number of spin orbitals, has a min. value of 1. num_particles: The number of particles as a tuple storing the number of alpha- and beta-spin electrons in the first and second number, respectively. qubit_converter: a QubitConverter instance. """ # get the bitstring encoding the Hartree Fock state bitstr = hartree_fock_bitstring(num_spin_orbitals, num_particles) # encode the bitstring as a `FermionicOp` label = ['+' if bit else 'I' for bit in bitstr] bitstr_op = FermionicOp(''.join(label)) # map the `FermionicOp` to a qubit operator qubit_op: PauliSumOp = qubit_converter.convert_match(bitstr_op) # construct the circuit qr = QuantumRegister(qubit_op.num_qubits, 'q') super().__init__(qr, name='HF') # Add gates in the right positions: we are only interested in the `X` gates because we want # to create particles (0 -> 1) where the initial state introduced a creation (`+`) operator. for i, bit in enumerate(qubit_op.primitive.table.X[0]): if bit: self.x(i)
def test_h2_bopes_sampler(self): """Test BOPES Sampler on H2""" seed = 50 algorithm_globals.random_seed = seed # Molecule dof = partial(Molecule.absolute_distance, atom_pair=(1, 0)) m = Molecule(geometry=[['H', [0., 0., 1.]], ['H', [0., 0.45, 1.]]], degrees_of_freedom=[dof]) mapper = ParityMapper() converter = QubitConverter(mapper=mapper, two_qubit_reduction=True) driver = PySCFDriver(molecule=m) problem = ElectronicStructureProblem(driver) solver = NumPyMinimumEigensolver() me_gss = GroundStateEigensolver(converter, solver) # BOPES sampler sampler = BOPESSampler(gss=me_gss) # absolute internuclear distance in Angstrom points = [0.7, 1.0, 1.3] results = sampler.sample(problem, points) points_run = results.points energies = results.energies np.testing.assert_array_almost_equal(points_run, [0.7, 1.0, 1.3]) np.testing.assert_array_almost_equal( energies, [-1.13618945, -1.10115033, -1.03518627], decimal=2)
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_oh_uhf_bk(self): """ oh uhf bk test """ driver = PySCFDriver(atom=self.o_h, unit=UnitsType.ANGSTROM, charge=0, spin=1, basis='sto-3g', hf_method=HFMethodType.UHF) result = self._run_driver(driver, converter=QubitConverter(BravyiKitaevMapper())) self._assert_energy_and_dipole(result, 'oh')
def test_oh_rohf_parity(self): """ oh rohf parity test """ driver = PySCFDriver(atom=self.o_h, unit=UnitsType.ANGSTROM, charge=0, spin=1, basis='sto-3g', hf_method=HFMethodType.ROHF) result = self._run_driver(driver, converter=QubitConverter(ParityMapper())) self._assert_energy_and_dipole(result, 'oh')
def test_puccd_ansatz(self, num_spin_orbitals, num_particles, expect): """Tests the PUCCD Ansatz.""" converter = QubitConverter(JordanWignerMapper()) ansatz = PUCCD(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_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 test_lih_rhf_bk(self): """ lih rhf bk test """ driver = PySCFDriver(atom=self.lih, unit=UnitsType.ANGSTROM, charge=0, spin=0, basis='sto-3g', hf_method=HFMethodType.RHF) result = self._run_driver(driver, converter=QubitConverter(BravyiKitaevMapper()), transformers=[FreezeCoreTransformer()]) self._assert_energy_and_dipole(result, 'lih')
def test_oh_uhf_parity_2q(self): """ oh uhf parity 2q test """ driver = PySCFDriver(atom=self.o_h, unit=UnitsType.ANGSTROM, charge=0, spin=1, basis='sto-3g', hf_method=HFMethodType.UHF) result = self._run_driver(driver, converter=QubitConverter(ParityMapper(), two_qubit_reduction=True)) self._assert_energy_and_dipole(result, 'oh')
def test_lih_rhf_parity_2q(self): """ lih rhf parity 2q test """ driver = PySCFDriver(atom=self.lih, unit=UnitsType.ANGSTROM, charge=0, spin=0, basis='sto-3g', hf_method=HFMethodType.RHF) result = self._run_driver(driver, converter=QubitConverter(ParityMapper(), two_qubit_reduction=True), transformers=[FreezeCoreTransformer()]) self._assert_energy_and_dipole(result, 'lih')
def test_puccd_ansatz_with_singles(self, num_spin_orbitals, num_particles, include_singles, expect): """Tests the PUCCD Ansatz with included single excitations.""" converter = QubitConverter(JordanWignerMapper()) ansatz = PUCCD(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 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]]]
def setUp(self): super().setUp() self.converter = QubitConverter(JordanWignerMapper()) self.seed = 50 self.quantum_instance = QuantumInstance( BasicAer.get_backend('statevector_simulator'), shots=1, seed_simulator=self.seed, seed_transpiler=self.seed) self._vqe_uvcc_factory = VQEUVCCFactory(self.quantum_instance)
def setUp(self): super().setUp() algorithm_globals.random_seed = 8 self.reference_energies = [1889.95738428, 3294.21806197, 4287.26821341, 5819.76975784] 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 )
def _run_driver(driver: FermionicDriver, 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 _build_single_hopping_operator( excitation: Tuple[Tuple[int, ...], Tuple[int, ...]], num_modals: List[int], qubit_converter: QubitConverter) -> PauliSumOp: sum_modes = sum(num_modals) label = ['I'] * sum_modes for occ in excitation[0]: label[occ] = '+' for unocc in excitation[1]: label[unocc] = '-' vibrational_op = VibrationalOp(''.join(label), len(num_modals), num_modals) qubit_op: PauliSumOp = qubit_converter.convert_match(vibrational_op) return qubit_op
def setUp(self): super().setUp() try: self.driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735', unit=UnitsType.ANGSTROM, basis='sto3g') except QiskitNatureError: self.skipTest('PYSCF driver does not appear to be installed') return self.problem = ElectronicStructureProblem(self.driver) self.expected = -1.85727503 self.qubit_converter = QubitConverter(ParityMapper())
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_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 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.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 __init__( self, num_modals: List[int], qubit_converter: Optional[QubitConverter] = None, ) -> None: """ Args: num_modals: Is a list defining the number of modals per mode. E.g. for a 3 modes system with 4 modals per mode num_modals = [4,4,4] qubit_converter: a QubitConverter instance. This argument is currently being ignored because only a single use-case is supported at the time of release: that of the :class:`DirectMapper`. However, for future-compatibility of this functions signature, the argument has already been inserted. """ # get the bitstring encoding initial state bitstr = vscf_bitstring(num_modals) # encode the bitstring in a `VibrationalOp` label = ['+' if bit else 'I' for bit in bitstr] bitstr_op = VibrationalOp(''.join(label), num_modes=len(num_modals), num_modals=num_modals) # map the `VibrationalOp` to a qubit operator if qubit_converter is not None: logger.warning( 'The only supported `QubitConverter` is one with a `DirectMapper` as the mapper ' 'instance. However you specified %s as an input, which will be ignored until more ' 'variants will be supported.', str(qubit_converter)) qubit_converter = QubitConverter(DirectMapper()) qubit_op: PauliSumOp = qubit_converter.convert_match(bitstr_op) # construct the circuit qr = QuantumRegister(qubit_op.num_qubits, 'q') super().__init__(qr, name='VSCF') # add gates in the right positions for i, bit in enumerate(qubit_op.primitive.table.X[0]): if bit: self.x(i)