-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
BUG: Always return a real dtype from linalg.cond (gh-18304) #29333
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
base: main
Are you sure you want to change the base?
Conversation
Addresses numpygh-18304. The condition number of a matrix is the product of two norms, which are always non-negative and real-valued, so the condition number itself should be non-negative and real-valued. This commit returns the proper real dtype from `linalg.cond`, and includes tests for the condition number of a complex matrix in various norms.
numpy/linalg/_linalg.py
Outdated
return r | ||
# Return the absolute value, since the condition number is | ||
# always a non-negative real number. | ||
return abs(r) |
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.
Thanls, I am sure it's correct, but I do feel it should probably be more targeted to where the complex number comes from here.
This commit addresses a reviewer comment on the blanket application of `abs(r)`. It specifically ensures the return type of complex-valued matrices will be the corresponding real type.
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.
Thanks, LGTM. I do wonder if we should add a release note, since it is a subtle fix, but it seems pretty hard to run into issues due to not getting a complex value.
@@ -2011,6 +2011,7 @@ def cond(x, p=None): | |||
# contain nans in the entries where inversion failed. | |||
_assert_stacked_square(x) | |||
t, result_t = _commonType(x) | |||
result_t = _realType(result_t) # condition number is always real | |||
signature = 'D->D' if isComplexType(t) else 'd->d' | |||
with errstate(all='ignore'): | |||
invx = _umath_linalg.inv(x, signature=signature) |
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.
So, I think this is fine. Your other comment (deleted now) is not wrong, in that it would be fine to cast invx
to the original result_t
to achieve the right thing.
(Norm might in some paths end up casting back and forth then, but it would work too.)
I agree that a release note is probably not needed. There is functionally no difference, since the imaginary part was always 0 anyway. There are no member functions that differ between |
Addresses gh-18304.
The condition number of a matrix is the product of two norms, which are
always non-negative and real-valued, so the condition number itself
should be non-negative and real-valued. This commit returns the proper
real dtype from
linalg.cond
, and includes tests for the conditionnumber of a complex matrix in various norms.
The existing docstring for
linalg.cond
already states that the return value iseither a float or inf, so the function behavior is now consistent with the
docstring.