Skip to content

Commit

Permalink
Fixed Issue 11026: SparsePauliOp.apply_layout should do nothing if gi…
Browse files Browse the repository at this point in the history
…ven None (#11041)

* fixed issue 11026 by adding condition in apply_layout and implemented test

* fixed formatting

* added expansion of operator if num_qubits is provided and added tests

* fixed finding

* added release note
  • Loading branch information
SoranaAurelia authored Nov 16, 2023
1 parent 3c1a87c commit 8707699
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
16 changes: 12 additions & 4 deletions qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -1109,24 +1109,30 @@ def assign_parameters(
return None if inplace else bound

def apply_layout(
self, layout: TranspileLayout | List[int], num_qubits: int | None = None
self, layout: TranspileLayout | List[int] | None, num_qubits: int | None = None
) -> SparsePauliOp:
"""Apply a transpiler layout to this :class:`~.SparsePauliOp`
Args:
layout: Either a :class:`~.TranspileLayout` or a list of integers.
layout: Either a :class:`~.TranspileLayout`, a list of integers or None.
If both layout and num_qubits are none, a copy of the operator is
returned.
num_qubits: The number of qubits to expand the operator to. If not
provided then if ``layout`` is a :class:`~.TranspileLayout` the
number of the transpiler output circuit qubits will be used by
default. If ``layout`` is a list of integers the permutation
specified will be applied without any expansion.
specified will be applied without any expansion. If layout is
None, the operator will be expanded to the given number of qubits.
Returns:
A new :class:`.SparsePauliOp` with the provided layout applied
"""
from qiskit.transpiler.layout import TranspileLayout

if layout is None and num_qubits is None:
return self.copy()

n_qubits = self.num_qubits
if isinstance(layout, TranspileLayout):
n_qubits = len(layout._output_qubit_list)
Expand All @@ -1138,8 +1144,10 @@ def apply_layout(
f"applied to a {n_qubits} qubit operator"
)
n_qubits = num_qubits
if any(x >= n_qubits for x in layout):
if layout is not None and any(x >= n_qubits for x in layout):
raise QiskitError("Provided layout contains indicies outside the number of qubits.")
if layout is None:
layout = list(range(self.num_qubits))
new_op = type(self)("I" * n_qubits)
return new_op.compose(self, qargs=layout)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
features:
- |
The function :meth:`~.SparsePauliOp.apply_layout` from :class:`.SparsePauliOp` now allows for the
layout argument to also be None. That is, the method can now also be used for circuits where no transpilation/routing
took place (for example when transpiling for a simulator).
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,25 @@ def test_apply_layout_layout_list_and_num_qubits(self):
res = op.apply_layout([4, 0], 5)
self.assertEqual(SparsePauliOp.from_list([("IIIIY", 2), ("IIIIX", 1)]), res)

def test_apply_layout_null_layout_no_num_qubits(self):
"""Test apply_layout with a null layout"""
op = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
res = op.apply_layout(layout=None)
self.assertEqual(op, res)

def test_apply_layout_null_layout_and_num_qubits(self):
"""Test apply_layout with a null layout a num_qubits provided"""
op = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
res = op.apply_layout(layout=None, num_qubits=5)
# this should expand the operator
self.assertEqual(SparsePauliOp.from_list([("IIIII", 1), ("IIIIZ", 2), ("IIIXI", 3)]), res)

def test_apply_layout_null_layout_invalid_num_qubits(self):
"""Test apply_layout with a null layout and num_qubits smaller than capable"""
op = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
with self.assertRaises(QiskitError):
op.apply_layout(layout=None, num_qubits=1)


if __name__ == "__main__":
unittest.main()

0 comments on commit 8707699

Please sign in to comment.