コード例 #1
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))
コード例 #2
0
 def test_init_multiple_digits(self):
     """Test __init__ for sparse label with multiple digits"""
     actual = FermionicOp([("-_2 +_10", 1 + 2j), ("-_12", 56 + 0j)],
                          register_length=13,
                          display_format="dense")
     desired = [
         ("II-IIIIIII+II", 1 + 2j),
         ("IIIIIIIIIIII-", 56),
     ]
     self.assertListEqual(actual.to_list(), desired)
コード例 #3
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", "second_q/properties/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")))
コード例 #4
0
    def test_init_multiterm(self):
        """Test __init__ with multi terms"""
        with self.subTest("Test 1"):
            labels = [("N", 2), ("-", 3.14)]
            self.assertListEqual(
                FermionicOp(labels, display_format="dense").to_list(), labels)

        with self.subTest("Test 2"):
            labels = [("+-", 1), ("-+", -1)]
            op = FermionicOp([("+_0 -_1", 1.0), ("-_0 +_1", -1.0)],
                             register_length=2,
                             display_format="dense")
            self.assertListEqual(op.to_list(), labels)
コード例 #5
0
def _get_adjacency_matrix(fer_op: FermionicOp) -> np.ndarray:
    """Return an adjacency matrix specifying the edges in the BKSF graph for the
    operator `fer_op`.

    The graph is undirected, so we choose to return the edges in the upper triangle.
    (There are no self edges.) The lower triangle entries are all `False`.

    Args:
      fer_op: The Fermionic operator.

    Returns:
      numpy.ndarray(dtype=bool): edge_matrix the adjacency matrix.
    """
    n_modes = fer_op.register_length
    edge_matrix = np.zeros((n_modes, n_modes), dtype=bool)
    for term in fer_op.to_list():
        if _operator_coefficient(term) != 0:
            _add_edges_for_term(edge_matrix, _operator_string(term))
    return edge_matrix
コード例 #6
0
 def test_init(self, label, pre_processing):
     """Test __init__"""
     fer_op = FermionicOp(pre_processing(label), display_format="dense")
     self.assertListEqual(fer_op.to_list(), [(label, 1)])
     self.assertFermionEqual(eval(repr(fer_op)), fer_op)  # pylint: disable=eval-used
コード例 #7
0
 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)))
コード例 #8
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():
        if _operator_coefficient(term) == 0:
            continue
        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)

    if sparse_pauli is None:
        sparse_pauli = _pauli_id(edge_list.shape[1], complex(0.0))
    return sparse_pauli