-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
Handling ndarrays with singular matrices in linalg functions #6027
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
Comments
I don't know of any really good workarounds, no. There was some discussion of this issue when we first merged the ability to solve stacks of equations in a single call (which happened in #3220, a follow-up to #2954, and see also #3217). Basically, we all agreed that the I posted some general thoughts on how this might work, and the questions we'd need to answer, here. If I were going to spitball a solution off the top of my head, it'd be something like:
So the idea would be that by default we would continue to error (or at least warn) when singular matrices were passed to
and silently get back matrices full of NaNs when appropriate. That's just one idea, though; any real proposal would need a bit of thought into the questions posted in that link above, and to then get posted on the mailing list for wider review to make sure we didn't accidentally miss some important issue. |
As far as I remember, the underlying gufunc used to implement solve does report any error in the underlying call to LAPACK by setting the results to NaNs. The linalg module function provides an "extobj" so that if that condition happens the exception is raised. Maybe using seterr to 'ignore' for invalid will prevent the exception from being raised, with invalid entries having its results set to NaN. It could also be possible to call the underlying gufunc without extobj (and using the appropriate seterr as well). Maybe adding a keyword to the linalg wrappers so that they don't raise exceptions and just return the results with NaNs for invalid entries would be useful (this could be implemented in all the linalg functions that are 'gufunc-like' and that can raise exceptions). Another option would be to have the results available even if an exception is raised (maybe in the exception object). This would allow the user the following 3 options:
|
IIRC, what was not decided is the precise API to be used for the error
handling.
.
Raising exceptions is IMHO a bad idea in the first place. Small fp
perturbations can make the LAPACK algorithms return with no error, but
with garbage results --- the exceptions don't guard against this and are
just a nuisance. Error tolerances / condition number limits could be
used, but their values would need to be tunable by the user. Many other
compsci software just emits warnings on potential numerical instability,
returning best-efforts results.
.
Implementation-wise, controlling error state with keyword arguments in
the linalg functions should be fairly simple to implement just by
changing the code in linalg.py that raises the errors. Extending
np.seterr with an additional linalg flag requires more extensive changes.
.
Internally, numpy.linalg abuses the 'invalid' flag for reporting linalg
errors. seterr has currently no effect on raising errors; an explicit
error object is always used.
|
In fact, when implementing the gufuncs, error handling was a bit of a caveat, but IMHO, a plain exception raised when any of the elements has an error condition is Note that implementing a "noexcept" keyword would just be a matter of not providing and extobj to |
The linalg behavior probably shouldn't be controlled by the value of the
`invalid` seterr flag, I think, because linalg errors aren't directly
connected to the FP flags. noexpect=True then should pass in an extobj
that specifies 'ignore'.
.
Also, I think it is not a good approach to go with an approach where
"error" directly means "LAPACK routine returned error code" in all
cases. What 'error' means may be fairly different for eigenvalue
computation and matrix inversion. Although for the latter LAPACK returns
an error if it encounters pivoting failure, the amount of precision loss
is a continuum and a 'successful' return may well contain garbage.
|
I am trying to solve several independent systems of equations at the same time using
numpy.linalg.solve
, e.g.,a
has shape (N, M, M). The challenge I'm running into is how to deal with the case when, for some values of N, the last two dimensions comprise a singular matrix.Consider this example
On numpy 1.9.2, this will raise a
LinAlgError
, but I still would like to know the solutions for all the full-rank matrices. (I would be okay with getting back NaNs for the singular cases.) I'm aware I can compute the singular values and use fancy indexing to slice the array, but in my algorithm I have to do several slicing/filtering steps and I would prefer not to lose the alignment ofa
withb
-- my real-worlda
typically has 6-7 dimensions and all the indexing arrays make the code hard to follow.My ideal solution seems to involve masked arrays since I end up doing several other filtering steps, but it appears that most (all?) functions in the
linalg
family ignore array masks.Is there an alternative solution already available, or perhaps a suggestion on how I could contribute a solution that I could package as a PR?
The text was updated successfully, but these errors were encountered: