Use SVD-based fidelity for density matrices and add numerical stability test
Summary
Fixes #4819
This PR replaces the existing eigen‑decomposition formula for two density matrices
state1_sqrt = _sqrt_positive_semidefinite_matrix(state1)
eigs = eigvalsh(state1_sqrt @ state2 @ state1_sqrt)
trace = sum(sqrt(abs(eigs)))
fidelity = trace**2
with an equivalent but more accurate form
rho1_sqrt = scipy.linalg.sqrtm(rho1)
rho2_sqrt = scipy.linalg.sqrtm(rho2)
fidelity = np.sum(scipy.linalg.svdvals(rho1_sqrt @ rho2_sqrt)) ** 2
This ensures fidelity never exceeds 1 due to round‑off error in higher dimensions.
What’s Changed
In cirq/qis/measures.py, the density‑matrix branch of _fidelity_state_vectors_or_density_matrices now uses sqrtm + svdvals. A new unit test test_fidelity_numerical_stability_high_dim in measures_test.py constructs a 10‑qubit pure state, traces out one qubit, and verifies that the old eigen‑value‑based fidelity exceeds 1, and the new SVD‑based fidelity ≈ 1.
Testing
Ran pytest cirq-core/cirq/qis/measures_test.py::test_fidelity_numerical_stability_high_dim — old formula fails (>1), new passes (≈1).
Codecov Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 98.68%. Comparing base (e9a592d) to head (9a46b19).
:warning: Report is 249 commits behind head on main.
Additional details and impacted files
@@ Coverage Diff @@
## main #7292 +/- ##
=======================================
Coverage 98.68% 98.68%
=======================================
Files 1112 1112
Lines 97599 97616 +17
=======================================
+ Hits 96315 96334 +19
+ Misses 1284 1282 -2
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
- :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
@RevanthGundala would you be able to take a look at the merge conflicts?
This pull request has been automatically labeled as stale because 90 days have passed without comments or other activity. If no further activity occurs and the status/stale label is not removed by a maintainer within 60 days, this pull request will be closed. If you would like to restore its active status, please leave a comment here; doing so will cause the staleness handler to remove the label.
If you have questions or feedback about this process, we welcome your input. You can open a new issue to let us know (please also reference this issue there, for continuity), or reach out to the project maintainers at [email protected].
This pull request has been automatically labeled as stale because 90 days have passed without comments or other activity. If no further activity occurs and the status/stale label is not removed by a maintainer within 60 days, this pull request will be closed. If you would like to restore its active status, please leave a comment here; doing so will cause the staleness handler to remove the label.
If you have questions or feedback about this process, we welcome your input. You can open a new issue to let us know (please also reference this issue there, for continuity), or reach out to the project maintainers at [email protected].