Source code for toqito.rand.random_psd_operator
"""Generates a random positive semidefinite operator."""
import numpy as np
[docs]
def random_psd_operator(
dim: int,
is_real: bool = False,
seed: int | None = None,
) -> np.ndarray:
r"""Generate a random positive semidefinite operator.
A positive semidefinite operator is a Hermitian operator that has only real and non-negative eigenvalues.
This function generates a random positive semidefinite operator by constructing a Hermitian matrix,
based on the fact that a Hermitian matrix can have real eigenvalues.
Examples:
Using `|toqito⟩`, we may generate a random positive semidefinite matrix.
For \(\text{dim}=2\), this can be accomplished as follows.
```python exec="1" source="above" session="psd_operator"
from toqito.rand import random_psd_operator
complex_psd_mat = random_psd_operator(2)
print(complex_psd_mat)
```
We can confirm that this matrix indeed represents a valid positive semidefinite matrix by utilizing
the `is_positive_semidefinite` function from the `|toqito⟩` library, as demonstrated below:
```python exec="1" source="above" session="psd_operator"
from toqito.matrix_props import is_positive_semidefinite
print(is_positive_semidefinite(complex_psd_mat))
```
We can also generate random positive semidefinite matrices that are real-valued as follows.
```python exec="1" source="above" session="psd_operator"
from toqito.rand import random_psd_operator
real_psd_mat = random_psd_operator(2, is_real=True)
print(real_psd_mat)
```
Again, verifying that this is a valid positive semidefinite matrix can be done as follows.
```python exec="1" source="above" session="psd_operator"
from toqito.matrix_props import is_positive_semidefinite
print(is_positive_semidefinite(real_psd_mat))
```
It is also possible to add a seed for reproducibility.
```python exec="1" source="above" session="psd_operator"
from toqito.rand import random_psd_operator
seeded = random_psd_operator(2, is_real=True, seed=42)
print(seeded)
```
Args:
dim: The dimension of the operator.
is_real: Boolean denoting whether the returned matrix will have all real entries or not. Default is `False`.
seed: A seed used to instantiate numpy's random number generator.
Returns:
A `dim` x `dim` random positive semidefinite matrix.
"""
# Generate a random matrix of dimension dim x dim.
gen = np.random.default_rng(seed=seed)
rand_mat = gen.random((dim, dim))
# If is_real is False, add an imaginary component to the matrix.
if not is_real:
rand_mat = rand_mat + 1j * gen.random((dim, dim))
# Constructing a Hermitian matrix.
rand_mat = (rand_mat.conj().T + rand_mat) / 2
eigenvals, eigenvecs = np.linalg.eigh(rand_mat)
Q, R = np.linalg.qr(eigenvecs)
return Q @ np.diag(np.abs(eigenvals)) @ Q.conj().T