From 1b505b70af5d78ad6244567f3a85a8bd4edecea2 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Tue, 25 Jun 2024 12:54:14 +0400 Subject: [PATCH 1/7] functions --- src/qibo/quantum_info/operations.py | 95 +++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/qibo/quantum_info/operations.py diff --git a/src/qibo/quantum_info/operations.py b/src/qibo/quantum_info/operations.py new file mode 100644 index 0000000000..1b49852006 --- /dev/null +++ b/src/qibo/quantum_info/operations.py @@ -0,0 +1,95 @@ +"""Module with the most common linear algebra operations for quantum information.""" + +import numpy as np + +from qibo.config import raise_error + + +def commutator(operator_1, operator_2): + """Returns the commutator of ``operator_1`` and ``operator_2``. + + The commutator of two matrices :math:`A` and :math:`B` is given by + + .. math:: + [A, B] = A \\, B - B \\, A \\,. + + Args: + operator_1 (ndarray): First operator. + operator_2 (ndarray): Second operator. + + Returns: + ndarray: Commutator of ``operator_1`` and ``operator_2``. + """ + if ( + (len(operator_1.shape) >= 3) + or (len(operator_1) == 0) + or (len(operator_1.shape) == 2 and operator_1.shape[0] != operator_1.shape[1]) + ): + raise_error( + TypeError, + f"``operator_1`` must have shape (k,k), but have shape {operator_1.shape}.", + ) + + if ( + (len(operator_2.shape) >= 3) + or (len(operator_2) == 0) + or (len(operator_2.shape) == 2 and operator_2.shape[0] != operator_2.shape[1]) + ): + raise_error( + TypeError, + f"``operator_2`` must have shape (k,k), but have shape {operator_2.shape}.", + ) + + if operator_1.shape != operator_2.shape: + raise_error( + ValueError, + "``operator_1`` and ``operator_2`` must have the same shape, " + + f"but {operator_1.shape} != {operator_2.shape}", + ) + + return operator_1 @ operator_2 - operator_2 @ operator_1 + + +def anticommutator(operator_1, operator_2): + """Returns the anticommutator of ``operator_1`` and ``operator_2``. + + The anticommutator of two matrices :math:`A` and :math:`B` is given by + + .. math:: + \\{A, B\\} = A \\, B + B \\, A \\,. + + Args: + operator_1 (ndarray): First operator. + operator_2 (ndarray): Second operator. + + Returns: + ndarray: Anticommutator of ``operator_1`` and ``operator_2``. + """ + if ( + (len(operator_1.shape) >= 3) + or (len(operator_1) == 0) + or (len(operator_1.shape) == 2 and operator_1.shape[0] != operator_1.shape[1]) + ): + raise_error( + TypeError, + f"``operator_1`` must have shape (k,k), but have shape {operator_1.shape}.", + ) + + if ( + (len(operator_2.shape) >= 3) + or (len(operator_2) == 0) + or (len(operator_2.shape) == 2 and operator_2.shape[0] != operator_2.shape[1]) + ): + raise_error( + TypeError, + f"``operator_2`` must have shape (k,k), but have shape {operator_2.shape}.", + ) + + if operator_1.shape != operator_2.shape: + raise_error( + ValueError, + "``operator_1`` and ``operator_2`` must have the same shape, " + + f"but {operator_1.shape} != {operator_2.shape}", + ) + + return operator_1 @ operator_2 + operator_2 @ operator_1 From 98ba47a46b5764f331430e6c0a2dcaa7c29c5b16 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Tue, 25 Jun 2024 12:57:49 +0400 Subject: [PATCH 2/7] remove import --- src/qibo/quantum_info/operations.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/qibo/quantum_info/operations.py b/src/qibo/quantum_info/operations.py index 1b49852006..b16f373cd6 100644 --- a/src/qibo/quantum_info/operations.py +++ b/src/qibo/quantum_info/operations.py @@ -1,7 +1,5 @@ """Module with the most common linear algebra operations for quantum information.""" -import numpy as np - from qibo.config import raise_error From f41dbd0e59d5edb128a1850232eaad0e6d8639b7 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Tue, 25 Jun 2024 13:22:23 +0400 Subject: [PATCH 3/7] addition to module's init --- src/qibo/quantum_info/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qibo/quantum_info/__init__.py b/src/qibo/quantum_info/__init__.py index 8d9400104e..6756df73aa 100644 --- a/src/qibo/quantum_info/__init__.py +++ b/src/qibo/quantum_info/__init__.py @@ -3,6 +3,7 @@ from qibo.quantum_info.entanglement import * from qibo.quantum_info.entropies import * from qibo.quantum_info.metrics import * +from qibo.quantum_info.operations import * from qibo.quantum_info.quantum_networks import * from qibo.quantum_info.random_ensembles import * from qibo.quantum_info.superoperator_transformations import * From dc78b1d7511dca4297e3fe02340c7e3dae167309 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Tue, 25 Jun 2024 13:22:26 +0400 Subject: [PATCH 4/7] tests --- tests/test_quantum_info_operations.py | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 tests/test_quantum_info_operations.py diff --git a/tests/test_quantum_info_operations.py b/tests/test_quantum_info_operations.py new file mode 100644 index 0000000000..7fdd533cb8 --- /dev/null +++ b/tests/test_quantum_info_operations.py @@ -0,0 +1,67 @@ +import numpy as np +import pytest + +from qibo import matrices +from qibo.quantum_info.operations import anticommutator, commutator + + +def test_commutator(backend): + matrix_1 = np.random.rand(2, 2, 2) + matrix_1 = backend.cast(matrix_1, dtype=matrix_1.dtype) + + matrix_2 = np.random.rand(2, 2) + matrix_2 = backend.cast(matrix_2, dtype=matrix_2.dtype) + + with pytest.raises(TypeError): + test = commutator(matrix_1, matrix_2) + with pytest.raises(TypeError): + test = commutator(matrix_2, matrix_1) + + I, X, Y, Z = matrices.I, matrices.X, matrices.Y, matrices.Z + I = backend.cast(I, dtype=I.dtype) + X = backend.cast(X, dtype=X.dtype) + Y = backend.cast(Y, dtype=Y.dtype) + Z = backend.cast(Z, dtype=Z.dtype) + + comm = commutator(X, I) + backend.assert_allclose(comm, 0.0) + + comm = commutator(X, X) + backend.assert_allclose(comm, 0.0) + + comm = commutator(X, Y) + backend.assert_allclose(comm, 2j * Z) + + comm = commutator(X, Z) + backend.assert_allclose(comm, -2j * Y) + + +def test_anticommutator(backend): + matrix_1 = np.random.rand(2, 2, 2) + matrix_1 = backend.cast(matrix_1, dtype=matrix_1.dtype) + + matrix_2 = np.random.rand(2, 2) + matrix_2 = backend.cast(matrix_2, dtype=matrix_2.dtype) + + with pytest.raises(TypeError): + test = anticommutator(matrix_1, matrix_2) + with pytest.raises(TypeError): + test = anticommutator(matrix_2, matrix_1) + + I, X, Y, Z = matrices.I, matrices.X, matrices.Y, matrices.Z + I = backend.cast(I, dtype=I.dtype) + X = backend.cast(X, dtype=X.dtype) + Y = backend.cast(Y, dtype=Y.dtype) + Z = backend.cast(Z, dtype=Z.dtype) + + anticomm = anticommutator(X, I) + backend.assert_allclose(anticomm, 2 * X) + + anticomm = anticommutator(X, X) + backend.assert_allclose(anticomm, 2 * I) + + anticomm = anticommutator(X, Y) + backend.assert_allclose(anticomm, 0.0) + + anticomm = anticommutator(X, Z) + backend.assert_allclose(anticomm, 0.0) From 63d4c57760b1d170ccd9a6b571c0aebdd8ed61d9 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Tue, 25 Jun 2024 13:25:29 +0400 Subject: [PATCH 5/7] api ref --- doc/source/api-reference/qibo.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/source/api-reference/qibo.rst b/doc/source/api-reference/qibo.rst index fb7099e2b7..7e9d508bfa 100644 --- a/doc/source/api-reference/qibo.rst +++ b/doc/source/api-reference/qibo.rst @@ -1912,6 +1912,24 @@ Frame Potential .. autofunction:: qibo.quantum_info.frame_potential +Linear Algebra Operations +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Collection of linear algebra operations that are commonly used in quantum information theory. + + +Commutator +"""""""""" + +.. autofunction:: qibo.quantum_info.commutator + + +Anticommutator +"""""""""""""" + +.. autofunction:: qibo.quantum_info.anticommutator + + Quantum Networks ^^^^^^^^^^^^^^^^ From 590026d89690cf4e2c7ac582e97a12e826f91ae5 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Tue, 25 Jun 2024 15:44:21 +0400 Subject: [PATCH 6/7] fix coverage --- src/qibo/quantum_info/operations.py | 4 ++-- tests/test_quantum_info_operations.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/qibo/quantum_info/operations.py b/src/qibo/quantum_info/operations.py index b16f373cd6..29e4ea08f1 100644 --- a/src/qibo/quantum_info/operations.py +++ b/src/qibo/quantum_info/operations.py @@ -40,7 +40,7 @@ def commutator(operator_1, operator_2): if operator_1.shape != operator_2.shape: raise_error( - ValueError, + TypeError, "``operator_1`` and ``operator_2`` must have the same shape, " + f"but {operator_1.shape} != {operator_2.shape}", ) @@ -85,7 +85,7 @@ def anticommutator(operator_1, operator_2): if operator_1.shape != operator_2.shape: raise_error( - ValueError, + TypeError, "``operator_1`` and ``operator_2`` must have the same shape, " + f"but {operator_1.shape} != {operator_2.shape}", ) diff --git a/tests/test_quantum_info_operations.py b/tests/test_quantum_info_operations.py index 7fdd533cb8..45847fb379 100644 --- a/tests/test_quantum_info_operations.py +++ b/tests/test_quantum_info_operations.py @@ -12,10 +12,15 @@ def test_commutator(backend): matrix_2 = np.random.rand(2, 2) matrix_2 = backend.cast(matrix_2, dtype=matrix_2.dtype) + matrix_3 = np.random.rand(3, 3) + matrix_3 = backend.cast(matrix_3, dtype=matrix_3.dtype) + with pytest.raises(TypeError): test = commutator(matrix_1, matrix_2) with pytest.raises(TypeError): test = commutator(matrix_2, matrix_1) + with pytest.raises(TypeError): + test = commutator(matrix_2, matrix_3) I, X, Y, Z = matrices.I, matrices.X, matrices.Y, matrices.Z I = backend.cast(I, dtype=I.dtype) @@ -43,10 +48,15 @@ def test_anticommutator(backend): matrix_2 = np.random.rand(2, 2) matrix_2 = backend.cast(matrix_2, dtype=matrix_2.dtype) + matrix_3 = np.random.rand(3, 3) + matrix_3 = backend.cast(matrix_3, dtype=matrix_3.dtype) + with pytest.raises(TypeError): test = anticommutator(matrix_1, matrix_2) with pytest.raises(TypeError): test = anticommutator(matrix_2, matrix_1) + with pytest.raises(TypeError): + test = commutator(matrix_2, matrix_3) I, X, Y, Z = matrices.I, matrices.X, matrices.Y, matrices.Z I = backend.cast(I, dtype=I.dtype) From 9cd5092e59694a8f42e94a4a50366e7c1e298e12 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 26 Jun 2024 07:19:11 +0400 Subject: [PATCH 7/7] fix coverage --- tests/test_quantum_info_operations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_quantum_info_operations.py b/tests/test_quantum_info_operations.py index 45847fb379..0dae19ac74 100644 --- a/tests/test_quantum_info_operations.py +++ b/tests/test_quantum_info_operations.py @@ -56,7 +56,7 @@ def test_anticommutator(backend): with pytest.raises(TypeError): test = anticommutator(matrix_2, matrix_1) with pytest.raises(TypeError): - test = commutator(matrix_2, matrix_3) + test = anticommutator(matrix_2, matrix_3) I, X, Y, Z = matrices.I, matrices.X, matrices.Y, matrices.Z I = backend.cast(I, dtype=I.dtype)