Source code for toqito.channel_props.is_quantum_channel
"""Determines if an input is a quantum channel."""
import numpy as np
from toqito.channel_ops import kraus_to_choi
from toqito.channel_props import is_completely_positive, is_trace_preserving
[docs]
def is_quantum_channel(
phi: np.ndarray | list[list[np.ndarray]],
rtol: float = 1e-05,
atol: float = 1e-08,
) -> bool:
r"""Determine whether the given input is a quantum channel.
For more info, see Section 2.2.1: Definitions and Basic Notions Concerning Channels from
[@Watrous_2018_TQI].
A map \(\Phi \in \text{T} \left(\mathcal{X}, \mathcal{Y} \right)\) is a *quantum
channel* for some choice of complex Euclidean spaces \(\mathcal{X}\)
and \(\mathcal{Y}\), if it holds that:
1. \(\Phi\) is completely positive.
2. \(\Phi\) is trace preserving.
Examples:
We can specify the input as a list of Kraus operators. Consider the map \(\Phi\) defined as
\[
\Phi(X) = X - U X U^*
\]
where
\[
U = \frac{1}{\sqrt{2}}
\begin{pmatrix}
1 & 1 \\
-1 & 1
\end{pmatrix}.
\]
To check if this is a valid quantum channel or not,
```python exec="1" source="above"
import numpy as np
from toqito.matrices import pauli
from toqito.channel_props import is_quantum_channel
U = (1/np.sqrt(2))*np.array([[1, 1],[-1, 1]])
X = pauli("X")
phi = X - np.matmul(U, np.matmul(X, np.conjugate(U)))
print(is_quantum_channel(phi))
```
If we instead check for the validity of depolarizing channel being a valid quantum channel,
```python exec="1" source="above"
from toqito.channels import depolarizing
from toqito.channel_props import is_quantum_channel
choi_depolarizing = depolarizing(dim=2, param_p=0.2)
print(is_quantum_channel(choi_depolarizing))
```
Args:
phi: The channel provided as either a Choi matrix or a list of Kraus operators.
rtol: The relative tolerance parameter (default 1e-05).
atol: The absolute tolerance parameter (default 1e-08).
Returns:
`True` if the channel is a quantum channel, and `False` otherwise.
"""
# If the variable `phi` is provided as a list, we assume this is a list
# of Kraus operators.
if not (
isinstance(phi, np.ndarray)
or (
isinstance(phi, list)
and all(isinstance(row, list) and all(isinstance(op, np.ndarray) for op in row) for row in phi)
)
):
raise TypeError(
"phi must be either a numpy array (Choi matrix) or a list of lists of numpy arrays (Kraus operators)."
)
if isinstance(phi, list):
phi = kraus_to_choi(phi)
# A valid quantum channel is a superoperator that is both completely
# positive and trace-preserving.
try:
return is_completely_positive(phi, rtol, atol) and is_trace_preserving(phi, rtol, atol)
except Exception:
return False