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 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_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)
Example #4
0
    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)
Example #6
0
 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)
Example #7
0
    def setUp(self):
        super().setUp()
        self.driver = HDF5Driver(self.get_resource_path('test_driver_hdf5.hdf5',
                                                        '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.watson_hamiltonian = self.vibrational_problem.grouped_property_transformed
        self.num_modals = [self.basis_size] * self.watson_hamiltonian.num_modes
Example #9
0
    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 _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 test_unsupported_mapper(self):
     """Test passing unsupported mapper fails gracefully."""
     with self.assertRaisesRegex(NotImplementedError, "supported"):
         _ = FermionicGaussianState(
             np.block([np.eye(2), np.zeros((2, 2))]),
             qubit_converter=QubitConverter(BravyiKitaevMapper()),
         )
Example #12
0
    def test_h2_bopes_sampler(self):
        """Test BOPES Sampler on H2"""
        # Molecule
        dof = partial(Molecule.absolute_distance, atom_pair=(1, 0))
        m = Molecule(
            geometry=[["H", [0.0, 0.0, 1.0]], ["H", [0.0, 0.45, 1.0]]],
            degrees_of_freedom=[dof],
        )

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

        driver = ElectronicStructureMoleculeDriver(
            m, driver_type=ElectronicStructureDriverType.PYSCF)
        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 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 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)
Example #15
0
    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 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_return_groundstate(self):
     """Test the VQEClient yields a ground state solver that returns the ground state."""
     for use_deprecated in [False, True]:
         vqe, _ = self.get_standard_program(use_deprecated=use_deprecated)
         qubit_converter = QubitConverter(JordanWignerMapper())
         gss = GroundStateEigensolver(qubit_converter, vqe)
         self.assertTrue(gss.returns_groundstate)
    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,
        )
Example #19
0
    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)
Example #20
0
    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_vqe_mes_parity_auto(self):
     """Test VQEUCCSDFactory with QEOM + Parity mapping + auto symmetry"""
     self.skipTest(
         "Temporarily skip test until the changes done by "
         "https://github.com/Qiskit/qiskit-terra/pull/7551 are handled properly."
     )
     converter = QubitConverter(ParityMapper(), z2symmetry_reduction="auto")
     self._solve_with_vqe_mes(converter)
 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_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 __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.mappers.second_quantization.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.mappers.second_quantization.JordanWignerMapper "
                "to construct the qubit mapper.")
Example #25
0
    def test_uccsd_ansatz(self, num_spin_orbitals, num_particles, expect):
        """Tests the UCCSD Ansatz."""
        converter = QubitConverter(JordanWignerMapper())

        ansatz = UCCSD(qubit_converter=converter,
                       num_particles=num_particles,
                       num_spin_orbitals=num_spin_orbitals)

        assert_ucc_like_ansatz(self, ansatz, num_spin_orbitals, expect)
Example #26
0
def hartree_fock_bitstring_mapped(
    num_spin_orbitals: int,
    num_particles: Tuple[int, int],
    qubit_converter: QubitConverter,
    match_convert: bool = True,
) -> List[bool]:
    """Compute the bitstring representing the mapped Hartree-Fock state for the specified system.

    Args:
        num_spin_orbitals: The number of spin orbitals, has a min. value of 1.
        num_particles: The number of particles as a tuple (alpha, beta) containing the number of
            alpha- and  beta-spin electrons, respectively.
        qubit_converter: A QubitConverter instance.
        match_convert: Whether to use `convert_match` method of the qubit converter (default),
            or just do mapping and possibly two qubit reduction but no tapering. The latter
            is an advanced usage - e.g. if we are trying to auto-select the tapering sector
            then we would not want any match conversion done on a converter that was set to taper.

    Returns:
        The bitstring representing the mapped state of the Hartree-Fock state as array of bools.
    """

    # 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), display_format="sparse")

    # map the `FermionicOp` to a qubit operator
    qubit_op: PauliSumOp = (
        qubit_converter.convert_match(bitstr_op, check_commutes=False)
        if match_convert
        else qubit_converter.convert_only(bitstr_op, num_particles)
    )

    # We check the mapped operator `x` part of the paulis because we want to have particles
    # i.e. True, where the initial state introduced a creation (`+`) operator.
    bits = []
    for bit in qubit_op.primitive.paulis.x[0]:
        bits.append(bit)

    return bits
Example #27
0
    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)
Example #28
0
    def setUp(self):
        super().setUp()

        self.driver = PySCFDriver(atom="H .0 .0 .0; H .0 .0 0.735",
                                  unit=UnitsType.ANGSTROM,
                                  basis="sto3g")

        self.problem = ElectronicStructureProblem(self.driver)

        self.expected = -1.85727503

        self.qubit_converter = QubitConverter(ParityMapper())
    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_ucc_factory = VQEUCCFactory(self.quantum_instance)
Example #30
0
    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:`Q` that specifies the coefficients of the
                new creation operators in terms of the original creation operators.
                The rows of the matrix must be orthonormal.
            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.
            NotImplementedError: Currently, only the Jordan-Wigner Transform is supported.
                Please use
                :class:`qiskit_nature.mappers.second_quantization.JordanWignerMapper`
                to construct the qubit mapper used to construct `qubit_converter`.
        """
        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 = _prepare_slater_determinant_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.mappers.second_quantization.JordanWignerMapper "
                "to construct the qubit mapper used to construct qubit_converter."
            )