Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1543fc3
parameterize random_psd_operator with wishart option
aman-coder03 Jan 23, 2026
0a76570
adding tests
aman-coder03 Jan 23, 2026
4386100
parametrize tests
aman-coder03 Jan 23, 2026
033ebac
implementing the feedback
aman-coder03 Jan 24, 2026
6582e49
Merge branch 'master' into feature/random-psd-parameterization
aman-coder03 Feb 5, 2026
69dc08e
enhance wishart sampling with scale matrix and df parameterization
aman-coder03 Feb 5, 2026
2e0f4c7
enhance random_psd_operator with parameterized Wishart distribution s…
aman-coder03 Feb 24, 2026
04ee607
reordering
aman-coder03 Feb 24, 2026
b178239
Merge branch 'master' into feature/random-psd-parameterization
aman-coder03 Feb 24, 2026
68371dc
address reviewer feedback:docstring format, validation, wishart fixes…
aman-coder03 Mar 3, 2026
d9f6407
Merge branch 'feature/random-psd-parameterization' of https://github.…
aman-coder03 Mar 3, 2026
2b1e616
Merge branch 'master' into feature/random-psd-parameterization
aman-coder03 Mar 3, 2026
3190b3e
fix invalid non-PSD scale matrix shape in test
aman-coder03 Mar 3, 2026
3821e99
Merge branch 'feature/random-psd-parameterization' of https://github.…
aman-coder03 Mar 3, 2026
c43e400
fix docstring format, add wishart expected values, rank-deficient war…
aman-coder03 Mar 6, 2026
a11999f
Merge branch 'master' into feature/random-psd-parameterization
aman-coder03 Mar 14, 2026
789b245
Merge branch 'master' into feature/random-psd-parameterization
aman-coder03 Mar 19, 2026
3e1cb51
address reviewer feedback
aman-coder03 Mar 19, 2026
4d40650
Merge branch 'master' into feature/random-psd-parameterization
aman-coder03 Mar 19, 2026
0914f38
Merge branch 'master' into feature/random-psd-parameterization
aman-coder03 Apr 7, 2026
378bb08
fix review comments
aman-coder03 Apr 11, 2026
d4dfbeb
Merge branch 'feature/random-psd-parameterization' of https://github.…
aman-coder03 Apr 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions toqito/rand/random_psd_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def random_psd_operator(
dim: int,
is_real: bool = False,
seed: int | None = None,
distribution: str = "uniform",
) -> np.ndarray:
r"""Generate a random positive semidefinite operator.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring still uses the old Sphinx/RST format (.. jupyter-execute::, :param:, :return:,
Examples\n========). The rest of the codebase — including the closest precedent random_density_matrix.py —
has been migrated to Google-style with markdown-exec blocks. Compare:

PR (outdated):
Examples
========
.. jupyter-execute::
from toqito.rand import random_psd_operator
:param dim: ...
:return: ...

Expected (matches random_density_matrix.py):
Examples:
python exec="1" source="above" session="psd_operator" from toqito.rand import random_psd_operator ...
Args:
dim: ...
Returns:
...

The current master version of this file already uses the modern format. This PR would revert the docstring to
the old format, which would break the docs build.


Expand Down Expand Up @@ -77,21 +78,38 @@ def random_psd_operator(
:param is_real: Boolean denoting whether the returned matrix will have all real entries or not.
Default is :code:`False`.
:param seed: A seed used to instantiate numpy's random number generator.
:param distribution: Distribution used to generate the PSD operator.
Options are `"uniform"` (default) and `"wishart"`.
:return: A :code:`dim` x :code:`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))
if not isinstance(dim, int) or dim <= 0:
raise ValueError("`dim` must be a positive integer.")

# Constructing a Hermitian matrix.
rand_mat = (rand_mat.conj().T + rand_mat) / 2
eigenvals, eigenvecs = np.linalg.eigh(rand_mat)
if distribution == "uniform":
rand_mat = gen.random((dim, dim))

Q, R = np.linalg.qr(eigenvecs)
if not is_real:
rand_mat = rand_mat + 1j * gen.random((dim, dim))

return Q @ np.diag(np.abs(eigenvals)) @ Q.conj().T
rand_mat = (rand_mat.conj().T + rand_mat) / 2
eigenvals, eigenvecs = np.linalg.eigh(rand_mat)
Q, _ = np.linalg.qr(eigenvecs)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upper case letters are not appropriate for variable names according to PEP-8


return Q @ np.diag(np.abs(eigenvals)) @ Q.conj().T

elif distribution == "wishart":
if is_real:
X = gen.standard_normal((dim, dim))
else:
X = gen.standard_normal((dim, dim)) + 1j * gen.standard_normal((dim, dim))

return X @ X.conj().T

else:
raise ValueError(
"Invalid distribution. Supported options are 'uniform' and 'wishart'."
)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linter is set for 120 char-width:

Suggested change
raise ValueError(
"Invalid distribution. Supported options are 'uniform' and 'wishart'."
)
raise ValueError("Invalid distribution. Supported options are 'uniform' and 'wishart'.")

31 changes: 31 additions & 0 deletions toqito/rand/tests/test_random_psd_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,34 @@ def test_random_psd_operator_with_seed(dim, is_real, seed, expected_mat):
"""Test that random_psd_operator function returns the expected output when seeded."""
matrix = random_psd_operator(dim, is_real, seed)
assert_allclose(matrix, expected_mat)

def test_random_psd_operator_wishart():
"""Test Wishart distribution generates PSD matrix."""
mat = random_psd_operator(4, distribution="wishart")
assert mat.shape == (4, 4)
assert is_positive_semidefinite(mat)


def test_random_psd_operator_invalid_distribution():

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pytest.raises(ValueError) without match= is too permissive — any ValueError raised anywhere in the function will satisfy this assertion, including ones raised for unrelated reasons if the code is later refactored. Please add match="Supported options" (or similar) so the test actually pins the intended error path.

with pytest.raises(ValueError, match="Supported options"):
    random_psd_operator(4, distribution="invalid")

"""Test invalid distribution raises ValueError."""
with pytest.raises(ValueError):
random_psd_operator(4, distribution="invalid")

def test_random_psd_operator_invalid_dim_type():
"""Test invalid dim type raises ValueError."""
with pytest.raises(ValueError):
random_psd_operator("4")


def test_random_psd_operator_invalid_dim_negative():
"""Test negative dim raises ValueError."""
with pytest.raises(ValueError):
random_psd_operator(-2)


def test_random_psd_operator_wishart_real_branch():
"""Test Wishart distribution with real sampling branch."""
mat = random_psd_operator(4, is_real=True, distribution="wishart")
assert mat.shape == (4, 4)
assert is_positive_semidefinite(mat)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a way to use the pytest.parameterize decorator to consolidate these tests so that they are not all written as separate functions. You can refer to how this is used elsewhere in the repo for context/reference.

@aman-coder03 aman-coder03 Jan 23, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure @vprusso i will check and update shortly!