-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Added Golub Kahan Bidiagonalization with Householder Reflections #18797
Conversation
✅ Hi, I am the SymPy bot (v158). 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.6. Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it. Click here to see the pull request description that was parsed.
Update The release notes on the wiki have been updated. |
I only added to the code of matrices.py, eigen.py, test_eigen.py, and durations.json, but for some unknown reason, tests in number theory are failing. |
What should I do know? Can you please help a little @sylee957 . The tests that fail have no relation with my PR. https://travis-ci.org/sympy/sympy/builds/659763753?utm_source=github_status&utm_medium=notification |
I think that the test should be rerun as I deferred the issue in #18800 |
Can the algorithm be modified as a decomposition method to return the transformation matrix |
Yes, I will modify it and submit a PR soon. |
I have a few suggestions
|
…oth complex and real matrices, as well as upper and lower bidiagonalization
I have worked on your suggestions and here is the checklist,
|
For rectangular matrices, tests become too slow, so I had doubts on whether to add them or not. So should I add them. |
If you have concerns about some slowdowns, I'd recommend adding them as floating point tests rather than radicals. I also anticipate much slowdowns for stuff larger than There is |
|
Is there anything else that needs to be done? |
…bidiag_hholder, _bidiagonal_decmp_hholder
I think this can be improved. The test code here is very confusing because the asserts are a long way away from the calculations. It would be better to put them right next to them like:
There can sometimes be reasons for using random tests but I don't see the merit here because:
We also normally try to avoid using generic simplify in testing or library code because usually a specific simplification function is better. Why is simplify needed? I guess from an example that cancel is sufficient:
Maybe it's worth calling cancel on the outputs by default if this kind of simplification is usually beneficial. I just tried this example which seems to hang:
This also fails for simple symbolic examples: In [57]: x = Symbol('x', real=True)
In [58]: Matrix([[1, x], [x, 1]]).bidiagonalize()
---------------------------------------------------------------------------
TypeError: cannot determine truth value of Relational |
Thanks @oscarbenjamin for suggesting multiple changes,
In the above example itself, one has to apply cancel Further, for assert to not raise an Assertion Error, the matrices have to be exactly equal,
|
I tried doing the In [57]: x = Symbol('x', real=True)
In [58]: Matrix([[1, x], [x, 1]]).bidiagonalize() and the entire problem breaks down to: In [51]: x = Symbol('x', real=True)
In [52]: abs(1 + sqrt(1 + x**2)) >= abs(1 - sqrt(1 + x**2))
Out[52]:
________ │ ________ │
╱ 2 │ ╱ 2 │
╲╱ x + 1 + 1 ≥ │╲╱ x + 1 - 1│ now this above expression is always |
Is it fundamentally necessary to know which of the two expressions is bigger in order to make the algorithm work? This is important because it will be the ultimate limitation in the algorithm for the symbolic case. |
I am not sure, but after a lot of random tests and some pen and paperwork, I found out that the else block is responsible for flipping the sign of the diagonal element corresponding to the column being operated on, to make all diagonal values positive. if v_plus.norm() <= v_minus.norm():
v = v_plus
else:
v = v_minus and if we remove that, it would still work fine, the only thing is that signs of some values, get flipped. Technically it should be correct because the householder matrix just reflects about a plane/hyperplane and it seems totally valid as the definition of a bidiagonal matrix nowhere states that the diagonal elements must be positive. However, I couldn't find any official source or research paper stating this, so I am not 100% sure. What's your opinion on this, sir? |
I think that I'm also thinking that just using the direct formula can be better than using the Golub's construction Because it gives a worse result for symbolic construction. (Latter is Golub's construction) |
I realized and agree that v_plus and v_minus can be chosen arbitrarily, however, I also think that both of them can be eliminated and we can also eliminate the check. |
References to other Issues or PRs
Brief description of what is fixed or changed
Added Golub Kahan Bidiagonalization
Other comments
#18775
Release Notes