Skip to content

Commit

Permalink
Document conversion tools between channel representations (#4554)
Browse files Browse the repository at this point in the history
  • Loading branch information
viathor committed Oct 6, 2021
1 parent 09da391 commit e66ac53
Showing 1 changed file with 186 additions and 6 deletions.
192 changes: 186 additions & 6 deletions cirq-core/cirq/qis/channels.py
Expand Up @@ -21,7 +21,35 @@


def kraus_to_choi(kraus_operators: Sequence[np.ndarray]) -> np.ndarray:
"""Returns the unique Choi matrix corresponding to a Kraus representation of a channel."""
r"""Returns the unique Choi matrix corresponding to a Kraus representation of a channel.
Quantum channel E: L(H1) -> L(H2) may be described by a collection of operators A_i, called
Kraus operators, such that
$$
E(\rho) = \sum_i A_i \rho A_i^\dagger.
$$
Kraus representation is not unique. Alternatively, E may be specified by its Choi matrix J(E)
defined as
$$
J(E) = (E \otimes I)(|\phi\rangle\langle\phi|)
$$
where $|\phi\rangle = \sum_i|i\rangle|i\rangle$ is the unnormalized maximally entangled state
and I: L(H1) -> L(H1) is the identity map. Choi matrix is unique for a given channel.
The computation of the Choi matrix from a Kraus representation is essentially a reconstruction
of a matrix from its eigendecomposition. It has the cost of O(kd**4) where k is the number of
Kraus operators and d is the dimension of the input and output Hilbert space.
Args:
kraus_operators: Sequence of Kraus operators specifying a quantum channel.
Returns:
Choi matrix of the channel specified by kraus_operators.
"""
d = np.prod(kraus_operators[0].shape, dtype=np.int64)
c = np.zeros((d, d), dtype=np.complex128)
for k in kraus_operators:
Expand All @@ -31,7 +59,28 @@ def kraus_to_choi(kraus_operators: Sequence[np.ndarray]) -> np.ndarray:


def choi_to_kraus(choi: np.ndarray, atol: float = 1e-10) -> Sequence[np.ndarray]:
"""Returns a Kraus representation of a channel with given Choi matrix.
r"""Returns a Kraus representation of a channel with given Choi matrix.
Quantum channel E: L(H1) -> L(H2) may be described by a collection of operators A_i, called
Kraus operators, such that
$$
E(\rho) = \sum_i A_i \rho A_i^\dagger.
$$
Kraus representation is not unique. Alternatively, E may be specified by its Choi matrix J(E)
defined as
$$
J(E) = (E \otimes I)(|\phi\rangle\langle\phi|)
$$
where $|\phi\rangle = \sum_i|i\rangle|i\rangle$ is the unnormalized maximally entangled state
and I: L(H1) -> L(H1) is the identity map. Choi matrix is unique for a given channel.
The most expensive step in the computation of a Kraus representation from a Choi matrix is
the eigendecomposition of the Choi. Therefore, the cost of the conversion is O(d**6) where
d is the dimension of the input and output Hilbert space.
Args:
choi: Choi matrix of the channel.
Expand Down Expand Up @@ -67,7 +116,36 @@ def kraus_to_channel_matrix(kraus_operators: Sequence[np.ndarray]) -> np.ndarray


def kraus_to_superoperator(kraus_operators: Sequence[np.ndarray]) -> np.ndarray:
"""Returns the matrix representation of the linear map with given Kraus operators."""
r"""Returns the matrix representation of the linear map with given Kraus operators.
Quantum channel E: L(H1) -> L(H2) may be described by a collection of operators A_i, called
Kraus operators, such that
$$
E(\rho) = \sum_i A_i \rho A_i^\dagger.
$$
Kraus representation is not unique. Alternatively, E may be specified by its superoperator
matrix K(E) defined so that
$$
K(E) vec(\rho) = vec(E(\rho))
$$
where the vectorization map $vec$ rearranges d-by-d matrices into d**2-dimensional vectors.
Superoperator matrix is unique for a given channel. It is also called the natural
representation of a quantum channel.
The computation of the superoperator matrix from a Kraus representation involves the sum of
Kronecker products of all Kraus operators. This has the cost of O(kd**4) where k is the number
of Kraus operators and d is the dimension of the input and output Hilbert space.
Args:
kraus_operators: Sequence of Kraus operators specifying a quantum channel.
Returns:
Superoperator matrix of the channel specified by kraus_operators.
"""
d_out, d_in = kraus_operators[0].shape
m = np.zeros((d_out * d_out, d_in * d_in), dtype=np.complex128)
for k in kraus_operators:
Expand All @@ -76,12 +154,79 @@ def kraus_to_superoperator(kraus_operators: Sequence[np.ndarray]) -> np.ndarray:


def superoperator_to_kraus(superoperator: np.ndarray) -> Sequence[np.ndarray]:
"""Returns a Kraus representation of a channel specified via the superoperator matrix."""
r"""Returns a Kraus representation of a channel specified via the superoperator matrix.
Quantum channel E: L(H1) -> L(H2) may be described by a collection of operators A_i, called
Kraus operators, such that
$$
E(\rho) = \sum_i A_i \rho A_i^\dagger.
$$
Kraus representation is not unique. Alternatively, E may be specified by its superoperator
matrix K(E) defined so that
$$
K(E) vec(\rho) = vec(E(\rho))
$$
where the vectorization map $vec$ rearranges d-by-d matrices into d**2-dimensional vectors.
Superoperator matrix is unique for a given channel. It is also called the natural
representation of a quantum channel.
The most expensive step in the computation of a Kraus representation from a superoperator
matrix is eigendecomposition. Therefore, the cost of the conversion is O(d**6) where d is
the dimension of the input and output Hilbert space.
Args:
superoperator: Superoperator matrix specifying a quantum channel.
Returns:
Sequence of Kraus operators of the channel specified by superoperator.
Raises:
ValueError: If superoperator is not a valid superoperator matrix.
"""
return choi_to_kraus(superoperator_to_choi(superoperator))


def choi_to_superoperator(choi: np.ndarray) -> np.ndarray:
"""Returns the superoperator matrix of a quantum channel specified via the Choi matrix."""
r"""Returns the superoperator matrix of a quantum channel specified via the Choi matrix.
Quantum channel E: L(H1) -> L(H2) may be specified by its Choi matrix J(E) defined as
$$
J(E) = (E \otimes I)(|\phi\rangle\langle\phi|)
$$
where $|\phi\rangle = \sum_i|i\rangle|i\rangle$ is the unnormalized maximally entangled state
and I: L(H1) -> L(H1) is the identity map. Choi matrix is unique for a given channel.
Alternatively, E may be specified by its superoperator matrix K(E) defined so that
$$
K(E) vec(\rho) = vec(E(\rho))
$$
where the vectorization map $vec$ rearranges d-by-d matrices into d**2-dimensional vectors.
Superoperator matrix is unique for a given channel. It is also called the natural
representation of a quantum channel.
A quantum channel can be viewed as a tensor with four indices. Different ways of grouping
the indices into two pairs yield different matrix representations of the channel, including
the superoperator and Choi representations. Hence, the conversion between the superoperator
and Choi matrices is a permutation of matrix elements effected by reshaping the array and
swapping its axes. Therefore, its cost is O(d**4) where d is the dimension of the input and
output Hilbert space.
Args:
choi: Choi matrix specifying a quantum channel.
Returns:
Superoperator matrix of the channel specified by choi.
Raises:
ValueError: If Choi is not Hermitian or is of invalid shape.
"""
d = int(np.round(np.sqrt(choi.shape[0])))
if choi.shape != (d * d, d * d):
raise ValueError(f"Invalid Choi matrix shape, expected {(d * d, d * d)}, got {choi.shape}")
Expand All @@ -94,7 +239,42 @@ def choi_to_superoperator(choi: np.ndarray) -> np.ndarray:


def superoperator_to_choi(superoperator: np.ndarray) -> np.ndarray:
"""Returns the Choi matrix of a quantum channel specified via the superoperator matrix."""
r"""Returns the Choi matrix of a quantum channel specified via the superoperator matrix.
Quantum channel E: L(H1) -> L(H2) may be specified by its Choi matrix J(E) defined as
$$
J(E) = (E \otimes I)(|\phi\rangle\langle\phi|)
$$
where $|\phi\rangle = \sum_i|i\rangle|i\rangle$ is the unnormalized maximally entangled state
and I: L(H1) -> L(H1) is the identity map. Choi matrix is unique for a given channel.
Alternatively, E may be specified by its superoperator matrix K(E) defined so that
$$
K(E) vec(\rho) = vec(E(\rho))
$$
where the vectorization map $vec$ rearranges d-by-d matrices into d**2-dimensional vectors.
Superoperator matrix is unique for a given channel. It is also called the natural
representation of a quantum channel.
A quantum channel can be viewed as a tensor with four indices. Different ways of grouping
the indices into two pairs yield different matrix representations of the channel, including
the superoperator and Choi representations. Hence, the conversion between the superoperator
and Choi matrices is a permutation of matrix elements effected by reshaping the array and
swapping its axes. Therefore, its cost is O(d**4) where d is the dimension of the input and
output Hilbert space.
Args:
superoperator: Superoperator matrix specifying a quantum channel.
Returns:
Choi matrix of the channel specified by superoperator.
Raises:
ValueError: If superoperator has invalid shape.
"""
d = int(np.round(np.sqrt(superoperator.shape[0])))
if superoperator.shape != (d * d, d * d):
raise ValueError(
Expand Down

0 comments on commit e66ac53

Please sign in to comment.