Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

matrix_props: Check if stochastic or doubly stochastic #723

Merged
merged 13 commits into from
Aug 7, 2024
15 changes: 15 additions & 0 deletions docs/refs.bib
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ @article{Lupo_2008_Bipartite


#Last name begins with M

@misc{Matsumoto_2010_Reverse,
title={Reverse test and quantum analogue of classical fidelity and generalized fidelity},
author={Matsumoto, Keiji},
Expand Down Expand Up @@ -1122,6 +1123,13 @@ @misc{WikiDiagDom

}

@misc{WikiDoublyStichasticMatrix,
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
author = "Wikipedia",
title = "Doubly Stochastic Matrix",
howpublished = {https://en.wikipedia.org/wiki/Doubly_stochastic_matrix}

}

@misc{WikiFidQuant,
author = "Wikipedia",
title = "Fidelity of quantum states",
Expand Down Expand Up @@ -1389,6 +1397,13 @@ @misc{WikiSymMat

}

@misc{WikiStichasticMatrix,
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
author = "Wikipedia",
title = "Stochastic Matrix",
howpublished = {https://en.wikipedia.org/wiki/Stochastic_matrix}

}

@misc{WikiTensorProd,
author = "Wikipedia",
title = "Tensor product",
Expand Down
3 changes: 3 additions & 0 deletions toqito/matrix_props/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@
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
from toqito.matrix_props.is_right_stochastic import is_right_stochastic
from toqito.matrix_props.is_left_stochastic import is_left_stochastic
from toqito.matrix_props.is_doubly_stochastic import is_doubly_stochastic
75 changes: 75 additions & 0 deletions toqito/matrix_props/is_doubly_stochastic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""Check is a matrix is doubly stochastic."""

import numpy as np

from toqito.matrix_props import is_left_stochastic, is_right_stochastic


def is_doubly_stochastic(mat: np.ndarray) -> bool:
r"""Verify matrix is doubly stochastic.

A matrix is doubky stochastic if it is also a right and left stochastic matrix.
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
:cite:`WikiStichasticMatrix, WikiDoublyStichasticMatrix`.
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved

See Also
========
is_right_stochastic
is_left_stochastic

Examples
========
The elements an identity matrix and a Pauli X matrix are nonnegative where both the rows and columns sum up to 1.
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
The same cannot be said about a Pauli Z matrix.

.. math::
Id = \begin{pmatrix}
1 & 0 & 0 & 0 & 0\\
0 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 0\\
0 & 0 & 0 & 1 & 0\\
0 & 0 & 0 & 0 & 1\\
\end{pmatrix}

>>> import numpy as np
>>> from toqito.matrix_props import is_doubly_stochastic
>>> id_mat = np.eye(5)
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
>>> is_doubly_stochastic(id_mat)
True

.. math::
PauliX = \begin{pmatrix}
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
0 & 1 \\
1 & 0\\
\end{pmatrix}

>>> from toqito.matrices import pauli
>>> from toqito.matrix_props import is_doubly_stochastic
>>> x_mat = pauli("X")
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
>>> is_doubly_stochastic(x_mat)
True

.. math::
PauliY = \begin{pmatrix}
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
1 & 0 \\
0 & -1\\
\end{pmatrix}

>>> from toqito.matrices import pauli
>>> from toqito.matrix_props import is_doubly_stochastic
>>> z_mat = pauli("Z")
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
>>> is_doubly_stochastic(z_mat)
False


References
==========
.. bibliography::
:filter: docname in docnames

:param rho: Matrix of interest

"""
if is_left_stochastic(mat) and is_right_stochastic(mat):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One liner?

return is_left_stochastic(mat) and is_right_stochastic(mat)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had tried this pattern first. The function would return True if the matrix was doubly stochastic.

But when it was not doubly stochastic, it would not return False. The output cell in the jupyter notebook was blank in this case.

return True

return False
72 changes: 72 additions & 0 deletions toqito/matrix_props/is_left_stochastic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""Check is a matrix is left stochastic."""

import numpy as np

from toqito.matrix_props import is_nonnegative, is_square


def is_left_stochastic(mat: np.ndarray) -> bool:
r"""Verify matrix is right stochastic.

A matrix is right stochastic if it is a square matrix with nonegative elements such that the columns sum up to 1
:cite:WikiStichasticMatrix.

Examples
========
The elements an identity matrix and a Pauli X matrix are nonnegative and the rows sum up to 1. The same cannot be
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
said about a Pauli Z matrix.

.. math::
Id = \begin{pmatrix}
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
1 & 0 & 0 & 0 & 0\\
0 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 0\\
0 & 0 & 0 & 1 & 0\\
0 & 0 & 0 & 0 & 1\\
\end{pmatrix}

>>> import numpy as np
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
>>> from toqito.matrix_props import is_left_stochastic
>>> id_mat = np.eye(5)
>>> is_left_stochastic(id_mat)
True

.. math::
PauliX = \begin{pmatrix}
0 & 1 \\
1 & 0\\
\end{pmatrix}

>>> from toqito.matrices import pauli
>>> from toqito.matrix_props import is_left_stochastic
>>> x_mat = pauli("X")
>>> is_left_stochastic(x_mat)
True

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

>>> from toqito.matrices import pauli
>>> from toqito.matrix_props import is_left_stochastic
>>> z_mat = pauli("Z")
>>> is_left_stochastic(z_mat)
False




References
==========
.. bibliography::
:filter: docname in docnames

:param rho: Matrix of interest

"""
if is_square(mat) and is_nonnegative(mat) and np.all(np.sum(mat, axis=0) == 1.0):
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
return True

return False
74 changes: 74 additions & 0 deletions toqito/matrix_props/is_right_stochastic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""Check is a matrix is right stochastic."""

import numpy as np

from toqito.matrix_props import is_nonnegative, is_square


def is_right_stochastic(mat: np.ndarray) -> bool:
purva-thakre marked this conversation as resolved.
Show resolved Hide resolved
r"""Verify matrix is right stochastic.

A matrix is right stochastic if it is a square matrix with nonegative elements such that the rows sum up to 1
:cite:WikiStichasticMatrix.

Examples
========
The elements an identity matrix and a Pauli X matrix are nonnegative and the rows sum up to 1. The same cannot be
said about a Pauli Z matrix.

.. math::
Id = \begin{pmatrix}
1 & 0 & 0 & 0 & 0\\
0 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 0\\
0 & 0 & 0 & 1 & 0\\
0 & 0 & 0 & 0 & 1\\
\end{pmatrix}

>>> import numpy as np
>>> from toqito.matrix_props import is_right_stochastic
>>> id_mat = np.eye(5)
>>> is_right_stochastic(id_mat)
True

.. math::
PauliX = \begin{pmatrix}
0 & 1 \\
1 & 0\\
\end{pmatrix}

>>> from toqito.matrices import pauli
>>> from toqito.matrix_props import is_right_stochastic
>>> x_mat = pauli("X")
>>> is_right_stochastic(x_mat)
True

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

>>> from toqito.matrices import pauli
>>> from toqito.matrix_props import is_right_stochastic
>>> z_mat = pauli("Z")
>>> is_right_stochastic(z_mat)
False




References
==========
.. bibliography::
:filter: docname in docnames

:param rho: Matrix of interest

"""
if is_square(mat) and is_nonnegative(mat) and np.all(np.sum(mat, axis=1) == 1.0):
return True

return False


23 changes: 23 additions & 0 deletions toqito/matrix_props/tests/test_is_doubly_stochastic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Tests for doubly stochastic matrix."""


import numpy as np
import pytest

from toqito.matrices import cyclic_permutation_matrix, pauli
from toqito.matrix_props import is_doubly_stochastic, is_left_stochastic, is_right_stochastic


@pytest.mark.parametrize("test_input", [(np.identity(3)), (cyclic_permutation_matrix(4)), (pauli("X"))])
def test_true(test_input):
"""Check if function identifies right stochastic matrix correctly."""
assert is_left_stochastic(test_input)
assert is_right_stochastic(test_input)
assert is_doubly_stochastic(test_input)



@pytest.mark.parametrize("test_input", [(pauli("Y")), (pauli("Z"))])
def test_true(test_input):
"""Check if function identifies non-right stochastic matrix correctly."""
assert not is_doubly_stochastic(test_input)
23 changes: 23 additions & 0 deletions toqito/matrix_props/tests/test_is_left_stochastic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Tests for left stochastic matrix."""


import numpy as np
import pytest

from toqito.matrices import cyclic_permutation_matrix, pauli
from toqito.matrix_props import is_left_stochastic, is_nonnegative, is_square


@pytest.mark.parametrize("test_input", [(np.identity(3)), (cyclic_permutation_matrix(4)), (pauli("X"))])
def test_true(test_input):
"""Check if function identifies right stochastic matrix correctly."""
assert is_square(test_input)
assert is_nonnegative(test_input)
assert is_left_stochastic(test_input)



@pytest.mark.parametrize("test_input", [(pauli("Y")), (pauli("Z"))])
def test_true(test_input):
"""Check if function identifies non-right stochastic matrix correctly."""
assert not is_left_stochastic(test_input)
22 changes: 22 additions & 0 deletions toqito/matrix_props/tests/test_is_right_stochastic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Tests for right stochastic matrix."""

import numpy as np
import pytest

from toqito.matrices import cyclic_permutation_matrix, pauli
from toqito.matrix_props import is_nonnegative, is_right_stochastic, is_square


@pytest.mark.parametrize("test_input", [(np.identity(3)), (cyclic_permutation_matrix(4)), (pauli("X"))])
def test_true(test_input):
"""Check if function identifies right stochastic matrix correctly."""
assert is_square(test_input)
assert is_nonnegative(test_input)
assert is_right_stochastic(test_input)



@pytest.mark.parametrize("test_input", [(pauli("Y")), (pauli("Z"))])
def test_true(test_input):
"""Check if function identifies non-right stochastic matrix correctly."""
assert not is_right_stochastic(test_input)