From 08f60a6363af167abe848d91feb558934bbc016b Mon Sep 17 00:00:00 2001 From: vrusso Date: Thu, 16 Nov 2023 22:39:48 -0500 Subject: [PATCH] Optimizing is mutually orthogonal function. --- .../test_is_mutually_orthogonal.py | 18 ++++++++++++++++++ toqito/state_props/is_mutually_orthogonal.py | 18 ++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/tests/test_state_props/test_is_mutually_orthogonal.py b/tests/test_state_props/test_is_mutually_orthogonal.py index ad74b0910..241ca794b 100644 --- a/tests/test_state_props/test_is_mutually_orthogonal.py +++ b/tests/test_state_props/test_is_mutually_orthogonal.py @@ -11,6 +11,18 @@ ([bell(0), bell(1), bell(2), bell(3)], True), # Return False for non-orthogonal vectors. ([np.array([1, 0]), np.array([1, 1])], False), + # Orthogonal vectors in R^2 + ([np.array([1, 0]), np.array([0, 1])], True), + # Orthogonal vectors in R^2 + ([np.array([1, 0, 0]), np.array([0, 1, 0]), np.array([0, 0, 1])], True), + # Orthogonal complex-valued vectors + ([np.array([[1], [1j]]), np.array([[1j], [1]])], True), + # Vectors with zero elements. + ([np.array([[0], [0]]), np.array([[1], [0]])], True), + # Colinear vectors. + ([np.array([[1], [2]]), np.array([2, 4])], False), + # Vectors that are theoretically orthogonal but due to numerical precision issues might not be exactly orthogonal. + ([np.array([[1], [np.sqrt(2)]]), np.array([[-np.sqrt(2)], [1]])], True), ]) def test_is_mutually_orthogonal(states, expected_result): np.testing.assert_equal(is_mutually_orthogonal(states), expected_result) @@ -19,6 +31,12 @@ def test_is_mutually_orthogonal(states, expected_result): @pytest.mark.parametrize("states", [ # Tests for invalid input len. ([np.array([1, 0])]), + # Single vector should raise error. + ([np.array([[1], [2], [3]])]), + # Vectors of differing lengths. + ([np.array([[1], [0]]), np.array([[1], [0], [1]])]), + # Empty vector. + ([]), ]) def test_is_mutually_orthogonal_basis_invalid_input(states): with np.testing.assert_raises(ValueError): diff --git a/toqito/state_props/is_mutually_orthogonal.py b/toqito/state_props/is_mutually_orthogonal.py index 4594dfa13..afe392830 100644 --- a/toqito/state_props/is_mutually_orthogonal.py +++ b/toqito/state_props/is_mutually_orthogonal.py @@ -61,9 +61,15 @@ def is_mutually_orthogonal(vec_list: list[np.ndarray | list[float | Any]]) -> bo if len(vec_list) <= 1: raise ValueError("There must be at least two vectors provided as input.") - for i, vec_1 in enumerate(vec_list): - for j, vec_2 in enumerate(vec_list): - if i != j: - if not np.isclose(np.inner(vec_1.conj().T, vec_2.conj().T), 0): - return False - return True + # Convert list of vectors to a 2D array (each vector is a column) + mat = np.column_stack(vec_list) + + # Compute the matrix of inner products + inner_product_matrix = np.dot(mat.T.conj(), mat) + + # The diagonal elements will be non-zero (norm of each vector) + # Set the diagonal elements to zero for the comparison + np.fill_diagonal(inner_product_matrix, 0) + + # Check if all off-diagonal elements are close to zero + return np.allclose(inner_product_matrix, 0)