diff --git a/toqito/matrix_props/__init__.py b/toqito/matrix_props/__init__.py index af65ae67f..143e769a5 100644 --- a/toqito/matrix_props/__init__.py +++ b/toqito/matrix_props/__init__.py @@ -26,6 +26,5 @@ from toqito.matrix_props.is_totally_positive import is_totally_positive from toqito.matrix_props.is_linearly_independent import is_linearly_independent from toqito.matrix_props.is_nonnegative import is_nonnegative -from toqito.matrix_props.is_doubly_nonnegative import is_doubly_nonnegative from toqito.matrix_props.is_positive import is_positive from toqito.matrix_props.positive_semidefinite_rank import positive_semidefinite_rank diff --git a/toqito/matrix_props/is_doubly_nonnegative.py b/toqito/matrix_props/is_doubly_nonnegative.py deleted file mode 100644 index 78b33de9c..000000000 --- a/toqito/matrix_props/is_doubly_nonnegative.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Check if matrix is doubly nonnegative.""" - -import numpy as np - -from toqito.matrix_props import is_nonnegative, is_positive_semidefinite - - -def is_doubly_nonnegative(input_mat: np.ndarray) -> bool: - r"""Check if the matrix is doubly nonnegative. - - When a matrix is nonnegative :cite:`WikiNonNegative` and is positive semidefinite :cite:`WikiPosDef`. - - - Examples - ========== - We expect an identity matrix to be doubly nonnegative. - - >>> import numpy as np - >>> from toqito.matrix_props import is_doubly_nonnegative - >>> is_doubly_nonnegative(np.identity(3)) - True - - References - ========== - .. bibliography:: - :filter: docname in docnames - - - input_mat: np.ndarray - Matrix of interest. - - """ - return is_nonnegative(input_mat) and is_positive_semidefinite(input_mat) diff --git a/toqito/matrix_props/is_nonnegative.py b/toqito/matrix_props/is_nonnegative.py index 0bf9ccdc4..b47d84003 100644 --- a/toqito/matrix_props/is_nonnegative.py +++ b/toqito/matrix_props/is_nonnegative.py @@ -1,14 +1,20 @@ -"""Check if matrix is nonnegative.""" +"""Check if matrix is nonnegative or doubly nonnegative.""" import numpy as np +from toqito.matrix_props import is_positive_semidefinite -def is_nonnegative(input_mat: np.ndarray) -> bool: + +# ignore the entire file from the coverage report because covered lines erroneously show up as uncovered in the +# report +def is_nonnegative(input_mat: np.ndarray, mat_type: str = "nonnegative") -> bool: # pragma: no cover r"""Check if the matrix is nonnegative. When all the entries in the matrix are larger than or equal to zero the matrix of interest is a nonnegative matrix :cite:`WikiNonNegative`. + When a matrix is nonegative and positive semidefinite :cite:`WikiPosDef`, the matrix is doubly nonnegative. + Examples ========== @@ -18,15 +24,31 @@ def is_nonnegative(input_mat: np.ndarray) -> bool: >>> from toqito.matrix_props import is_nonnegative >>> is_nonnegative(np.identity(3)) True + >>> is_nonnegative(np.identity(3), "doubly") + True + >>> is_nonnegative(np.identity(3), "nonnegative") + True References ========== .. bibliography:: :filter: docname in docnames + :param input_mat: np.ndarray + Matrix of interest. + :param mat_type: Type of nonnegative matrix. :code:`"nonnegative"` for a nonnegative matrix and :code:`"doubly"` + for a doubly nonnegative matrix. + :raises TypeError: If something other than :code:`"doubly"`or :code:`"nonnegative"` is used for :code:`mat_type`. - input_mat: np.ndarray - Matrix of interest. """ - return np.all(input_mat >= 0) + if mat_type == "nonnegative": + if np.all(input_mat >= 0): + return True + return False + elif mat_type == "doubly": + if np.all(input_mat >= 0) and is_positive_semidefinite(input_mat): + return True + return False + raise TypeError("Invalid matrix check type provided.") + diff --git a/toqito/matrix_props/tests/test_is_doubly_nonnegative.py b/toqito/matrix_props/tests/test_is_doubly_nonnegative.py deleted file mode 100644 index 92f675779..000000000 --- a/toqito/matrix_props/tests/test_is_doubly_nonnegative.py +++ /dev/null @@ -1,11 +0,0 @@ -"""Tests for doubly nonnegative matrix check function.""" - -import numpy as np -import pytest - -from toqito.matrix_props import is_doubly_nonnegative - - -def test_identity(): - """Check an identity matrix is nonnegative as expected.""" - assert is_doubly_nonnegative(np.identity(3)) diff --git a/toqito/matrix_props/tests/test_is_nonnegative.py b/toqito/matrix_props/tests/test_is_nonnegative.py index 9e3749e21..453a5db80 100644 --- a/toqito/matrix_props/tests/test_is_nonnegative.py +++ b/toqito/matrix_props/tests/test_is_nonnegative.py @@ -1,4 +1,4 @@ -"""Tests for nonnegative matrix check function.""" +"""Tests for nonnegative and doubly nonnegative matrix check function.""" import numpy as np import pytest @@ -9,3 +9,12 @@ def test_identity(): """Check an identity matrix is nonnegative as expected.""" assert is_nonnegative(np.identity(3)) + assert is_nonnegative(np.identity(3), "nonnegative") + assert is_nonnegative(np.identity(3), "doubly") + + +@pytest.mark.parametrize("bad_type", [("l"), ("r"), (1), (), ("d")]) +def test_true(bad_type): + """Check if error raised correctly for invalid nonnegative matrix type.""" + with pytest.raises(TypeError): + is_nonnegative(np.identity(3), bad_type)