-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
ENH: add hermitian=False kwarg to np.linalg.matrix_rank #8557
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
Conversation
numpy/linalg/linalg.py
Outdated
None, and ``S`` is an array with singular values for `M`, and | ||
``eps`` is the epsilon value for datatype of ``S``, then `tol` is | ||
set to ``S.max() * max(M.shape) * eps``. | ||
symmetric : bool, optional | ||
If True (default), `M` is assumed to be square and symmetric, enabling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its not the default.
More tests could be nice, such as also for the tolerance. Which also makes me wonder, the singular values are not quite the eigenvalues, no? So if you would change to symmetric, the difference, with respect to the tolerance setting, should be more then just numerical accuracy? |
Should I make a new method for the symmetric option tests or keep them where they are now? My last commit fixes the discrepancy by using the absolute value of the eigenvalues, which (as I understand the math) exactly matches the singular values for a symmetric matrix:
Combining these equalities gives us |
Yeah, probably right for symmetry. Do whatever you feel looks nicer, my guess is, it would look nicer in different functions ;) and making tests shorter makes it easier to find the code that broke if it gets triggered. |
What is the speed/accuracy advantage? |
Isn't the title of this PR incorrect? Looks like matrix_rank is the relevant function. Same with the summary line of the first commit. |
@charris: Oops, you're correct on the title mixup. My bad. Here's some unscientific testing on my Ubuntu machine with master-branch numpy:
|
I'm not sure how to tell which method is more numerically accurate. They do produce very slightly different results on large badly-scaled matrices, but it's unclear which introduces more floating-point error. |
How about the name |
@charris I changed it to |
☔ The latest upstream changes (presumably #8368) made this pull request unmergeable. Please resolve the merge conflicts. |
Would be better as a rebase rather than a merge. Also, this will conflict with #8682 anyway |
Given we already have
|
Yeah, I was trying out Github's web-based conflict resolution tool. It's nice, but a rebase would indeed be cleaner. If the Github folks are watching, maybe that would be a nice feature to add? ;-) I'll rebase and squash when/if this PR is accepted for merging, especially because I need to fix my commit message. I'm -1 for |
One benefit of adding a |
☔ The latest upstream changes (presumably #8682) made this pull request unmergeable. Please resolve the merge conflicts. |
Needs rebase |
Rebased and squashed, and updated the title. |
numpy/linalg/linalg.py
Outdated
if hermitian: | ||
S = eigvalsh(M) | ||
else: | ||
S = abs(svd(M, compute_uv=False)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this abs
appear? Should it be in the other branch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See this comment for the derivation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think you should have abs(eigvalsh(X))
on the line above. Why are you changing what happens for hermitian = False
? Was there a bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof, my bad! Fixed now.
numpy/linalg/linalg.py
Outdated
hermitian : bool, optional | ||
If True, `M` is assumed to be Hermitian (symmetric if real-valued), | ||
enabling the use of a more efficient method for finding singular values. | ||
Defaults to False. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs .. versionadded:: 1.14
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Do we want to consider allowing |
I'm not sure how useful allowing |
I agree, but we already expose it on No need to change this PR further |
I've opened gh-9436 to get that roadmap out explicitly. |
Needs a release note. Might be nice to add a benchmark comparing hermitian with not, but not necessary. |
e90561b
to
4539ca9
Compare
Added a release note and rebased. I didn't add an asv benchmark because those are more useful for tracking efficiency improvements for the same codepaths. I did run a final sanity check using
|
4539ca9
to
7125968
Compare
Rebased to fix merge conflicts. |
More conflicts, I'm afraid. I'll try and merge this before it conflicts again |
Conflicts resolved. |
I don't agree with that last commit - that doesn't seem to match the style of other files. Can you push again without that commit? Also, I don't think I can restart appveyor with a |
140bd41
to
22792eb
Compare
With a symmetric matrix, the more efficient `eigvalsh` method can be used to find singular values.
22792eb
to
ae1191b
Compare
Ok, I reverted that change and squashed the commits. Hopefully appveyor will work this time! |
Oh I see - the last commit brought it in line with what it was before. Whatever, let's just put this in, since the tests now run. Thanks @perimosocordiae! |
Thanks for sticking with this, @eric-wieser ! |
With a symmetric matrix, the more efficient
eigvalsh
method can be used to find singular values.This PR also make some minor docstring fixes, and uses the more efficient
count_nonzero
method.