Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
vprusso committed Oct 11, 2024
2 parents 886222c + 5812b50 commit d62400a
Show file tree
Hide file tree
Showing 18 changed files with 510 additions and 204 deletions.
174 changes: 1 addition & 173 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ numpy = "2.1.2"
scipy = "1.14.1"
scs = "3.2.7"
picos = "2.4.17"
qiskit = "1.2.4"


[tool.poetry.group.dev.dependencies]
Expand Down
17 changes: 15 additions & 2 deletions toqito/rand/random_circulant_gram_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np


def random_circulant_gram_matrix(dim: int) -> np.ndarray:
def random_circulant_gram_matrix(dim: int, seed: int | None = None) -> np.ndarray:
r"""Generate a random circulant Gram matrix of specified dimension.
A circulant matrix is a square matrix where the elements of each row are identical to the elements of the
Expand Down Expand Up @@ -38,6 +38,16 @@ def random_circulant_gram_matrix(dim: int) -> np.ndarray:
[0.04257471, 0.21058986, 0.42351891, 0.21058986],
[0.21058986, 0.04257471, 0.21058986, 0.42351891]])
It is also possible to pass a seed to this function for reproducibility.
>>> from toqito.rand import random_circulant_gram_matrix
>>> circulant_matrix = random_circulant_gram_matrix(4, seed=42)
>>> circulant_matrix
array([[ 0.69220011, -0.02116047, 0.12407687, -0.02116047],
[-0.02116047, 0.69220011, -0.02116047, 0.12407687],
[ 0.12407687, -0.02116047, 0.69220011, -0.02116047],
[-0.02116047, 0.12407687, -0.02116047, 0.69220011]])
References
==========
Expand All @@ -46,13 +56,16 @@ def random_circulant_gram_matrix(dim: int) -> np.ndarray:
:param dim: int
The dimension of the circulant matrix to generate.
:param seed: int | None
A seed used to instantiate numpy's random number generator.
:return: numpy.ndarray
A `dim` x `dim` real, symmetric, circulant matrix.
"""
gen = np.random.default_rng(seed=seed)
# Step 1: Generate a random diagonal matrix with non-negative entries
diag_mat = np.diag(np.random.rand(dim))
diag_mat = np.diag(gen.random(dim))

# Step 2: Construct the normalized DFT matrix
dft_mat = np.fft.fft(np.eye(dim)) / np.sqrt(dim)
Expand Down
24 changes: 21 additions & 3 deletions toqito/rand/random_density_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def random_density_matrix(
is_real: bool = False,
k_param: list[int] | int = None,
distance_metric: str = "haar",
seed: int | None = None,
) -> np.ndarray:
r"""Generate a random density matrix.
Expand Down Expand Up @@ -74,6 +75,21 @@ def random_density_matrix(
>>> is_density(bures_mat)
np.True_
It is also possible to pass a seed to this function for reproducibility.
>>> from toqito.rand import random_density_matrix
>>> seeded = random_density_matrix(2, seed=42)
>>> seeded
array([[0.82448019+0.j , 0.14841568-0.33318114j],
[0.14841568+0.33318114j, 0.17551981+0.j ]])
We can once again verify that this is in fact a valid density matrix using the
:code:`is_density` function from :code:`toqito` as follows
>>> from toqito.matrix_props import is_density
>>> is_density(seeded)
np.True_
:param dim: The number of rows (and columns) of the density matrix.
:param is_real: Boolean denoting whether the returned matrix will have all
Expand All @@ -83,20 +99,22 @@ def random_density_matrix(
density matrix. This metric is either the Haar
measure or the Bures measure. Default value is to
use the Haar measure.
:param seed: A seed used to instantiate numpy's random number generator.
:return: A :code:`dim`-by-:code:`dim` random density matrix.
"""
gen = np.random.default_rng(seed=seed)
if k_param is None:
k_param = dim

# Haar / Hilbert-Schmidt measure.
gin = np.random.rand(dim, k_param)
gin = gen.random((dim, k_param))

if not is_real:
gin = gin + 1j * np.random.randn(dim, k_param)
gin = gin + 1j * gen.standard_normal((dim, k_param))

if distance_metric == "bures":
gin = random_unitary(dim, is_real) + np.identity(dim) @ gin
gin = random_unitary(dim, is_real, seed=seed) + np.identity(dim) @ gin

rho = gin @ np.array(gin).conj().T

Expand Down
12 changes: 10 additions & 2 deletions toqito/rand/random_ginibre.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np


def random_ginibre(dim_n: int, dim_m: int) -> np.ndarray:
def random_ginibre(dim_n: int, dim_m: int, seed: int | None = None) -> np.ndarray:
r"""Generate a Ginibre random matrix :cite:`WikiCircLaw`.
Generates a random :code:`dim_n`-by-:code:`dim_m` Ginibre matrix.
Expand All @@ -23,6 +23,12 @@ def random_ginibre(dim_n: int, dim_m: int) -> np.ndarray:
array([[0.39166472-1.54657971j, 0.36538245+0.23324642j],
[0.50103695-0.25857737j, 0.8357054 +0.31404353j]])
It is also possible to pass a seed to this function for reproducibility.
>>> from toqito.rand import random_ginibre
>>> random_ginibre(2, 2, seed=42)
array([[ 0.21546751-1.37959021j, -0.73537981-0.92077996j],
[ 0.53064913+0.09039682j, 0.66507969-0.22361728j]])
References
Expand All @@ -33,7 +39,9 @@ def random_ginibre(dim_n: int, dim_m: int) -> np.ndarray:
:param dim_n: The number of rows of the Ginibre random matrix.
:param dim_m: The number of columns of the Ginibre random matrix.
:param seed: A seed used to instantiate numpy's random number generator.
:return: A :code:`dim_n`-by-:code:`dim_m` Ginibre random density matrix.
"""
return (np.random.randn(dim_n, dim_m) + 1j * np.random.randn(dim_n, dim_m)) / np.sqrt(2)
gen = np.random.default_rng(seed=seed)
return (gen.standard_normal((dim_n, dim_m)) + 1j * gen.standard_normal((dim_n, dim_m))) / np.sqrt(2)
Loading

0 comments on commit d62400a

Please sign in to comment.