toqito.channel_ops.dual_channel =============================== .. py:module:: toqito.channel_ops.dual_channel .. autoapi-nested-parse:: Computes the dual of a map. Module Contents --------------- .. py:function:: dual_channel(phi_op, dims = None) Compute the dual of a map (quantum channel). (Section: Representations and Characterizations of Channels of [@Watrous_2018_TQI]). The map can be represented as a Choi matrix, with optional specification of input and output dimensions. If the input channel maps \(M_{r,c}\) to \(M_{x,y}\) then `dim` should be the list `[[r,x], [c,y]]`. If it maps \(M_m\) to \(M_n\), then `dim` can simply be the vector `[m,n]`. In this case the Choi matrix of the dual channel is returned, obtained by swapping input and output (see [`swap`][toqito.perms.swap.swap]), and complex conjugating all elements. The map can also be represented as a list of Kraus operators. A list of lists, each containing two elements, corresponds to the families of operators \(\{(A_a, B_a)\}\) representing the map \[ \Phi(X) = \sum_a A_a X B^*_a. \] The dual map is obtained by taking the Hermitian adjoint of each operator. If `phi_op` is given as a one-dimensional list, \(\{A_a\}\), it is interpreted as the completely positive map \[ \Phi(X) = \sum_a A_a X A^*_a. \] .. rubric:: Examples When a channel is represented by a 1-D list of of Kraus operators, the CPTP dual channel can be determined as shown below. ```python exec="1" source="above" import numpy as np from toqito.channel_ops import dual_channel kraus_1 = np.array([[1, 0, 1j, 0]]) kraus_2 = np.array([[0, 1, 0, 1j]]) kraus_list = [kraus_1, kraus_2] dual_kraus = dual_channel(kraus_list) for i, op in enumerate(dual_kraus, start=1): print(f"\nDual Kraus operator {i}:") print(op) ``` If the input channel's dimensions are different from the output dual channel's dimensions, ```python exec="1" source="above" import numpy as np from toqito.channel_ops import dual_channel from toqito.perms import swap_operator input_op = swap_operator([2, 3]) output = dual_channel(input_op, [[3, 2], [2, 3]]) print(output) ``` :raises ValueError: If matrices are not Choi matrix. :param phi_op: A superoperator. It should be provided either as a Choi matrix, or as a (1d or 2d) list of numpy arrays :param whose entries are its Kraus operators.: :param dims: Dimension of the input and output systems, for Choi matrix representation. If `None`, try to infer them :param from `phi_op.shape`.: :returns: The map dual to `phi_op`, in the same representation.