Skip to content

Commit

Permalink
12406: add NotFullRankError for _solve_right_nonsingular_square
Browse files Browse the repository at this point in the history
  • Loading branch information
mwageringel committed Mar 30, 2020
1 parent 99c2a7e commit c1178d9
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 9 deletions.
21 changes: 15 additions & 6 deletions src/sage/matrix/matrix2.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -834,11 +834,8 @@ cdef class Matrix(Matrix1):
else:
try:
X = self._solve_right_nonsingular_square(C, check_rank=True)
except ValueError as e:
if 'not of full rank' in str(e):
X = self._solve_right_general(C, check=check)
else:
raise e
except NotFullRankError:
X = self._solve_right_general(C, check=check)

if b_is_vec:
# Convert back to a vector
Expand Down Expand Up @@ -882,7 +879,7 @@ cdef class Matrix(Matrix1):
# this could probably be optimized so that the rank computation is
# avoided
if check_rank and self.rank() < self.nrows():
raise ValueError("not of full rank")
raise NotFullRankError
D = self.augment(B)
D.echelonize()
return D.matrix_from_columns(range(self.ncols(),D.ncols()))
Expand Down Expand Up @@ -16469,3 +16466,15 @@ def _matrix_power_symbolic(A, n):
Pinv = ~P

return P * M * Pinv

class NotFullRankError(ValueError):
"""
An error that indicates that a matrix is not of full rank.

The fact that a square system is rank-deficient sometimes only becomes
apparent while attempting to solve it. The methods
:meth:`.Matrix.solve_left` and :meth:`.Matrix.solve_right` defer to
:meth:`.Matrix._solve_right_nonsingular_square` for square systems, and
that method raises this error if the system turns out to be singular.
"""
pass
3 changes: 2 additions & 1 deletion src/sage/matrix/matrix_integer_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -4255,7 +4255,8 @@ cdef class Matrix_integer_dense(Matrix_dense):
# in the non-full rank case. In any case, we do this for now,
# since rank is very fast and infinite loops are evil.
if check_rank and self.rank() < self.nrows():
raise ValueError("not of full rank")
from .matrix2 import NotFullRankError
raise NotFullRankError

if not self.is_square():
raise NotImplementedError("the input matrix must be square.")
Expand Down
3 changes: 2 additions & 1 deletion src/sage/matrix/matrix_integer_sparse.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,8 @@ cdef class Matrix_integer_sparse(Matrix_sparse):
[0 2]
"""
if check_rank and self.rank() < self.nrows():
raise ValueError("not of full rank")
from .matrix2 import NotFullRankError
raise NotFullRankError

if self.base_ring() != B.base_ring():
B = B.change_ring(self.base_ring())
Expand Down
3 changes: 2 additions & 1 deletion src/sage/matrix/matrix_modn_sparse.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,8 @@ cdef class Matrix_modn_sparse(matrix_sparse.Matrix_sparse):
[0 2]
"""
if check_rank and self.rank() < self.nrows():
raise ValueError("not of full rank")
from .matrix2 import NotFullRankError
raise NotFullRankError

if self.base_ring() != B.base_ring():
B = B.change_ring(self.base_ring())
Expand Down

0 comments on commit c1178d9

Please sign in to comment.