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

Improve rand tests #265

Merged
merged 20 commits into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 36 additions & 14 deletions toqito/matrix_ops/inner_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,41 @@ def inner_product(v1: np.ndarray, v2: np.ndarray) -> float:
The inner product is calculated as follows:

.. math::
\left\langle \begin{pmatrix}a_1 \\ \vdots \\ a_n\end{pmatrix},\begin{pmatrix}b_1 \\ \vdots \\ b_n\end{pmatrix}\right\rangle = \begin{pmatrix} a_1,\cdots, a_n\end{pmatrix}\begin{pmatrix}b_1 \\ \vdots \\ b_n\end{pmatrix} = a_1 b_1 + \cdots + a_n b_n
\left\langle
\begin{pmatrix}
a_1 \\ \vdots \\ a_n
\end{pmatrix},
\begin{pmatrix}
b_1 \\ \vdots \\ b_n
\end{pmatrix} \right\rangle =
\begin{pmatrix}
a_1, \cdots, a_n
\end{pmatrix}
\begin{pmatrix}
b_1 \\ \vdots \\ b_n
\end{pmatrix} = a_1 b_1 + \cdots + a_n b_n

Example
==========

The inner product of the vectors :math:`v1 = \begin{pmatrix}1 \\ 2 \\ 3 \end{pmatrix}` and :math:`v2 = \begin{pmatrix}4 \\ 5 \\ 6 \ \end{pmatrix}` looks as follows:
The inner product of the vectors :math:`v1 = \begin{pmatrix}1 \\ 2 \\ 3 \end{pmatrix}` and :math:`v2 =
\begin{pmatrix}4 \\ 5 \\ 6 \ \end{pmatrix}` looks as follows:

.. math::
\left\langle \begin{pmatrix}1 \\ 2 \\ 3\end{pmatrix},\begin{pmatrix}4 \\ 5 \\ 6\end{pmatrix}\right\rangle = \begin{pmatrix} 1,2, 3\end{pmatrix}\begin{pmatrix}4 \\ 5 \\ 6\end{pmatrix} = 1\times 4 + 2\times 5 + 3\times 6 = 32
\left\langle
\begin{pmatrix}
1 \\ 2 \\ 3
\end{pmatrix},
\begin{pmatrix}
4 \\ 5 \\ 6
\end{pmatrix}\right\rangle =
\begin{pmatrix}
1, 2, 3
\end{pmatrix}
\begin{pmatrix}
4 \\ 5 \\ 6
\end{pmatrix} = 1\times 4 + 2\times 5 + 3\times 6 =
32

In :code:`toqito`, this looks like this:

Expand All @@ -33,16 +59,12 @@ def inner_product(v1: np.ndarray, v2: np.ndarray) -> float:
https://en.wikipedia.org/wiki/Inner_product_space

:raises ValueError: Vector dimensions are mismatched.
:param v1: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:param v2: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:param v1: v1 and v2, both vectors of dimensions :math:`(n,1)` where :math:`n>1`.
:param v2: v1 and v2, both vectors of dimensions :math:`(n,1)` where :math:`n>1`.
:return: The computed inner product.
"""
# Check for dimensional validity
if not (v1.shape[0] == v2.shape[0] and v1.shape[0] > 1 and len(v1.shape) == 1):
raise ValueError("Dimension mismatch")

res = 0
for i in range(v1.shape[0]):
res += v1[i] * v2[i]

return res
if v1.ndim != 1 or v2.ndim != 1:
raise ValueError("Both v1 and v2 must be 1D vectors.")
if v1.shape[0] != v2.shape[0]:
raise ValueError("Dimension mismatch between v1 and v2.")
return np.vdot(v1, v2)
47 changes: 33 additions & 14 deletions toqito/matrix_ops/outer_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,33 @@ def outer_product(v1: np.ndarray, v2: np.ndarray) -> np.ndarray:

Example
==========

The outer product of the vectors :math:`v1 = \begin{pmatrix}1 \\ 2 \\ 3 \end{pmatrix}` and :math:`v2 = \begin{pmatrix}4 \\ 5 \\ 6 \ \end{pmatrix}` looks as follows:
The outer product of the vectors :math:`v1 = \begin{pmatrix}1 \\ 2 \\ 3 \end{pmatrix}` and :math:`v2 =
\begin{pmatrix}4 \\ 5 \\ 6 \ \end{pmatrix}` looks as follows:

.. math::
\left|\begin{pmatrix}1\\2\\3\end{pmatrix}\right\rangle\left\langle\begin{pmatrix}4\\5\\6\end{pmatrix}\right|=\begin{pmatrix}1\\2\\3\end{pmatrix}\begin{pmatrix}4&5&6\end{pmatrix}=\begin{pmatrix}1\times4&1\times5&1\times6\\2\times4&2\times5&2\times6\\3\times4&3\times5&3\times6\end{pmatrix}=\begin{pmatrix}4&5&6\\8&10&12\\12&15&18\end{pmatrix}
\left|\begin{pmatrix}
1 \\ 2 \\ 3
\end{pmatrix}\right\rangle
\left\langle
\begin{pmatrix}
4 \\ 5 \\ 6
\end{pmatrix}\right|=
\begin{pmatrix}
1 \\ 2 \\ 3
\end{pmatrix}
\begin{pmatrix}
4 & 5 & 6
\end{pmatrix}=
\begin{pmatrix}
1 \times 4 & 1 \times 5 & 1 \times 6 \\
2 \times 4 & 2 \times 5 & 2 \times 6 \\
3 \times 4 & 3 \times 5 & 3 \times 6
\end{pmatrix}=
\begin{pmatrix}
4 & 5 & 6 \\
8 & 10 & 12 \\
12 & 15 & 18
\end{pmatrix}

In :code:`toqito`, this looks like this:

Expand All @@ -35,16 +57,13 @@ def outer_product(v1: np.ndarray, v2: np.ndarray) -> np.ndarray:
https://en.wikipedia.org/wiki/Outer_product

:raises ValueError: Vector dimensions are mismatched.
:param v1: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:param v2: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:param v1: v1 and v2, both vectors of dimensions :math:`(n,1)` where :math:`n>1`.
:param v2: v1 and v2, both vectors of dimensions :math:`(n,1)` where :math:`n>1`.
:return: The computed outer product.
"""
# Check for dimensional validity
if not (v1.shape[0] == v2.shape[0] and v1.shape[0] > 1 and len(v1.shape) == 1):
raise ValueError("Dimension mismatch")

res = np.ndarray((v1.shape[0], v1.shape[0]))
for i in range(v1.shape[0]):
for j in range(v1.shape[0]):
res[i, j] = v1[i] * v2[j]
return res
if v1.ndim != 1 or v2.ndim != 1:
raise ValueError("Both v1 and v2 must be 1D vectors.")
if v1.shape[0] != v2.shape[0]:
raise ValueError("Dimension mismatch between v1 and v2.")

return np.outer(v1, np.conj(v2))
58 changes: 21 additions & 37 deletions toqito/matrix_ops/tests/test_inner_product.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,28 @@
"""Test inner_product."""
import numpy as np
import pytest

from toqito.matrix_ops import inner_product


def test_inner_product():
"""Test with two vectors, no complications."""

v1, v2 = np.array([1, 2, 3]), np.array([4, 5, 6])
expected_res = 32
np.testing.assert_equal(inner_product(v1, v2), expected_res)


def test_inner_product_negative_input():
"""Test with two vectors, with negative input value."""

v1, v2 = np.array([-1, 2, 3]), np.array([4, 5, 6])
expected_res = 24
np.testing.assert_equal(inner_product(v1, v2), expected_res)


def test_inner_product_negative_output():
"""Test with two vectors, with negative expected output."""

v1, v2 = np.array([1, 2, -3]), np.array([4, 5, 6])
expected_res = -4
np.testing.assert_equal(inner_product(v1, v2), expected_res)


def test_inner_product_different_dimensions():
"""Test with two vectors of different dimensions."""

v1, v2 = np.array([1, 2, 3]), np.array([4, 5, 6, 7])
with np.testing.assert_raises(ValueError):
inner_product(v1, v2)


def test_inner_product_different_dimensions_2():
"""Test with a vector and a 2d array."""

v1, v2 = np.array([1, 2, 3]), np.array([[4, 5, 6], [7, 8, 9]])
with np.testing.assert_raises(ValueError):
@pytest.mark.parametrize("v1, v2, expected_result", [
# Test with two vectors, no complications.
(np.array([1, 2, 3]), np.array([4, 5, 6]), 32),
# Test with two vectors, with negative input value.
(np.array([-1, 2, 3]), np.array([4, 5, 6]), 24),
# Test with two vectors, with negative expected output.
(np.array([1, 2, -3]), np.array([4, 5, 6]), -4),
])
def test_inner_product(v1, v2, expected_result):
assert inner_product(v1, v2) == expected_result


@pytest.mark.parametrize("v1, v2", [
# Different dimensions of vectors.
(np.array([1, 2, 3]), np.array([4, 5, 6, 7])),
# Vector and 2D array.
(np.array([1, 2, 3]), np.array([[4, 5, 6], [7, 8, 9]])),
])
def test_inner_product_invalid_input(v1, v2):
with pytest.raises(ValueError):
inner_product(v1, v2)
48 changes: 19 additions & 29 deletions toqito/matrix_ops/tests/test_outer_product.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,26 @@
"""Test outer_product."""
import numpy as np
import pytest

from toqito.matrix_ops import outer_product


def test_outer_product():
"""Test with two vectors, no complications."""

v1, v2 = np.array([1, 2, 3]), np.array([4, 5, 6])
expected_res = np.array([[4, 5, 6], [8, 10, 12], [12, 15, 18]])
np.testing.assert_equal(outer_product(v1, v2), expected_res)


def test_outer_product_negative():
"""Test with two vectors, with negative input/output values."""

v1, v2 = np.array([-1, 2, 3]), np.array([4, 5, 6])
expected_res = np.array([[-4, -5, -6], [8, 10, 12], [12, 15, 18]])
np.testing.assert_equal(outer_product(v1, v2), expected_res)


def test_outer_product_different_dimensions():
"""Test with two vectors of different dimensions."""

v1, v2 = np.array([1, 2, 3]), np.array([4, 5, 6, 7])
with np.testing.assert_raises(ValueError):
outer_product(v1, v2)


def test_outer_product_different_dimensions_2():
"""Test with a vector and a 2d array."""

v1, v2 = np.array([1, 2, 3]), np.array([[4, 5, 6], [7, 8, 9]])
with np.testing.assert_raises(ValueError):
@pytest.mark.parametrize("v1, v2, expected_result", [
# Test with two vectors, no complications.
(np.array([1, 2, 3]), np.array([4, 5, 6]), np.array([[4, 5, 6], [8, 10, 12], [12, 15, 18]])),
# Test with two vectors, with negative input/output values.
(np.array([-1, 2, 3]), np.array([4, 5, 6]), np.array([[-4, -5, -6], [8, 10, 12], [12, 15, 18]])),
])
def test_outer_product(v1, v2, expected_result):
np.testing.assert_array_equal(outer_product(v1, v2), expected_result)


@pytest.mark.parametrize("v1, v2", [
# Different dimensions of vectors.
(np.array([1, 2, 3]), np.array([4, 5, 6, 7])),
# Vector and 2D array.
(np.array([1, 2, 3]), np.array([[4, 5, 6], [7, 8, 9]])),
])
def test_outer_product_invalid_input(v1, v2):
with pytest.raises(ValueError):
outer_product(v1, v2)
26 changes: 24 additions & 2 deletions toqito/matrix_ops/tests/test_tensor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Test tensor."""
import numpy as np
import pytest

from toqito.matrix_ops import tensor
from toqito.states import basis
Expand Down Expand Up @@ -150,7 +151,28 @@ def test_tensor_list_3():
np.testing.assert_equal(np.all(bool_mat), True)


def test_tensor_with_three_or_more_matrices():
"""Test tensor product with a numpy array containing three or more matrices."""
# Three matrices to be Kronecker multiplied
matrix1 = np.array([[1, 2]])
matrix2 = np.array([[3], [4]])
matrix3 = np.array([[5, 6]])
matrix4 = np.array([[7, 8]])

# The numpy array containing the matrices
matrices = np.array([matrix1, matrix2, matrix3, matrix4], dtype=object)

# Expected output: Kronecker product of matrix1, matrix2, and matrix3
expected_output = np.kron(np.kron(matrix1, np.kron(matrix2, matrix3)), matrix4)

# Call the tensor function
result = tensor(matrices)

# Assert that the result is as expected
np.testing.assert_array_equal(result, expected_output)


def test_tensor_empty_args():
r"""Test tensor with no arguments."""
with np.testing.assert_raises(ValueError):
tensor()
with pytest.raises(ValueError):
tensor()
31 changes: 9 additions & 22 deletions toqito/matrix_ops/tests/test_unvec.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
"""Test unvec."""
import numpy as np
import pytest

from toqito.matrix_ops import unvec


def test_unvec():
"""Test standard unvec operation on a vector."""
expected_res = np.array([[1, 2], [3, 4]])

test_input_vec = np.array([1, 3, 2, 4])

res = unvec(test_input_vec)

bool_mat = np.isclose(res, expected_res)
np.testing.assert_equal(np.all(bool_mat), True)


def test_unvec_custom_dim():
"""Test standard unvec operation on a vector with custom dimension."""
expected_res = np.array([[1], [3], [2], [4]])

test_input_vec = np.array([1, 3, 2, 4])

res = unvec(test_input_vec, [4, 1])

bool_mat = np.isclose(res, expected_res)
np.testing.assert_equal(np.all(bool_mat), True)
@pytest.mark.parametrize("vector, shape, expected_result", [
# Test standard unvec operation on a vector.
(np.array([1, 3, 2, 4]), None, np.array([[1, 2], [3, 4]])),
# Test standard unvec operation on a vector with custom dimension.
(np.array([1, 3, 2, 4]), [4, 1], np.array([[1], [3], [2], [4]])),
])
def test_unvec(vector, shape, expected_result):
np.testing.assert_array_equal(unvec(vector, shape), expected_result)
17 changes: 7 additions & 10 deletions toqito/matrix_ops/tests/test_vec.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
"""Test vec."""
import numpy as np
import pytest

from toqito.matrix_ops import vec


def test_vec():
"""Test standard vec operation on a matrix."""
expected_res = np.array([[1], [3], [2], [4]])

test_input_mat = np.array([[1, 2], [3, 4]])

res = vec(test_input_mat)

bool_mat = np.isclose(res, expected_res)
np.testing.assert_equal(np.all(bool_mat), True)
@pytest.mark.parametrize("vector, expected_result", [
# Test standard vec operation on a vector.
(np.array(np.array([[1, 2], [3, 4]])), np.array([[1], [3], [2], [4]])),
])
def test_vec(vector, expected_result):
np.testing.assert_array_equal(vec(vector), expected_result)
Loading