-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
MAINT: Remove similar branches from linalg.lstsq #9986
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
Changes from 2 commits
a1af647
a311a8d
6f83089
e3a50a9
3402dcf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1982,7 +1982,11 @@ def lstsq(a, b, rcond="warn"): | |
ldb = max(n, m) | ||
if m != b.shape[0]: | ||
raise LinAlgError('Incompatible dimensions') | ||
|
||
t, result_t = _commonType(a, b) | ||
real_t = _linalgRealType(t) | ||
result_real_t = _realType(result_t) | ||
|
||
# Determine default rcond value | ||
if rcond == "warn": | ||
# 2017-08-19, 1.14.0 | ||
|
@@ -1997,8 +2001,6 @@ def lstsq(a, b, rcond="warn"): | |
if rcond is None: | ||
rcond = finfo(t).eps * ldb | ||
|
||
result_real_t = _realType(result_t) | ||
real_t = _linalgRealType(t) | ||
bstar = zeros((ldb, n_rhs), t) | ||
bstar[:b.shape[0], :n_rhs] = b.copy() | ||
a, bstar = _fastCopyAndTranspose(t, a, bstar) | ||
|
@@ -2039,28 +2041,35 @@ def lstsq(a, b, rcond="warn"): | |
0, work, lwork, iwork, 0) | ||
if results['info'] > 0: | ||
raise LinAlgError('SVD did not converge in Linear Least Squares') | ||
resids = array([], result_real_t) | ||
if is_1d: | ||
x = array(ravel(bstar)[:n], dtype=result_t, copy=True) | ||
if results['rank'] == n and m > n: | ||
if isComplexType(t): | ||
resids = array([sum(abs(ravel(bstar)[n:])**2)], | ||
dtype=result_real_t) | ||
else: | ||
resids = array([sum((ravel(bstar)[n:])**2)], | ||
dtype=result_real_t) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In what makes no sense at all, this branch produces the same effect as the one that follows it. |
||
|
||
# undo transpose imposed by fortran-order arrays | ||
b_out = bstar.T | ||
|
||
# b_out contains both the solution and the components of the residuals | ||
x = b_out[:n,:] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP8, no alignment like this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, PEP8 shows a bunch of other whitespace violations in |
||
r_parts = b_out[n:,:] | ||
if isComplexType(t): | ||
resids = sum(abs(r_parts)**2, axis=-2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wish we had a sensible There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not (at least on my machine), but fine to let this be. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not faster, or it's not guilty of introducing the ULP error? Seems to me that there must be some value for which There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just meant that Anyway, fine to not worry about it here! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've contemplated adding a ufunc for the squared absolute value, the main problem seems to be the name. |
||
else: | ||
x = array(bstar.T[:n,:], dtype=result_t, copy=True) | ||
if results['rank'] == n and m > n: | ||
if isComplexType(t): | ||
resids = sum(abs(bstar.T[n:,:])**2, axis=0).astype( | ||
result_real_t, copy=False) | ||
else: | ||
resids = sum((bstar.T[n:,:])**2, axis=0).astype( | ||
result_real_t, copy=False) | ||
resids = sum(r_parts**2, axis=-2) | ||
|
||
rank = results['rank'] | ||
|
||
st = s[:min(n, m)].astype(result_real_t, copy=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This slice was pointless, because |
||
return wrap(x), wrap(resids), results['rank'], st | ||
# remove the axis we added | ||
if is_1d: | ||
x = x.squeeze(axis=-1) | ||
# we probably should squeeze resids too, but we can't | ||
# without breaking compatibility. | ||
|
||
# as documented | ||
if rank != n or m <= n: | ||
resids = array([], result_real_t) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bizarre interface, and |
||
|
||
# coerce output arrays | ||
s = s.astype(result_real_t, copy=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree - kept only because it was there before. |
||
resids = resids.astype(result_real_t, copy=False) # array is temporary | ||
x = x.astype(result_t, copy=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Maybe this is trying to deal with a subclass that has a different default for Comment seems reasonable here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's fine. If one were to design this from scratch, one would do the coercion only if an output array was given... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking back, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Or maybe just work with the dtype passed in, rather than always promoting to double before handing off to the ufunc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That works only if one also uses different LAPACK routines (which is fine, of course), and would be less precise. But seems more logical in any case; just a different |
||
return wrap(x), wrap(resids), rank, s | ||
|
||
|
||
def _multi_svd_norm(x, row_axis, col_axis, op): | ||
|
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.
Not this PR, but when I looked at this before, I wondered what would be the point of
.copy()
; it is not like a view gets taken and this cannot be of much speed benefit for the whole routine.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.
Yeah, the
copy
stuff here is weird.