Skip to content

Commit

Permalink
Merge pull request #265 from vprusso/improve-rand-tests
Browse files Browse the repository at this point in the history
Improve rand tests
  • Loading branch information
vprusso authored Nov 25, 2023
2 parents 08ea5ee + e00c182 commit 77e9363
Show file tree
Hide file tree
Showing 57 changed files with 730 additions and 698 deletions.
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

0 comments on commit 77e9363

Please sign in to comment.