-
-
Notifications
You must be signed in to change notification settings - Fork 482
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
solve_left and solve_right should use coercion #12406
Comments
This comment has been minimized.
This comment has been minimized.
Branch: u/gh-mwageringel/12406 |
comment:6
Based on #17405. New commits:
|
Commit: |
Author: Markus Wageringel |
Dependencies: #17405 |
comment:8
A pynormaliz doctest fails in src/sage/geometry/polyhedron/library.py. |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:22
Replying to @orlitzky:
Scratch that, I see that the generic matrix code disagreed with its documentation all along. The MATLAB backslash operator doesn't check the rank, it only looks at the dimensions and does a QR solve regardless of the rank for a non-square matrix. It insists that square systems actually be solvable. So I would expect an error from |
comment:23
Ok, I finally have my head wrapped around this. The behavior promised by the In hindsight, the reason for setting I made a post to the -devel list asking about the behavior of So, here's the best solution that I was able to come up with. Instead of changing the superclass implementation, we change the documentation to admit that (a) we don't really implement the backslash the way MATLAB does, specifically with respect to rank-deficient matrices; and (b) the Here's the summary:
This doesn't attempt to implement the backslash exactly, but it does solve systems in a consistent(ish) manner regardless of whether or not the ring is exact. It also passes all of the doctests that don't refer specifically to the behavior that was changed on purpose. I've pushed a branch so you can see my proof-of-concept: sagemath/sagetrac-mirror@d596711 Please, take a look and see what you think. If you think it's a better approach, we can clean it up. If not... I tried. I'll give this a positive review if you prefer the original approach. |
comment:24
That branch is u/mjo/ticket/12406 if you'd rather look at it locally, by the way. |
comment:25
As I mentioned on sage-devel, I would prefer an implementation for inexact rings where square matrices and non-square matrices are treated differently. Contrary to what I said on devel though, I now realize that this is not consistent with exact rings: if a square matrix is singular to machine precision, an error is raised regardless of whether a solution exists or not, whereas over exact rings an error is raised only if a solution does not exist. Since we cannot in general detect such a degenerate situation over inexact rings however, this seems like the price we have to pay for inexact computations. Still, it seems important to get a predictable answer (the algorithm should not depend on numerical noise), so I would prefer to compute a least-squares solution only in the non-square case. This agrees with Matlab as well as SciPy treating the square situation differently. Getting a warning about a square matrix being singular can be a useful answer too, but it needs to be documented that this is different than in the exact case. Since the method is effectively broken for inexact rings currently, I do not expect these changes to cause many problems. I agree that the
if it was not for a test failure in The more I think about it though, it seems to me that the rank computation should be avoided even for exact rings. Computing the rank will usually involve some sort of echelonization I suppose which is already a major part of the work required to find a solution of a square system. Instead, we should remove the rank computation from the generic A couple of other thoughts: I still think it would be cleaner to call Replying to @orlitzky:
Indeed, this would be better for the rank computation, but it is different from how the coercion system usually works in Sage, so could lead to unexpected results. To the best of my knowledge, usually, the coercion system first searches for a common parent of two operands and only then invokes the appropriate binary operation on them. This is why the doctest
is justified, as it merely asserts that the answer is the same in either case. Because of that, I think it would be better to avoid using information obtained from the old parent, even if this is counter-intuitive. If we move the rank computation to
I agree. Ideally, it should be part of the coercion code (except in the non-integral-domain case), so changing rings happens only once. Replying to @orlitzky:
Indeed, this is not optimal. The superclass documentation should state that coercion is used on the arguments, and what the subclass method does (if it exists) should be consistent with what the superclass documentation says. There are two test failures with your branch.
I am not sure how The other failure is the peculiar doctest in I will try to see if I can make changes as outlined above if you agree. |
comment:26
Replying to @mwageringel:
Indeed, and I think the CBF doctest is wrong as well. It uses an indirect doctest instead of calling
Excellent point! I'm embarrassed that I stared at that In light of that, I agree with everything else you said. For inexact rings, we should go with the MATLAB behavior, even if it disagrees with the exact-ring behavior, because you can't know if the system is rank-deficient without first solving the problem. For backwards compatibility, we have to keep the exact-ring behavior roughly as it is, and document the difference. If we can try the square-nonsingular method first and have it fall back to the generic solve when the matrix isn't full rank, then that sounds reasonable to me. In the long term, I think it would be a better design to decree that subclasses should not override |
This comment has been minimized.
This comment has been minimized.
Changed dependencies from #17405 to none |
comment:28
I have updated the branch accordingly. The rank computation is now done in Additionally, I have added a doctest for the problem in #13932, which is solved by this branch since the New commits:
|
Changed branch from u/gh-mwageringel/12406 to u/gh-mwageringel/12406v2 |
comment:29
Instead of testing the string contents of the error message, what do you think about adding a new |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:31
That is a good idea. I have implemented it. |
comment:32
Let's get this over with =) The only other thing I see is in the new test,
to ensure that Thanks for sticking with this. I've been complaining about issues like this since I was an undergrad, but I never had the guts to tackle it myself. |
Branch pushed to git repo; I updated commit sha1 and set ticket back to needs_review. New commits:
|
comment:34
Thank you for the review and all the valuable input you provided. I have added the non-zeroness check to the doctest. Setting this back to positive. |
Changed branch from u/gh-mwageringel/12406v2 to |
This ticket uses coercion to find suitable parents for the arguments to
Matrix.solve_right
in order to solve these problems:This is implemented by moving the coercion code from
Matrix_double_dense.solve_right
, that was implemented in #17405, to the super class. As a result,Matrix_double_dense.solve_right
is redundant and therefore removed.The super method
Matrix.solve_right
is refactored a lot:check
parameter is ignored for inexact rings (see also solve_right fails with floating-point matrices #13932)solve_right
, but only in_solve_right_nonsingular_square
; this way, inexact rings overwriting the latter method can avoid computing the rank (which would not work over inexact rings)Additionally, this ticket adds support for calling
solve_right
/solve_left
with non-square matrices overRDF
/CDF
. In such cases,solve_right
returns the least-squares solution of the equation system, similar to the !Matlab/Octave backslash operator (which our documentation already claims is implemented). This is implemented using scipy.linalg.lstsq.CC: @orlitzky
Component: linear algebra
Author: Markus Wageringel
Branch/Commit:
93cea85
Reviewer: Michael Orlitzky
Issue created by migration from https://trac.sagemath.org/ticket/12406
The text was updated successfully, but these errors were encountered: