Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,26 @@ impl QubitSparsePauliList {
}
}
}

// Check if the elements of `self` commute with the elements of `other`.
pub fn commutes(&self, other: &QubitSparsePauliList) -> Result<Array2<bool>, ArithmeticError> {
if self.num_qubits != other.num_qubits {
return Err(ArithmeticError::MismatchedQubits {
left: self.num_qubits,
right: other.num_qubits,
});
}

Ok(Array2::from_shape_fn(
(self.num_terms(), other.num_terms()),
|(i, j)| {
self.term(i)
.to_term()
.commutes(&other.term(j).to_term())
.unwrap()
},
))
}
}

type RawParts = (Vec<Pauli>, Vec<u32>, Vec<usize>);
Expand Down Expand Up @@ -836,7 +856,7 @@ impl QubitSparsePauli {
}
}

// Check if `self` commutes with `other`
// Check if `self` commutes with `other`.
pub fn commutes(&self, other: &QubitSparsePauli) -> Result<bool, ArithmeticError> {
if self.num_qubits != other.num_qubits {
return Err(ArithmeticError::MismatchedQubits {
Expand Down Expand Up @@ -1465,7 +1485,7 @@ impl PyQubitSparsePauli {
self.compose(other)
}

/// Check if `self`` commutes with another qubit sparse pauli.
/// Check if `self`` commutes with another qubit sparse Pauli.
///
/// Args:
/// other (QubitSparsePauli): the qubit sparse Pauli to check for commutation with.
Expand Down Expand Up @@ -2104,6 +2124,17 @@ impl PyQubitSparsePauliList {
Ok(out.into_pyarray(py).unbind())
}

/// Check if the elements of `self`` commute with another qubit sparse Pauli list.
///
/// Args:
/// other (QubitSparsePauliList): the qubit sparse Pauli list to check for commutation with.
#[pyo3(signature = (other))]
fn commutes(&self, py: Python, other: &PyQubitSparsePauliList) -> PyResult<Py<PyArray2<bool>>> {
let slf_inner = self.inner.read().map_err(|_| InnerReadError)?;
let other_inner = other.inner.read().map_err(|_| InnerReadError)?;
Ok(slf_inner.commutes(&other_inner)?.into_pyarray(py).unbind())
}

/// Return a :class:`~.quantum_info.PauliList` representing the same phaseless list of Paulis.
fn to_pauli_list<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
let inner = self.inner.read().map_err(|_| InnerReadError)?;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
features_quantum_info:
- |
Added the method :meth:`.QubitSparsePauliList.commutes`. This method returns the commutation
relations of this :class:`.QubitSparsePauliList` with another as an array of bools.
21 changes: 21 additions & 0 deletions test/python/quantum_info/test_qubit_sparse_pauli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,27 @@ def test_to_dense_array(self):
expected = np.array([[0, 2, 0], [0, 0, 3], [1, 0, 0]], dtype=np.uint8)
np.testing.assert_array_equal(pauli_list.to_dense_array(), expected, strict=True)

def test_commutes(self):
p0 = QubitSparsePauliList.from_list(["XIY", "IXI", "IZI"])
p1 = QubitSparsePauliList.from_list(["IZI", "ZII"])
expected = np.array([[True, False], [False, True], [True, True]], dtype=np.bool_)
np.testing.assert_array_equal(p0.commutes(p1), expected, strict=True)
np.testing.assert_array_equal(p1.commutes(p0), expected.T, strict=True)

p0 = QubitSparsePauliList.from_sparse_list([], num_qubits=3)
p1 = QubitSparsePauliList.from_list(["ZZZ"])
expected = np.empty((0, 1), dtype=np.bool_)
np.testing.assert_array_equal(p0.commutes(p1), expected, strict=True)
np.testing.assert_array_equal(p1.commutes(p0), expected.T, strict=True)

def test_commutes_errors(self):
p0 = QubitSparsePauliList.from_label("XZYI")
p1 = QubitSparsePauliList.from_label("ZIY")
with self.assertRaisesRegex(ValueError, "mismatched numbers of qubits: 4, 3"):
p0.commutes(p1)
with self.assertRaisesRegex(ValueError, "mismatched numbers of qubits: 3, 4"):
p1.commutes(p0)


def canonicalize_term(pauli, indices):
# canonicalize a sparse list term by sorting by indices (which is unique as
Expand Down
Loading