New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix the Ket*Op -> Op*Ket Bug in qapply and _apply_operator #24164
Conversation
✅ Hi, I am the SymPy bot (v167). I'm here to help you write a release notes entry. Please read the guide on how to write release notes. Your release notes are in good order. Here is what the release notes will look like:
This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.12. Click here to see the pull request description that was parsed.
Update The release notes on the wiki have been updated. |
This looks okay to me except there should be some added tests for Also try to imagine someone reading the release note in the context of the release notes page: Someone reading that won't now what "the bug" means and won't really care about internal methods like |
Benchmark results from GitHub Actions Lower numbers are good, higher numbers are bad. A ratio less than 1 Significantly changed benchmark results (PR vs master) Significantly changed benchmark results (master vs previous release) before after ratio
[41d90958] [b1de2706]
<sympy-1.11.1^0>
- 993±2μs 620±1μs 0.62 solve.TimeSparseSystem.time_linear_eq_to_matrix(10)
- 2.84±0.01ms 1.16±0ms 0.41 solve.TimeSparseSystem.time_linear_eq_to_matrix(20)
- 5.63±0.01ms 1.69±0ms 0.30 solve.TimeSparseSystem.time_linear_eq_to_matrix(30)
Full benchmark results can be found as artifacts in GitHub Actions |
I edited the release notes to
So some code / expressions that (maybe inadvertently) relied on this behaviour will now return correct but unexpected results. But in my oppinion we don't break an existing feature. What we do is removing an undocumented and incorrect behaviour. So no 'Breaking' remark is required. |
Can we say now that this fixes #6073 with the added tests? |
It is unfortunate that no example has been given in #6073, so we cannot test it. It looked clearly similar, but the reason is that #6073 says that lhs and rhs don't know how to apply to each other, explicitly lhs._apply_operator(rhs) and rhs._apply_operator(lhs) both are not defined. This is definitely different from the situation I'm fixing here, where quite the opposite is the case: at least oneof lhs._apply_operator(rhs), rhs._apply_operator(lhs) are defined, but are applied incorrectly. |
References to other Issues or PRs
Fixes #24158
Brief description of what is fixed or changed
See issue #24158. It might also fix #6073 (not tested).
qapply may wrongly associate kets to operators from the left, e.g. |1> X -> |0>, which leads to wrong results. Note in the example Qubit(1)=|1>, QubitBra(1)=<1| and XGate(0)=X the CNOT gate:
You might consider P2 posed unclearly, but expression P1 is perfectly legal and may easily come up when building expressions in code.
Assessment
P0 already demonstrates the core issue: From the code analysis it seems that qapply has been written to accept and automatically 'correct' the (undefined) term
Ket*Operator
toOperator*Ket
. However as shown above this behaviour may lead to fatally wrong results and should be removed.Modifications
See #24158 for a technical description of the situation and the required modifications. In a nut shell:
In some Ket-classes the incorrect definitions of and calls to
Ket._apply_operator(op)
to computeKet*op
- which is undefined but returnedop*Ket
instead - are renamed to_apply_from_right_to()
so qapply (which is also patched) will call them in the correct context ofop*Ket
only.Other comments
._apply_operator_*
and._apply_from_right_to_*
are related to each other as is.__mul__
to.__rmul__
.Release Notes
qapply
would evaluateKet * Operator
in expressions asOperator * Ket
. This behavior could lead to incorrect results and has been removed.