Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Trac #33159: add special case to solve_right() for symbolic systems.
Browse files Browse the repository at this point in the history
Elements of SR remember whether or not they are exact, and if we are
given a system consisting entirely of exact elements, then the checks
for correctness in solve_left() and solve_right() need not be skipped
as they are for other inexact rings. This commit adds a special case
to the solve_right() method for matrices to handle SR with care, and
includes an additional test case from Trac 29729. Since solve_left()
is implemented in terms of solve_right(), both are addressed.
  • Loading branch information
orlitzky committed Jan 13, 2022
1 parent 3da1b22 commit 4d094d6
Showing 1 changed file with 53 additions and 10 deletions.
63 changes: 53 additions & 10 deletions src/sage/matrix/matrix2.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ cdef class Matrix(Matrix1):

- ``check`` -- boolean (default: ``True``); verify the answer
if the system is non-square or rank-deficient, and if its
entries lie in an exact ring. Meaningless over inexact rings,
or when the system is square and of full rank.
entries lie in an exact ring. Meaningless over most inexact
rings, or when the system is square and of full rank.

OUTPUT:

Expand All @@ -239,12 +239,13 @@ cdef class Matrix(Matrix1):
If the system is not square or does not have full rank, then a
solution is attempted via other means. For example, over
``RDF`` or ``CDF`` a least-squares solution is returned, as
with MATLAB's "backslash" operator. For inexact rings, the
with MATLAB's "backslash" operator. For most inexact rings, the
``check`` parameter is ignored because an approximate solution
will be returned in any case. Over exact rings, on the other
hand, setting the ``check`` parameter results in an additional
test to determine whether or not the answer actually solves the
system exactly.
system exactly. If a symbolic system involves only exact elements,
its solution can still be checked.

If `B` is a vector, the result is returned as a vector, as well,
and as a matrix, otherwise.
Expand Down Expand Up @@ -395,6 +396,21 @@ cdef class Matrix(Matrix1):
(0.5 - 1.5*I, 0.5 + 0.5*I)
sage: b = vector(QQ[I], [1+I, 2])
sage: x = A.solve_left(b)

Over the inexact ring ``SR``, we can still verify the solution
if all of the elements involved were exact to begin with; if
any are inexact, however, the ``check`` is still skipped
(:trac:`29729` and :trac:`33159`)::

sage: A = matrix(SR, [[1, 1]])
sage: b = vector(SR, [2, 3])
sage: A.solve_left(b)
Traceback (most recent call last):
...
ValueError: matrix equation has no solutions
sage: A.solve_left(b, check=False)
(2)

"""
if is_Vector(B):
try:
Expand Down Expand Up @@ -433,8 +449,8 @@ cdef class Matrix(Matrix1):

- ``check`` -- boolean (default: ``True``); verify the answer
if the system is non-square or rank-deficient, and if its
entries lie in an exact ring. Meaningless over inexact rings,
or when the system is square and of full rank.
entries lie in an exact ring. Meaningless over most inexact
rings, or when the system is square and of full rank.

OUTPUT:

Expand All @@ -448,12 +464,13 @@ cdef class Matrix(Matrix1):
If the system is not square or does not have full rank, then a
solution is attempted via other means. For example, over
``RDF`` or ``CDF`` a least-squares solution is returned, as
with MATLAB's "backslash" operator. For inexact rings, the
with MATLAB's "backslash" operator. For most inexact rings, the
``check`` parameter is ignored because an approximate solution
will be returned in any case. Over exact rings, on the other
hand, setting the ``check`` parameter results in an additional
test to determine whether or not the answer actually solves the
system exactly.
system exactly. If a symbolic system involves only exact elements,
its solution can still be checked.

If `B` is a vector, the result is returned as a vector, as well,
and as a matrix, otherwise.
Expand Down Expand Up @@ -780,6 +797,23 @@ cdef class Matrix(Matrix1):
sage: A = matrix(RF, [[0.24, 1, 0], [1, 0, 0]])
sage: 0 < (A * A.solve_right(B) - B).norm() < 1e-14
True

Over the inexact ring ``SR``, we can still verify the solution
if all of the elements involved were exact to begin with; if
any are inexact, however, the ``check`` is still skipped
(:trac:`29729` and :trac:`33159`)::

sage: m = matrix(SR, [0])
sage: b = vector(SR, [1])
sage: m.solve_right(b, check=True)
Traceback (most recent call last):
...
ValueError: matrix equation has no solutions
sage: m.solve_right(b, check=False)
(0)
sage: m = matrix(SR, [0.0])
sage: m.solve_right(b, check=True)
(0)
"""
try:
L = B.base_ring()
Expand Down Expand Up @@ -812,8 +846,17 @@ cdef class Matrix(Matrix1):
K = P
self = self.change_ring(P)

# If our field is inexact, checking the answer is doomed anyway.
check = (check and K.is_exact())
# If our field is inexact, checking the answer is doomed in
# most cases. But here we handle the special ones.
from sage.symbolic.ring import SR
if K is SR:
# Elements of SR "remember" whether or not they are exact.
# If every element in the system is exact, we can probably
# still check the solution over the inexact ring SR.
check = (check and all( e.is_exact()
for e in self.list() + B.list() ))
else:
check = (check and K.is_exact())

if not K.is_integral_domain():
# The non-integral-domain case is handled almost entirely
Expand Down

0 comments on commit 4d094d6

Please sign in to comment.