diff --git a/docs/refs.bib b/docs/refs.bib index 5df631a7c..ddd8f62ce 100644 --- a/docs/refs.bib +++ b/docs/refs.bib @@ -806,6 +806,15 @@ @misc{Russo_2017_Extended } #Last name begins with S + +@misc{SE_1688950, + author = "Stack Exchange Mathematics", + title = "Why do the columns of a unitary matrix form an orthonormal basis?", + howpublished = {https://math.stackexchange.com/q/1688950} + +} + + @misc{Seshadri_2021_Git, author = "Seshadri, Akshay", title = "Minimax Fidelity Estimation", diff --git a/toqito/matrix_props/is_orthonormal.py b/toqito/matrix_props/is_orthonormal.py index 876fb3695..244021853 100644 --- a/toqito/matrix_props/is_orthonormal.py +++ b/toqito/matrix_props/is_orthonormal.py @@ -39,4 +39,5 @@ def is_orthonormal(vectors: list[np.ndarray]) -> bool: :return: True if vectors are orthonormal; False otherwise. """ - return is_mutually_orthogonal(vectors) and np.allclose(np.dot(vectors, vectors.T), np.eye(vectors.shape[0])) + return is_mutually_orthogonal(vectors) and np.allclose(np.dot(vectors, np.conjugate(vectors).T), np.eye( + vectors.shape[0])) diff --git a/toqito/rand/__init__.py b/toqito/rand/__init__.py index 9fd42e46d..94acf6fcd 100644 --- a/toqito/rand/__init__.py +++ b/toqito/rand/__init__.py @@ -7,3 +7,4 @@ from toqito.rand.random_state_vector import random_state_vector from toqito.rand.random_states import random_states from toqito.rand.random_circulant_gram_matrix import random_circulant_gram_matrix +from toqito.rand.random_orthonormal_basis import random_orthonormal_basis diff --git a/toqito/rand/random_orthonormal_basis.py b/toqito/rand/random_orthonormal_basis.py new file mode 100644 index 000000000..73df01d93 --- /dev/null +++ b/toqito/rand/random_orthonormal_basis.py @@ -0,0 +1,41 @@ +"""Generate random orthonormal basis.""" +import numpy as np + +from toqito.matrix_props import is_orthonormal +from toqito.rand import random_unitary + + +def random_orthonormal_basis(dim: int, is_real: bool = False) -> list[np.ndarray]: + r"""Generate a real random orthonormal basis of given dimension :math:`d`. + + The basis is generated from the columns of a random unitary matrix of the same dimension + as the columns of a unitary matrix typically form an orthonormal basis :cite:`SE_1688950`. + + Examples + ========== + To generate a random orthonormal basis of dimension :math:`4`, + + >>> from toqito.rand import random_orthonormal_basis + >>> random_orthonormal_basis(4, is_real = True) # doctest: +SKIP + [array([0.52188745, 0.4983613 , 0.69049811, 0.04981832]), + array([-0.48670459, 0.58756912, -0.10226756, 0.63829658]), + array([ 0.23965404, -0.58538248, 0.187136 , 0.75158061]), + array([ 0.658269 , 0.25243989, -0.69118291, 0.158815 ])] + + References + ========== + .. bibliography:: + :filter: docname in docnames + + dim: int + Number of elements in the random orthonormal basis. + + """ + random_mat = random_unitary(dim, is_real) + + random_mat = random_unitary(dim, is_real) + return [random_mat[:, i] for i in range(dim)] + + return rand_orth_basis + + diff --git a/toqito/rand/tests/test_random_orthonormal_basis.py b/toqito/rand/tests/test_random_orthonormal_basis.py new file mode 100644 index 000000000..cc9a0d419 --- /dev/null +++ b/toqito/rand/tests/test_random_orthonormal_basis.py @@ -0,0 +1,17 @@ +"""Tests for random orthonormal basis.""" + +import numpy as np +import pytest + +from toqito.matrix_props import is_orthonormal +from toqito.rand import random_orthonormal_basis + + +@pytest.mark.parametrize("input_dim", range(2, 5)) +@pytest.mark.parametrize("bool", [False, True]) +def test_random_orth_basis_int_dim(input_dim, bool): + """Test function works as expected for a valid int input.""" + gen_basis = random_orthonormal_basis(dim=input_dim, is_real = bool) + assert len(gen_basis) == input_dim + assert is_orthonormal(np.array(gen_basis)) +