Source code for toqito.rand.random_density_matrix

"""Generates a random density matrix."""

import numpy as np

from toqito.rand import random_unitary


[docs] def random_density_matrix( dim: int, is_real: bool = False, k_param: list[int] | int | None = None, distance_metric: str = "haar", seed: int | None = None, ) -> np.ndarray: r"""Generate a random density matrix. Generates a random `dim`-by-`dim` density matrix distributed according to the Hilbert-Schmidt measure. The matrix is of rank <= `k_param` distributed according to the distribution `distance_metric` If `is_real = True`, then all of its entries will be real. The variable `distance_metric` must be one of: - `haar` (default): Generate a larger pure state according to the Haar measure and trace out the extra dimensions. Sometimes called the Hilbert-Schmidt measure when `k_param = dim`. - `bures`: The Bures measure. Examples: Using `|toqito⟩`, we may generate a random complex-valued \(n\)- dimensional density matrix. For \(d=2\), this can be accomplished as follows. ```python exec="1" source="above" session="complex_dm_example" from toqito.rand import random_density_matrix complex_dm = random_density_matrix(2) print(complex_dm) ``` We can verify that this is in fact a valid density matrix using the `is_density` function from `|toqito⟩` as follows ```python exec="1" source="above" session="complex_dm_example" from toqito.matrix_props import is_density print(is_density(complex_dm)) ``` We can also generate random density matrices that are real-valued as follows. ```python exec="1" source="above" session="real_dm_example" from toqito.rand import random_density_matrix real_dm = random_density_matrix(2, is_real=True) print(real_dm) ``` Again, verifying that this is a valid density matrix can be done as follows. ```python exec="1" source="above" session="real_dm_example" from toqito.matrix_props import is_density print(is_density(real_dm)) ``` By default, the random density operators are constructed using the Haar measure. We can select to generate the random density matrix according to the Bures metric instead as follows. ```python exec="1" source="above" session="bures_dm_example" from toqito.rand import random_density_matrix bures_mat = random_density_matrix(2, distance_metric="bures") print(bures_mat) ``` As before, we can verify that this matrix generated is a valid density matrix. ```python exec="1" source="above" session="bures_dm_example" from toqito.matrix_props import is_density print(is_density(bures_mat)) ``` It is also possible to pass a seed to this function for reproducibility. ```python exec="1" source="above" session="seeded_dm_example" from toqito.rand import random_density_matrix seeded = random_density_matrix(2, seed=42) print(seeded) ``` We can once again verify that this is in fact a valid density matrix using the `is_density` function from `|toqito⟩` as follows ```python exec="1" source="above" session="seeded_dm_example" from toqito.matrix_props import is_density seeded = random_density_matrix(2, seed=42) print(is_density(seeded)) ``` Args: dim: The number of rows (and columns) of the density matrix. is_real: Boolean denoting whether the returned matrix will have all real entries or not. k_param: Default value is equal to `dim`. distance_metric: The distance metric used to randomly generate the density matrix. This metric is either the Haar measure or the Bures measure. Default value is to use the Haar measure. seed: A seed used to instantiate numpy's random number generator. Returns: A `dim`-by-`dim` random density matrix. """ gen = np.random.default_rng(seed=seed) if k_param is None: k_param = dim # Haar / Hilbert-Schmidt measure. gin = gen.random((dim, k_param)) if not is_real: gin = gin + 1j * gen.standard_normal((dim, k_param)) if distance_metric == "bures": gin = random_unitary(dim, is_real, seed=seed) + np.identity(dim) @ gin rho = gin @ gin.conj().T return np.divide(rho, np.trace(rho))