Example #1
0
def is_positive_definite(mat: np.ndarray,
                         rtol: float = 1e-05,
                         atol: float = 1e-08) -> bool:
    r"""
    Check if matrix is positive definite (PD) [WikPD]_.

    Examples
    ==========

    Consider the following matrix

    .. math::
        A = \begin{pmatrix}
                2 & -1 & 0 \\
                -1 & 2 & -1 \\
                0 & -1 & 2
            \end{pmatrix}

    our function indicates that this is indeed a positive definite matrix.

    >>> from toqito.matrix_props import is_positive_definite
    >>> import numpy as np
    >>> A = np.array([[2, -1, 0], [-1, 2, -1], [0, -1, 2]])
    >>> is_positive_definite(A)
    True

    Alternatively, the following example matrix :math:`B` defined as

    .. math::
        B = \begin{pmatrix}
                -1 & -1 \\
                -1 & -1
            \end{pmatrix}

    is not positive definite.

    >>> from toqito.matrix_props import is_positive_definite
    >>> import numpy as np
    >>> B = np.array([[-1, -1], [-1, -1]])
    >>> is_positive_definite(B)
    False

    See Also
    ========
    is_positive_semidefinite

    References
    ==========
    .. [WikPD] Wikipedia: Definiteness of a matrix.
        https://en.wikipedia.org/wiki/Definiteness_of_a_matrix

    :param mat: Matrix to check.
    :param rtol: The relative tolerance parameter (default 1e-05).
    :param atol: The absolute tolerance parameter (default 1e-08).
    :return: Return :code:`True` if matrix is positive definite, and :code:`False` otherwise.
    """
    if not is_hermitian(mat, rtol=rtol, atol=atol):
        return False
    evals, _ = np.linalg.eigh(mat)
    return all(x > -abs(atol) for x in evals)
Example #2
0
def test_is_hermitian():
    """Test if matrix is Hermitian."""
    mat = np.array([[2, 2 + 1j, 4], [2 - 1j, 3, 1j], [4, -1j, 1]])
    np.testing.assert_equal(is_hermitian(mat), True)
Example #3
0
def test_is_non_hermitian():
    """Test non-Hermitian matrix."""
    mat = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    np.testing.assert_equal(is_hermitian(mat), False)
Example #4
0
def is_herm_preserving(
    phi: Union[np.ndarray, List[List[np.ndarray]]],
    rtol: float = 1e-05,
    atol: float = 1e-08,
) -> bool:
    r"""
    Determine whether the given channel is Hermitian-preserving [WatH18]_.

    A map :math:`\Phi \in \text{T} \left(\mathcal{X}, \mathcal{Y} \right)` is
    *Hermitian-preserving* if it holds that

    .. math::
        \Phi(H) \in \text{Herm}(\mathcal{Y})

    for every Hermitian operator :math:`H \in \text{Herm}(\mathcal{X})`.

    Examples
    ==========

    The map :math:`\Phi` defined as

    .. math::
        \Phi(X) = X - U X U^*

    is Hermitian-preserving, where

    .. math::
        U = \frac{1}{\sqrt{2}}
        \begin{pmatrix}
            1 & 1 \\
            -1 & 1
        \end{pmatrix}.

    >>> import numpy as np
    >>> from toqito.channel_props import is_herm_preserving
    >>> unitary_mat = np.array([[1, 1], [-1, 1]]) / np.sqrt(2)
    >>> kraus_ops = [[np.identity(2), np.identity(2)], [unitary_mat, -unitary_mat]]
    >>> is_herm_preserving(kraus_ops)
    True

    We may also verify whether the corresponding Choi matrix of a given map is
    Hermitian-preserving. The swap operator is the Choi matrix of the transpose map, which is
    Hermitian-preserving as can be seen as follows:

    >>> import numpy as np
    >>> from toqito.perms import swap_operator
    >>> from toqito.channel_props import is_herm_preserving
    >>> unitary_mat = np.array([[1, 1], [-1, 1]]) / np.sqrt(2)
    >>> choi_mat = swap_operator(3)
    >>> is_herm_preserving(choi_mat)
    True

    References
    ==========
    .. [WatH18] Watrous, John.
        "The theory of quantum information."
        Section: "Linear maps of square operators".
        Cambridge University Press, 2018.

    :param phi: The channel provided as either a Choi matrix or a list of Kraus operators.
    :param rtol: The relative tolerance parameter (default 1e-05).
    :param atol: The absolute tolerance parameter (default 1e-08).
    :return: True if the channel is Hermitian-preserving, and False otherwise.
    """
    # If the variable `phi` is provided as a list, we assume this is a list
    # of Kraus operators.
    if isinstance(phi, list):
        phi = kraus_to_choi(phi)

    # Phi is Hermiticity-preserving if and only if its Choi matrix is Hermitian.
    if phi.shape[0] != phi.shape[1]:
        return False
    return is_hermitian(phi, rtol=rtol, atol=atol)
Example #5
0
def test_is_hermitian_not_square():
    """Input must be a square matrix."""
    mat = np.array([[-1, 1, 1], [1, 2, 3]])
    np.testing.assert_equal(is_hermitian(mat), False)