Our documentation for Matrix.solve_right is schizophrenic, and it's
contagious. I'm trying to review #12406 that fixes some old issues with
the solution of linear systems. The problem I have is that solve_right()
doesn't know what it's supposed to do. The documentation says,
If self is a matrix A, then this function returns a vector or matrix X
such that AX=B. If B is a vector then X is a vector and if B is a
matrix, then X is a matrix.
Note: In Sage one can also write A \ B for A.solve_right(B), i.e.,
Sage implements the "the MATLAB/Octave backslash operator.
Those two statements are already at odds, because that's not what the
MATLAB backslash operator does:
https://www.mathworks.com/help/matlab/ref/mldivide.html
At the most basic level, the backslash operator has two cases for square
and non-square matrices:
* non-square gets an approximate solution
* square assumes non-singularity and throws an error otherwise
The docs for solve_right continue...
INPUT:
...
check - bool (default: True) - if False and self is nonsquare, may
not raise an error message even if there is no solution. This is
faster but more dangerous.
Which again, doesn't quite make sense in the context of an approximate
solution, or indeed *any* solution over an inexact ring, where the
answer will be approximate.
Several of these unusual behaviors are doctested, for example in the
tour of linear algebra,
http://doc.sagemath.org/html/en/tutorial/tour_linalg.html
where the very first example expects a solution from a singular square
system:
sage: A = Matrix([[1,2,3],[3,2,1],[1,1,1]])
sage: Y = vector([0, -4, -1])
sage: A.is_square()
True
sage: A.is_singular()
True
sage: A.solve_right(Y)
(-2, 1, 0)
That creates a sticky situation: to fix solve_right() over RDF or other
inexact rings, we basically have to add a _another_ special case that
ignores the documentation for solve_right(), and that doesn't quite
agree with what happens in exact rings.
Do tl;dr, what should solve_right() actually do? Is there a consistent
description of it that works for both exact and inexact rings? Should it
act like the backslash operator, or should we stop saying that we
implement the backslash operator?
The change that requires the least change would be to document that
non-square systems get approximate solutions, and to do away with the
"check" parameter entirely. Or maybe document that "check" only works
over exact rings, and to set it to False at the top of solve_right when
the ring is exact. Then we can tweak the implementation to work like the
MATLAB operator, by e.g. making it an error to solve a singular square
system. But as I mentioned, that breaks some doctests...
We could also just stop saying that we implement the backslash operator,
and put the approximate solvers in different methods. That's probably
cleaner and simpler, but it too will break a lot of stuff. I'm sure
there are dead-tree books out there that use the "\" exclusively.