Skip to content

Commit

Permalink
Move sort to helper function
Browse files Browse the repository at this point in the history
  • Loading branch information
chriseclectic committed Jun 5, 2024
1 parent cc269bc commit e51da9f
Showing 1 changed file with 28 additions and 23 deletions.
51 changes: 28 additions & 23 deletions qiskit_aer/noise/errors/pauli_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ def __eq__(self, other):
# Use BaseOperator eq to check type and shape
if not super().__eq__(other):
return False
lhs = self.simplify()._sort()
rhs = other.simplify()._sort()
return (
lhs.size == rhs.size
and np.allclose(lhs.probabilities, rhs.probabilities)
and lhs.paulis == rhs.paulis
)
lhs = self.simplify()
rhs = other.simplify()
if lhs.size != rhs.size:
return False
lpaulis, lprobs = sort_paulis(lhs.paulis, lhs.probabilities)
rpaulis, rprobs = sort_paulis(rhs.paulis, rhs.probabilities)
return np.allclose(lprobs, rprobs) and lpaulis == rpaulis

@property
def size(self):
Expand Down Expand Up @@ -175,22 +175,6 @@ def simplify(self, atol: float | None = None, rtol: float | None = None) -> Paul
simplified = SparsePauliOp(self.paulis, self.probabilities).simplify(atol=atol, rtol=rtol)
return PauliError(simplified.paulis, simplified.coeffs.real)

def _sort(self) -> PauliError:
"""Sort terms in a way that can be used for equality checks between simplified error ops"""
# Get packed bigs tableau of Paulis
# Use numpy sorted and enumerate to implement an argsort of
# rows based on python tuple sorting
tableau = np.hstack([self.paulis.x, self.paulis.z])
packed = np.packbits(tableau, axis=1)
index = [
tup[-1]
for tup in sorted(
(*row.tolist(), prob, i)
for i, (row, prob) in enumerate(zip(packed, self.probabilities))
)
]
return PauliError(self.paulis[index], self.probabilities[index])

def to_quantum_error(self) -> "QuantumError":
"""Convert to a general QuantumError object."""
if not self.is_cptp():
Expand Down Expand Up @@ -252,3 +236,24 @@ def from_dict(error: dict) -> PauliError:
paulis.append(inst[0]["params"][0])

return PauliError(paulis, probabilities)


def sort_paulis(paulis: PauliList, coeffs: Sequence | None = None) -> tuple[PauliList, Sequence]:
"""Sort terms in a way that can be used for equality checks between simplified error ops"""
if coeffs is not None and len(coeffs) != len(paulis):
raise ValueError("paulis and coefffs must have the same length.")

# Get packed bigs tableau of Paulis
# Use numpy sorted and enumerate to implement an argsort of
# rows based on python tuple sorting
tableau = np.hstack([paulis.x, paulis.z])
packed = np.packbits(tableau, axis=1)
if coeffs is None:
unsorted = ((*row.tolist(), i) for i, row in enumerate(packed))
else:
unsorted = ((*row.tolist(), coeff, i) for i, (row, coeff) in enumerate(zip(packed, coeffs)))
index = [tup[-1] for tup in sorted(unsorted)]

if coeffs is None:
return paulis[index]
return paulis[index], coeffs[index]

0 comments on commit e51da9f

Please sign in to comment.