Example #1
0
    def to_second_q_op(self) -> FermionicOp:
        """Creates the operator representing the Hamiltonian defined by these electronic integrals.

        This method uses ``to_spin`` internally to map the electronic integrals into the spin
        orbital basis.

        Returns:
            The :class:`~qiskit_nature.operators.second_quantization.FermionicOp` given by these
            electronic integrals.
        """
        spin_matrix = self.to_spin()
        register_length = len(spin_matrix)

        if not np.any(spin_matrix):
            return FermionicOp.zero(register_length)

        spin_matrix_iter = spin_matrix.flat
        # NOTE: we need to access `.coords` before `.next()` is called for the first time!
        coords = spin_matrix_iter.coords
        op_data = []
        for coeff in spin_matrix_iter:
            if coeff:
                op_data.append((self._calc_coeffs_with_ops(coords), coeff))
            coords = spin_matrix_iter.coords

        return FermionicOp(op_data,
                           register_length=register_length,
                           display_format="sparse")
    def test_mapping_for_single_op(self):
        """Test for single register operator."""
        with self.subTest("test +"):
            op = FermionicOp("+", display_format="dense")
            expected = PauliSumOp.from_list([("X", 0.5), ("Y", -0.5j)])
            self.assertEqual(JordanWignerMapper().map(op), expected)

        with self.subTest("test -"):
            op = FermionicOp("-", display_format="dense")
            expected = PauliSumOp.from_list([("X", 0.5), ("Y", 0.5j)])
            self.assertEqual(JordanWignerMapper().map(op), expected)

        with self.subTest("test N"):
            op = FermionicOp("N", display_format="dense")
            expected = PauliSumOp.from_list([("I", 0.5), ("Z", -0.5)])
            self.assertEqual(JordanWignerMapper().map(op), expected)

        with self.subTest("test E"):
            op = FermionicOp("E", display_format="dense")
            expected = PauliSumOp.from_list([("I", 0.5), ("Z", 0.5)])
            self.assertEqual(JordanWignerMapper().map(op), expected)

        with self.subTest("test I"):
            op = FermionicOp("I", display_format="dense")
            expected = PauliSumOp.from_list([("I", 1)])
            self.assertEqual(JordanWignerMapper().map(op), expected)
 def assertFermionEqual(self, first: FermionicOp, second: FermionicOp):
     """Fail if two FermionicOps are different.
     Note that this equality check is approximated since the true equality check is costly.
     """
     self.assertSetEqual(
         frozenset(first.to_list()), frozenset(second.to_list(first.display_format))
     )
Example #4
0
 def test_init_empty_str(self, pre_processing):
     """Test __init__ with empty string"""
     actual = FermionicOp(pre_processing(""),
                          register_length=3,
                          display_format="dense")
     desired = FermionicOp("III", display_format="dense")
     self.assertFermionEqual(actual, desired)
Example #5
0
 def test_div(self):
     """Test __truediv__"""
     fer_op = FermionicOp([("+N", 3),
                           ("E-", 1)], display_format="dense") / 3
     targ = FermionicOp([("+N", 1.0), ("E-", 1 / 3)],
                        display_format="dense")
     self.assertFermionEqual(fer_op, targ)
Example #6
0
 def test_sub(self):
     """Test __sub__"""
     fer_op = 3 * FermionicOp("++",
                              display_format="dense") - 2 * FermionicOp(
                                  "--", display_format="dense")
     targ = FermionicOp([("++", 3), ("--", -2)], display_format="dense")
     self.assertFermionEqual(fer_op, targ)
Example #7
0
 def test_matmul(self, label1, label2):
     """Test matrix multiplication"""
     fer_op = FermionicOp(label1, display_format="dense") @ FermionicOp(
         label2, display_format="dense")
     mapping = {
         "II": "I",
         "I+": "+",
         "I-": "-",
         "IN": "N",
         "IE": "E",
         "+I": "+",
         "++": 0,
         "+-": "N",
         "+N": 0,
         "+E": "+",
         "-I": "-",
         "-+": "E",
         "--": 0,
         "-N": "-",
         "-E": 0,
         "NI": "N",
         "N+": "+",
         "N-": 0,
         "NN": "N",
         "NE": 0,
         "EI": "E",
         "E+": 0,
         "E-": "-",
         "EN": 0,
         "EE": "E",
     }
     result = mapping[label1 + label2]
     targ = FermionicOp([(result, 1)] if result != 0 else [("I", 0)],
                        display_format="dense")
     self.assertFermionEqual(fer_op, targ)
Example #8
0
    def _build_fermionic_excitation_ops(
            self, excitations: Sequence) -> List[FermionicOp]:
        """Builds all possible excitation operators with the given number of excitations for the
        specified number of particles distributed in the number of orbitals.

        Args:
            excitations: the list of excitations.

        Returns:
            The list of excitation operators in the second quantized formalism.
        """
        operators = []

        for exc in excitations:
            label = ['I'] * self.num_spin_orbitals
            for occ in exc[0]:
                label[occ] = '+'
            for unocc in exc[1]:
                label[unocc] = '-'
            op = FermionicOp(''.join(label))
            op -= op.adjoint()
            # we need to account for an additional imaginary phase in the exponent (see also
            # `PauliTrotterEvolution.convert`)
            op *= 1j
            operators.append(op)

        return operators
Example #9
0
 def test_init_sparse_label(self, labels, pre_processing):
     """Test __init__ with sparse label"""
     dense_label, sparse_label = labels
     fer_op = FermionicOp(pre_processing(sparse_label),
                          register_length=len(dense_label),
                          display_format="sparse")
     targ = FermionicOp(dense_label, display_format="sparse")
     self.assertFermionEqual(fer_op, targ)
 def test_init_multiple_digits(self):
     """Test __init__ for sparse label with multiple digits"""
     actual = FermionicOp([("-_2 +_10", 1 + 2j), ("-_12", 56)], register_length=13)
     desired = [
         ("II-IIIIIII+II", 1 + 2j),
         ("IIIIIIIIIIII-", 56),
     ]
     self.assertListEqual(actual.to_list(), desired)
    def test_add(self):
        """Test __add__"""
        fer_op = 3 * FermionicOp("+N") + FermionicOp("E-")
        targ = FermionicOp([("+N", 3), ("E-", 1)])
        self.assertFermionEqual(fer_op, targ)

        fer_op = sum(FermionicOp(label) for label in ["NIII", "INII", "IINI", "IIIN"])
        targ = FermionicOp([("NIII", 1), ("INII", 1), ("IINI", 1), ("IIIN", 1)])
        self.assertFermionEqual(fer_op, targ)
Example #12
0
 def test_terms(self):
     """Test terms"""
     op = FermionicOp([("+", 1.0), ("N", 2.0), ("-+", 3.0)], display_format="dense")
     expected = {
         ((("+", 0),), 1.0),
         ((("+", 0), ("-", 0)), 2.0),
         ((("-", 0), ("+", 1)), 3.0),
     }
     self.assertEqual(set(op.terms()), expected)
Example #13
0
def _create_base_op_from_labels(coeff, length: int,
                                coeffs_with_ops) -> FermionicOp:
    label = ["I"] * length
    base_op = coeff * FermionicOp("".join(label))
    for i, op in coeffs_with_ops:
        label_i = label.copy()
        label_i[i] = op
        base_op @= FermionicOp("".join(label_i))
    return base_op
    def test_init_multiterm(self):
        """Test __init__ with multi terms"""
        with self.subTest("Test 1"):
            labels = [("N", 2), ("-", 3.14)]
            self.assertListEqual(FermionicOp(labels).to_list(), labels)

        with self.subTest("Test 2"):
            labels = [("+-", 1), ("-+", -1)]
            op = FermionicOp([("+_0 -_1", 1.0), ("-_0 +_1", -1.0)], register_length=2)
            self.assertListEqual(op.to_list(), labels)
Example #15
0
    def test_mul(self):
        """Test __mul__, and __rmul__"""
        with self.subTest("rightmul"):
            fer_op = FermionicOp("+-", display_format="dense") * 2
            targ = FermionicOp([("+-", 2)], display_format="dense")
            self.assertFermionEqual(fer_op, targ)

        with self.subTest("left mul"):
            fer_op = (2 + 1j) * FermionicOp([("+N", 3), ("E-", 1)], display_format="dense")
            targ = FermionicOp([("+N", (6 + 3j)), ("E-", (2 + 1j))], display_format="dense")
            self.assertFermionEqual(fer_op, targ)
    def test_adjoint(self):
        """Test adjoint method and dagger property"""
        with self.subTest("adjoint"):
            fer_op = ~FermionicOp([("+N", 3), ("N-", 1), ("--", 2 + 4j)])
            targ = FermionicOp([("-N", 3), ("N+", 1), ("++", (-2 + 4j))])
            self.assertFermionEqual(fer_op, targ)

        with self.subTest("dagger"):
            fer_op = FermionicOp([("+-", 1), ("II", 2j)]).dagger
            targ = FermionicOp([("-+", -1), ("II", -2j)])
            self.assertFermionEqual(fer_op, targ)
Example #17
0
    def test_adjoint(self):
        """Test adjoint method"""
        with self.subTest("adjoint"):
            fer_op = ~FermionicOp([("+N", 3), ("N-", 1), ("--", 2 + 4j)], display_format="dense")
            targ = FermionicOp([("-N", 3), ("N+", 1), ("++", (-2 + 4j))], display_format="dense")
            self.assertFermionEqual(fer_op, targ)

        with self.subTest("adjoint 2"):
            fer_op = FermionicOp([("+-", 1), ("II", 2j)], display_format="dense").adjoint()
            targ = FermionicOp([("-+", -1), ("II", -2j)], display_format="dense")
            self.assertFermionEqual(fer_op, targ)
Example #18
0
 def test_init_from_tuple_label(self):
     """Test __init__ for tuple"""
     actual = FermionicOp(
         [([("-", 2), ("+", 10)], 1 + 2j), ([("-", 12)], 56)],
         register_length=13,
         display_format="dense",
     )
     desired = [
         ("II-IIIIIII+II", 1 + 2j),
         ("IIIIIIIIIIII-", 56),
     ]
     self.assertListEqual(actual.to_list(), desired)
Example #19
0
 def test_second_q_ops(self):
     """Test second_q_ops."""
     op = self.prop.second_q_ops()["AngularMomentum"]
     with open(
             self.get_resource_path(
                 "angular_momentum_op.json",
                 "properties/second_quantization/electronic/resources"),
             "r",
             encoding="utf8",
     ) as file:
         expected = json.load(file)
         expected_op = FermionicOp(expected).simplify()
     self.assertSetEqual(frozenset(op.to_list("dense")),
                         frozenset(expected_op.to_list("dense")))
    def test_matmul_multi(self):
        """Test matrix multiplication"""
        with self.subTest("single matmul"):
            fer_op = FermionicOp("+-") @ FermionicOp("-I")
            targ = FermionicOp([("N-", -1)])
            self.assertFermionEqual(fer_op, targ)

        with self.subTest("multi matmul"):
            fer_op = FermionicOp("+-") @ FermionicOp("-I")
            fer_op = (FermionicOp("+N") + FermionicOp("E-")) @ (
                FermionicOp("II") + FermionicOp("-+")
            )
            targ = FermionicOp([("+N", 1), ("N+", 1), ("E-", 1), ("-E", -1)])
            self.assertFermionEqual(fer_op, targ)
Example #21
0
def _convert_operator(ferm_op: FermionicOp, edge_list: np.ndarray) -> SparsePauliOp:
    """Convert a fermionic operator together with qubit-connectivity graph to a Pauli operator.

    This is the heart of the implementation of BKSF mapping. The connectivity graph must be
    computed before this method is called. The returned Pauli operator must be sorted and simplified.

    Args:
      ferm_op: The fermionic operator to convert.
      edge_list: The qubit-connectivity graph expressed as an edge list.

    Returns:
      An un-simplified Pauli operator representing `ferm_op`.

    Raises:
      ValueError: if the type of interaction of any term is unknown.
    """
    sparse_pauli = None
    for term in ferm_op.to_list():
        term_type, facs = _analyze_term(_operator_string(term))
        if facs[0][1] == "-":  # keep only one of h.c. pair
            continue
        ## Following only filters h.c. of some number-excitation op
        if facs[0][0] == facs[1][0]:  # first op is number op, which is it's own h.c.
            if len(facs) > 2 and facs[2][1] == "-":  # So, look at next op to skip h.c.
                continue

        if term_type == TermType.NUMBER:  # a^\dagger_p a_p
            p = facs[0][0]  # pylint: disable=invalid-name
            h1_pq = _operator_coefficient(term)
            sparse_pauli = _add_sparse_pauli(sparse_pauli, _number_operator(edge_list, p, h1_pq))
            continue

        if term_type == TermType.EXCITATION:
            (p, q) = [facs[i][0] for i in range(2)]  # p < q always   # pylint: disable=invalid-name
            h1_pq = _operator_coefficient(term)
            sparse_pauli = _add_sparse_pauli(
                sparse_pauli, _excitation_operator(edge_list, p, q, h1_pq)
            )

        else:
            facs_reordered, phase = _to_physicist_index_order(facs)
            h2_pqrs = phase * _operator_coefficient(term)
            (p, q, r, s) = [facs_reordered[i][0] for i in range(4)]  # pylint: disable=invalid-name
            if term_type == TermType.DOUBLE_EXCITATION:
                sparse_pauli = _add_sparse_pauli(
                    sparse_pauli, _double_excitation(edge_list, p, q, r, s, h2_pqrs)
                )
            elif term_type == TermType.COULOMB_EXCHANGE:
                sparse_pauli = _add_sparse_pauli(
                    sparse_pauli, _coulomb_exchange(edge_list, p, q, s, h2_pqrs)
                )
            elif term_type == TermType.NUMBER_EXCITATION:
                # Note that h2_pqrs is not divided by 2 here, as in the aqua code
                sparse_pauli = _add_sparse_pauli(
                    sparse_pauli, _number_excitation(edge_list, p, q, r, s, h2_pqrs)
                )
            else:
                raise ValueError("Unknown interaction: ", term_type)

    return sparse_pauli
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
Example #23
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)
Example #24
0
 def test_init_from_tuple_label(self):
     """Test __init__ for tuple"""
     desired = [((("-", 2), ("+", 10)), (1 + 2j)), ((("-", 12),), 56)]
     # tuple
     actual = FermionicOp(
         [((("-", 2), ("+", 10)), 1 + 2j), ((("-", 12),), 56)],
         register_length=13,
         display_format="dense",
     )
     self.assertEqual(actual._data, desired)
     # list
     actual = FermionicOp(
         [([("-", 2), ("+", 10)], 1 + 2j), ([("-", 12)], 56)],
         register_length=13,
         display_format="dense",
     )
     self.assertListEqual(actual._data, desired)
Example #25
0
    def test_hermiticity(self):
        """test is_hermitian"""
        with self.subTest("operator hermitian"):
            # deliberately define test operator with duplicate terms in case .adjoint() simplifies terms
            fer_op = (1j * FermionicOp("+-NE", display_format="dense") +
                      1j * FermionicOp("+-NE", display_format="dense") +
                      1j * FermionicOp("-+NE", display_format="dense") +
                      1j * FermionicOp("-+NE", display_format="dense") +
                      FermionicOp("+-EN", display_format="dense") -
                      FermionicOp("-+EN", display_format="dense"))
            self.assertTrue(fer_op.is_hermitian())

        with self.subTest("operator not hermitian"):
            fer_op = (1j * FermionicOp("+-NE", display_format="dense") +
                      1j * FermionicOp("+-NE", display_format="dense") -
                      1j * FermionicOp("-+NE", display_format="dense") -
                      1j * FermionicOp("-+NE", display_format="dense"))
            self.assertFalse(fer_op.is_hermitian())
    def _create_base_op(self, indices: tuple[int, ...], coeff: complex,
                        length: int) -> FermionicOp:
        """Creates a single base operator for the given coefficient.

        Args:
            indices: the indices of the current integral.
            coeff: the current integral value.
            length: the register length of the created operator.

        Returns:
            The base operator.
        """
        base_op = FermionicOp(("I_0", coeff),
                              register_length=length,
                              display_format="sparse")
        for i, op in self._calc_coeffs_with_ops(indices):
            base_op @= FermionicOp(f"{op}_{i}", display_format="sparse")
        return base_op
Example #27
0
    def map(self, second_q_op: FermionicOp) -> PauliSumOp:
        if not isinstance(second_q_op, FermionicOp):
            raise TypeError("Type ", type(second_q_op), " not supported.")

        if second_q_op.display_format == "sparse":
            second_q_op = FermionicOp(second_q_op._to_dense_label_data(), display_format="dense")

        edge_list = _bksf_edge_list_fermionic_op(second_q_op)
        sparse_pauli = _convert_operator(second_q_op, edge_list)

        ## Simplify and sort the result
        sparse_pauli = sparse_pauli.simplify()
        indices = sparse_pauli.paulis.argsort()
        table = sparse_pauli.paulis[indices]
        coeffs = sparse_pauli.coeffs[indices]
        sorted_sparse_pauli = SparsePauliOp(table, coeffs)

        return PauliSumOp(sorted_sparse_pauli)
Example #28
0
    def test_to_matrix(self):
        """Test to_matrix"""
        with self.subTest("identity operator matrix"):
            mat = FermionicOp.one(2).to_matrix(sparse=False)
            targ = np.eye(4)
            self.assertTrue(np.allclose(mat, targ))

        with self.subTest("number operator matrix"):
            mat = FermionicOp("IN").to_matrix(sparse=False)
            targ = np.array([[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1]])
            self.assertTrue(np.allclose(mat, targ))

        with self.subTest("emptiness operator matrix"):
            mat = FermionicOp("IE").to_matrix(sparse=False)
            targ = np.array([[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0]])
            self.assertTrue(np.allclose(mat, targ))

        with self.subTest("raising operator matrix"):
            mat = FermionicOp("I+").to_matrix(sparse=False)
            targ = np.array([[0, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 0], [0, 0, -1, 0]])
            self.assertTrue(np.allclose(mat, targ))

        with self.subTest("lowering operator matrix"):
            mat = FermionicOp("I-").to_matrix(sparse=False)
            targ = np.array([[0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, -1], [0, 0, 0, 0]])
            self.assertTrue(np.allclose(mat, targ))

        with self.subTest("nontrivial sparse matrix"):
            mat = FermionicOp([("ENI+", 3j), ("-N+-", -2)]).to_matrix()
            targ = csc_matrix(([-3j, 3j, -2], ([5, 7, 6], [4, 6, 13])), shape=(16, 16))
            self.assertTrue((mat != targ).nnz == 0)

        with self.subTest("Test Hydrogen spectrum"):
            h2_labels = [
                ("+_0 -_1 +_2 -_3", (0.18093120148374142)),
                ("+_0 -_1 -_2 +_3", (-0.18093120148374134)),
                ("-_0 +_1 +_2 -_3", (-0.18093120148374134)),
                ("-_0 +_1 -_2 +_3", (0.18093120148374128)),
                ("+_3 -_3", (-0.4718960038869427)),
                ("+_2 -_2", (-1.2563391028292563)),
                ("+_2 -_2 +_3 -_3", (0.48365053378098793)),
                ("+_1 -_1", (-0.4718960038869427)),
                ("+_1 -_1 +_3 -_3", (0.6985737398458793)),
                ("+_1 -_1 +_2 -_2", (0.6645817352647293)),
                ("+_0 -_0", (-1.2563391028292563)),
                ("+_0 -_0 +_3 -_3", (0.6645817352647293)),
                ("+_0 -_0 +_2 -_2", (0.6757101625347564)),
                ("+_0 -_0 +_1 -_1", (0.48365053378098793)),
            ]
            h2_matrix = FermionicOp(h2_labels, register_length=4).to_matrix()
            evals, evecs = eigs(h2_matrix)
            self.assertTrue(np.isclose(np.min(evals), -1.8572750))
            # make sure the ground state has support only in the 2-particle subspace
            groundstate = evecs[:, np.argmin(evals)]
            for idx in np.where(~np.isclose(groundstate, 0))[0]:
                binary = f"{idx:0{4}b}"
                self.assertEqual(binary.count("1"), 2)
    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)

        # Regression test against https://github.com/Qiskit/qiskit-nature/issues/271
        with self.subTest(
                "Two qubit reduction skipped when operator too small"):
            qubit_conv.two_qubit_reduction = True
            small_op = FermionicOp([("N_0", 1.0), ("E_1", 1.0)],
                                   register_length=2,
                                   display_format="sparse")
            expected_op = 1.0 * (I ^ I) - 0.5 * (I ^ Z) + 0.5 * (Z ^ Z)
            with contextlib.redirect_stderr(io.StringIO()) as out:
                qubit_op = qubit_conv.convert(small_op,
                                              num_particles=self.num_particles)
            self.assertEqual(qubit_op, expected_op)
            self.assertTrue(out.getvalue().strip().startswith(
                "The original qubit operator only contains 2 qubits! "
                "Skipping the requested two-qubit reduction!"))
Example #30
0
    def test_label_display_mode(self, label, pre_processing):
        """test label_display_mode"""
        fer_op = FermionicOp(pre_processing(label), display_format="dense")

        fer_op.display_format = "sparse"
        self.assertListEqual(fer_op.to_list(), str2list(label))
        fer_op.display_format = "dense"
        self.assertNotEqual(fer_op.to_list(), str2list(label))