ensure partial_trace raises ValueError for invalid parameters#1391
ensure partial_trace raises ValueError for invalid parameters#1391vprusso merged 8 commits intovprusso:masterfrom
partial_trace raises ValueError for invalid parameters#1391Conversation
|
@vprusso please have look and suggest if some changes need to be made! |
| return traced_rho | ||
|
|
||
| # Ensure input_mat is square. | ||
| if input_mat.ndim != 2 or input_mat.shape[0] != input_mat.shape[1]: |
There was a problem hiding this comment.
There is an is_square function in matrix_props/ that could be used instead.
There was a problem hiding this comment.
if i am importing is_square on the top of the file there is circular import error happening, so i am planning to insert it inside the function so that circular import error is solved.
There was a problem hiding this comment.
but doing so is causing the error in ruff check
There was a problem hiding this comment.
maybe i should use this logic only instead of importing?
if input_mat.ndim != 2 or input_mat.shape[0] != input_mat.shape[1]
e8acd19 to
eb51929
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1391 +/- ##
======================================
Coverage 98.3% 98.3%
======================================
Files 202 202
Lines 5212 5223 +11
Branches 1196 1201 +5
======================================
+ Hits 5124 5135 +11
Misses 46 46
Partials 42 42 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
fd64fe5 to
7263b63
Compare
|
@vprusso codecov locally is showing 100% now after updating the PR and rebasing |
vprusso
left a comment
There was a problem hiding this comment.
Clean PR -- the validation improvements are exactly the kind of defensive checks this function needed. A few minor notes:
Minor
1. Negative sys indices are now rejected
Previously, sys=-1 would silently work (Python negative indexing → last subsystem). The PR now rejects it. This is the right call for this domain (negative subsystem indices are almost certainly a bug), but worth noting as a behavior change.
2. Error message for 1D input
If someone passes a 1D array, the check input_mat.ndim != 2 triggers with "input_mat must be a square matrix." Technically correct but "must be a 2D square matrix" would be slightly more helpful. Very minor.
3. Pre-existing test file issue (not your PR)
Line 14 of the existing test file has a double comma in the parametrize string:
"input_mat, , sys_arg, dim_arg, msg",Not caused by this PR, just FYI.
Looks good to merge once CI passes.
65e5332 to
af3a4f4
Compare
af3a4f4 to
930a220
Compare
|
i have updated the error message to |
5fdc8f7 to
25f9e63
Compare
|
@vprusso can you please have a look at this PR now? |
vprusso
left a comment
There was a problem hiding this comment.
This looks good overall — the validation logic is solid and the tests are comprehensive. A few minor items:
1. Changed behavior for non-square matrix error message
The test on line 32 changed the expected error from "Cannot infer subsystem dimensions directly" to "input_mat must be a 2D square matrix". This is a behavior change — previously a 3x4 matrix would fall through to the dim-inference logic and fail there. The new explicit check is better, but just noting it's a subtle change in error message for existing users.
2. The dim type broadening is good
Accepting tuple and np.ndarray in addition to list (line 140) is a nice improvement — users often pass numpy arrays or tuples for dimensions.
3. The prod_dim != n check
Good addition at line 149. Previously this would silently produce wrong results for mismatched dims.
4. Negative index handling
The sys < 0 check is correct — numpy would wrap negative indices silently, which could produce unexpected results. Good catch.
Approve with minor suggestion
Consider adding the dim type check (else: raise ValueError) to the docstring's Raises section so users know what input types are accepted. Otherwise this is ready to merge.
267a813 to
17e83c5
Compare
|
added all |
|
@vprusso i have addressed all the feedback and the PR is ready for a final review and merge at your convenience. thank you! |
vprusso
left a comment
There was a problem hiding this comment.
Thanks for tackling #1388 — the validation logic itself is a clear improvement (the early square check in particular replaces a misleading "Cannot infer subsystem dimensions" error with an accurate one). A few things need to be addressed before this can merge.
Blocking
-
The docstring was duplicated into two formats. The PR inserts a new Sphinx-RST block (
Examples,.. jupyter-execute::,.. math::,:code:,:raises:,:param:,.. footbibliography::) from lines 32–126 while leaving the original mkdocs-style docstring (Args:/Returns:/Examples:with```python exec="1" ```fences) intact below it. toqito's docs are built with mkdocs + mkdocstrings + markdown-exec, not Sphinx — none of the RST directives will render, andhelp(partial_trace)now prints the description twice. The docstring rewrite is also outside the scope of #1388. Please remove the added RST block entirely and keep only the validation changes in this PR. If you want to overhaul the docstring format, that should be a separate PR/discussion. -
Orphan text at lines 127–128 (
subsystems are given by the vector \dim`…) is a leftover fragment from the duplication and will appear as garbled floating text inhelp()`. Will go away when the RST block is removed. -
Trailing newline was removed from
partial_trace.py(\ No newline at end of fileat the end of the diff). This will trip ruff's W292. Please add it back.
Non-blocking
-
Tuple inconsistency between
dimandsys.dimnow acceptstuple, butsysstill only acceptsint | list | np.ndarray. Either accepttuplefor both, or neither — and update the type annotations (sys: int | list[int] | None,dim: int | list[int] | np.ndarray | None) to match whichever you choose. -
Scope creep in the test file.
test_partial_trace.pyalso fixes an unrelated pre-existing typo in the parametrize id string ("input_mat, , sys_arg, dim_arg, msg"→"input_mat, sys_arg, dim_arg, msg"). That's a fine fix, but it should be called out in the PR description so reviewers aren't surprised. -
test_dim_list_branchesonly asserts.shape. Both parametrized cases ([2]and[2, 2]) will produce a 2×2 result regardless of whether the partial trace is computed correctly. Consider comparing against a known expected matrix so the test actually guards correctness of those branches. -
Consider validating the CVXPY
Variablepath. The new square check runs after theisinstance(input_mat, Variable)recursion, so it's exercised for Variable inputs too — but there's no test for that path. A one-line test passing a non-squareVariableand assertingValueErrorwould close the loop. -
Nit (l. 271):
any(s < 0 or s >= num_sys for s in sys)— after converting tonp.asarrayyou can do this vectorized (np.any((arr < 0) | (arr >= num_sys))), but the current form is fine.
| By default, the partial trace function in :code:`|toqito⟩` takes the trace of the second | ||
| subsystem. | ||
|
|
||
| .. jupyter-execute:: |
There was a problem hiding this comment.
This entire RST block (roughly lines 32–126) is Sphinx syntax — .. jupyter-execute::, .. math::, :code:, .. footbibliography::, :raises:, :param:, :return:. toqito's docs are rendered by mkdocs + mkdocstrings + markdown-exec, not Sphinx, so none of this will render, and it duplicates the original docstring that still follows below starting at the Args: section (line 130). help(partial_trace) will also print the description twice.
Please remove this RST block entirely — the docstring rewrite is out of scope for #1388 (which is just about validation). If you want to update the docstring later, that should be a separate PR.
| equal. Accepted types are :code:`int`, :code:`list`, :code:`tuple`, or | ||
| :code:`numpy.ndarray`. | ||
| :return: The partial trace of matrix :code:`input_mat`. | ||
| subsystems are given by the vector `dim` and the subsystems to take the trace on are |
There was a problem hiding this comment.
Orphan sentence left over from the duplication — this is a continuation of the opening paragraph at line 28–30 that got stranded between the new :return: line and the original Args: section. Will be cleaned up automatically once the RST block above is removed.
| ) | ||
| dim = np.array([dim, n // dim]) | ||
| elif isinstance(dim, list): | ||
| elif isinstance(dim, (list, tuple, np.ndarray)): |
There was a problem hiding this comment.
Good extension — accepting tuple and np.ndarray is more consistent with the type annotation. Two small things:
- The function annotation at line 14 declares
dim: int | list[int] | np.ndarray | None—tupleisn't listed there. Please add it (or droptuplefrom the runtime check). - For a numpy input, you now always call
np.array(dim)even when it's already anndarray.np.asarray(dim)avoids the unnecessary copy.
| prod_dim_sys = dim[sys] | ||
| sys = np.array([sys]) | ||
|
|
||
| elif isinstance(sys, (list, np.ndarray)): |
There was a problem hiding this comment.
dim was just extended to accept tuple, but sys still only accepts list/ndarray. A user passing partial_trace(mat, (0, 1), [2, 2]) will hit the else branch and get a ValueError — inconsistent with dim. Either accept tuple here too, or (preferably) standardize on one rule for both parameters and update the annotations to match.
| pt_mat = np.sum(pt_mat, axis=2) | ||
|
|
||
| return pt_mat | ||
| return pt_mat |
There was a problem hiding this comment.
The file no longer ends with a newline (\ No newline at end of file in the diff). ruff's W292 will flag this — please re-add the trailing newline.
decbb4f to
047e8d4
Compare
|
@vprusso , addressed all feedback!! |
Description
closes #1388
adds explicit validation checks to
partial_traceto ensure that invalid parameters raise clear and consistentValueError.specifically, this PR ensures:
input_matmust be square.np.prod(dim)must match the matrix dimension.sysindices must be within valid subsystem bounds.previously, some invalid inputs could result in NumPy
IndexErroror unintended behavior instead of a clearValueError.corresponding unit tests have been added to maintain coverage for the new validation logic.
Changes
dimproduct mismatchsysindicesChecklist