Skip to content

Commit

Permalink
feat: add method to convert BitArray into boolean array (#13653)
Browse files Browse the repository at this point in the history
* feat: add method to convert `BitArray` into boolean array

* docs: minor changes in docstrings

* docs: add release note
  • Loading branch information
amiigas authored Jan 21, 2025
1 parent a7df171 commit 400f22d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
23 changes: 23 additions & 0 deletions qiskit/primitives/containers/bit_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,29 @@ def from_samples(
array = np.frombuffer(data, dtype=np.uint8, count=len(data))
return BitArray(array.reshape(-1, num_bytes), num_bits)

def to_bool_array(self, order: Literal["big", "little"] = "big") -> NDArray[np.bool_]:
"""Convert this :class:`~BitArray` to a boolean array.
Args:
order: One of ``"big"`` or ``"little"``, respectively indicating whether the most significant
bit or the least significant bit of each bitstring should be placed at ``[..., 0]``.
Returns:
A NumPy array of bools.
Raises:
ValueError: If the order is not one of ``"big"`` or ``"little"``.
"""
if order not in ("big", "little"):
raise ValueError(
f"Invalid value for order: '{order}'. Valid values are 'big' and 'little'."
)

arr = np.unpackbits(self.array, axis=-1)[..., -self.num_bits :]
if order == "little":
arr = arr[..., ::-1]
return arr.astype(np.bool_)

def get_counts(self, loc: int | tuple[int, ...] | None = None) -> dict[str, int]:
"""Return a counts dictionary with bitstring keys.
Expand Down
5 changes: 5 additions & 0 deletions releasenotes/notes/add-bool-bitarray-ddc30e5280f21c67.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
features_primitives:
- |
Added :meth:`~BitArray.to_bool_array` method to :class:`~BitArray` class that returns the bit array
as a boolean NumPy array. The ``order`` argument can be used to specify the endianness of the output array.
30 changes: 30 additions & 0 deletions test/python/primitives/containers/test_bit_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,36 @@ def test_from_bool_array(self):
[[[1, 0, 1, 0], [0, 0, 1, 1]], [[1, 0, 0, 0], [0, 0, 0, 1]]], order="bg"
)

def test_to_bool_array(self):
"""Test the to_bool_array method."""

bit_array = BitArray(u_8([[[10], [3]], [[8], [1]]]), 4)
expected_array = np.array(
[[[1, 0, 1, 0], [0, 0, 1, 1]], [[1, 0, 0, 0], [0, 0, 0, 1]]], dtype=np.bool_
)
self.assertTrue(np.array_equal(bit_array.to_bool_array(), expected_array))

bit_array = BitArray(u_8([[[10], [3]], [[8], [1]]]), 4)
expected_array = np.array(
[[[0, 1, 0, 1], [1, 1, 0, 0]], [[0, 0, 0, 1], [1, 0, 0, 0]]], dtype=np.bool_
)
self.assertTrue(np.array_equal(bit_array.to_bool_array(order="little"), expected_array))

bit_array = BitArray(u_8([[7, 3, 1]]), 21)
expected_array = np.array(
[[0, 0, 1, 1, 1] + [0, 0, 0, 0, 0, 0, 1, 1] + [0, 0, 0, 0, 0, 0, 0, 1]], dtype=np.bool_
)
self.assertTrue(np.array_equal(bit_array.to_bool_array(), expected_array))

bit_array = BitArray(u_8([[7, 3, 1]]), 21)
expected_array = np.array(
[[1, 0, 0, 0, 0, 0, 0, 0] + [1, 1, 0, 0, 0, 0, 0, 0] + [1, 1, 1, 0, 0]], dtype=np.bool_
)
self.assertTrue(np.array_equal(bit_array.to_bool_array(order="little"), expected_array))

with self.assertRaisesRegex(ValueError, "Invalid value for order"):
bit_array.to_bool_array(order="invalid")

@ddt.data("counts", "int", "hex", "bit")
def test_from_counts(self, counts_type):
"""Test the from_counts static constructor."""
Expand Down

0 comments on commit 400f22d

Please sign in to comment.