def random_density_matrix( dim: int, is_real: bool = False, k_param: Union[List[int], int] = None, distance_metric: str = "haar", ) -> np.ndarray: """ 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. :param dim: The number of rows (and columns) of the density matrix. :param is_real: Boolean denoting whether the returned matrix will have all real entries or not. :param k_param: Default value is equal to `dim`. :param 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. :return: A `dim`-by-`dim` random density matrix. """ if k_param is None: k_param = dim # Haar / Hilbert-Schmidt measure. gin = np.random.rand(dim, k_param) if not is_real: gin = gin + 1j * np.random.rand(dim, k_param) if distance_metric == "bures": gin = np.matmul(random_unitary(dim, is_real) + np.identity(dim), gin) rho = np.matmul(gin, np.matrix(gin).H) return np.divide(rho, np.trace(rho))
def test_is_unitary(self): """Test that unitary matrix returns True.""" mat = random_unitary(2) self.assertEqual(is_unitary(mat), True)
def test_random_unitary_not_real(self): """Generate random non-real unitary matrix.""" mat = random_unitary(2) self.assertEqual(is_unitary(mat), True)
def test_random_unitary_vec_dim(self): """Generate random non-real unitary matrix.""" mat = random_unitary([4, 4], True) self.assertEqual(is_unitary(mat), True)
def random_density_matrix( dim: int, is_real: bool = False, k_param: Union[List[int], int] = None, distance_metric: str = "haar", ) -> 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 :math:`n`- dimensional density matrix. For :math:`d=2`, this can be accomplished as follows. >>> from toqito.random.random_density_matrix import random_density_matrix >>> complex_dm = random_density_matrix(2) >>> complex_dm [[0.34903796+0.j 0.4324904 +0.103298j] [0.4324904 -0.103298j 0.65096204+0.j ]] We can verify that this is in fact a valid density matrix using the `is_denisty` function from `toqito` as follows >>> from toqito.linear_algebra.properties.is_density import is_density >>> is_density(complex_dm) True We can also generate random density matrices that are real-valued as follows. >>> from toqito.random.random_density_matrix import random_density_matrix >>> real_dm = random_density_matrix(2, is_real=True) >>> real_dm [[0.37330805 0.46466224] [0.46466224 0.62669195]] Again, verifying that this is a valid density matrix can be done as follows. >>> from toqito.linear_algebra.properties.is_density import is_density >>> is_density(real_dm) True 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. >>> from toqito.random.random_density_matrix import random_density_matrix >>> bures_mat = random_density_matrix(2, distance_metric="bures") >>> bures_mat [[0.59937164+0.j 0.45355087-0.18473365j] [0.45355087+0.18473365j 0.40062836+0.j ]] As before, we can verify that this matrix generated is a valid density matrix. >>> from toqito.linear_algebra.properties.is_density import is_density >>> is_density(bures_mat) 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 real entries or not. :param k_param: Default value is equal to `dim`. :param 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. :return: A `dim`-by-`dim` random density matrix. """ if k_param is None: k_param = dim # Haar / Hilbert-Schmidt measure. gin = np.random.rand(dim, k_param) if not is_real: gin = gin + 1j * np.random.rand(dim, k_param) if distance_metric == "bures": gin = np.matmul(random_unitary(dim, is_real) + np.identity(dim), gin) rho = np.matmul(gin, np.matrix(gin).H) return np.divide(rho, np.trace(rho))