Skip to content

Commit c71f7c9

Browse files
committed
Avoid hermite_form in solve_right if possible
1 parent 9352a32 commit c71f7c9

File tree

1 file changed

+44
-6
lines changed

1 file changed

+44
-6
lines changed

src/sage/matrix/matrix2.pyx

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,33 @@ cdef class Matrix(Matrix1):
878878
sage: v = vector(GF(3), [1,1])
879879
sage: m.solve_right(v)
880880
(2, 1)
881+
882+
Test ``extend``::
883+
884+
sage: matrix(ZZ, [[2]]).solve_right(vector(ZZ, [1]), extend=False)
885+
Traceback (most recent call last):
886+
...
887+
ValueError: matrix equation has no solutions
888+
sage: matrix(ZZ, [[2], [2]]).solve_right(vector(ZZ, [1, 1]), extend=False)
889+
Traceback (most recent call last):
890+
...
891+
ValueError: matrix equation has no solutions
892+
sage: matrix(ZZ, [[2], [2]]).solve_right(vector(ZZ, [2, 4]), extend=False)
893+
Traceback (most recent call last):
894+
...
895+
ValueError: matrix equation has no solutions
896+
sage: matrix(ZZ, [[2], [2]]).solve_right(vector(ZZ, [2, 2]), extend=False)
897+
(1)
898+
sage: matrix(QQ, [[2]]).solve_right(vector(QQ, [1]), extend=False)
899+
(1/2)
900+
sage: v = matrix.identity(QQ, 500).solve_right(vector(QQ, [1]*500), extend=True) # <1s
901+
sage: v = matrix.identity(QQ, 500).solve_right(vector(QQ, [1]*500), extend=False) # <1s
902+
sage: matrix.identity(QQ, 500).hermite_form() # not tested (slow)
903+
sage: v = (matrix.identity(ZZ, 500)*2).solve_right(vector(ZZ, [2]*500), extend=False) # <1s
904+
sage: matrix.identity(ZZ, 500).hermite_form() # not tested (slow)
905+
sage: m = matrix.identity(ZZ, 250).stack(matrix.identity(ZZ, 250))*2
906+
sage: v = m.solve_right(vector(ZZ, [2]*500), extend=False) # <1s
907+
sage: m._solve_right_hermite_form(matrix(ZZ, [[2]]*500)) # not tested (slow)
881908
"""
882909
try:
883910
L = B.base_ring()
@@ -944,11 +971,22 @@ cdef class Matrix(Matrix1):
944971

945972
C = B.column() if b_is_vec else B
946973

947-
if not extend:
948-
try:
949-
X = self._solve_right_hermite_form(C)
950-
except NotImplementedError:
951-
X = self._solve_right_smith_form(C)
974+
if P not in _Fields and not extend:
975+
if self.rank() == self.ncols():
976+
# hermite_form is slow, avoid if possible
977+
if self.is_square():
978+
X = self._solve_right_nonsingular_square(C, check_rank=False)
979+
else:
980+
X = self._solve_right_general(C)
981+
try:
982+
X = X.change_ring(P)
983+
except TypeError:
984+
raise ValueError('matrix equation has no solutions')
985+
else:
986+
try:
987+
X = self._solve_right_hermite_form(C)
988+
except NotImplementedError:
989+
X = self._solve_right_smith_form(C)
952990
return X.column(0) if b_is_vec else X
953991

954992
if not self.is_square():
@@ -1199,7 +1237,7 @@ cdef class Matrix(Matrix1):
11991237
try:
12001238
X_[i] = v / d
12011239
except (ZeroDivisionError, TypeError) as e:
1202-
raise ValueError("matrix equation has no solution")
1240+
raise ValueError("matrix equation has no solutions")
12031241
# assert H*X_ == B
12041242

12051243
return U * X_

0 commit comments

Comments
 (0)