Skip to content

Commit 7f848ff

Browse files
committed
Workaround for linbox charpoly/minpoly issues
1 parent 28b7af0 commit 7f848ff

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

src/sage/matrix/matrix_integer_dense.pyx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,10 +1411,13 @@ cdef class Matrix_integer_dense(Matrix_dense):
14111411
fmpz_mat_charpoly(g._poly, self._matrix)
14121412
sig_off()
14131413
elif algorithm == 'linbox':
1414-
g = (<Polynomial_integer_dense_flint> PolynomialRing(ZZ, names=var).gen())._new()
1415-
sig_on()
1416-
linbox_fmpz_mat_charpoly(g._poly, self._matrix)
1417-
sig_off()
1414+
while True:
1415+
g = (<Polynomial_integer_dense_flint> PolynomialRing(ZZ, names=var).gen())._new()
1416+
sig_on()
1417+
linbox_fmpz_mat_charpoly(g._poly, self._matrix)
1418+
sig_off()
1419+
if g.lc() == 1: # linbox is unreliable, see :issue:`37068`
1420+
break
14181421
elif algorithm == 'generic':
14191422
g = Matrix_dense.charpoly(self, var)
14201423
else:
@@ -1494,10 +1497,13 @@ cdef class Matrix_integer_dense(Matrix_dense):
14941497
return g.change_variable_name(var)
14951498

14961499
if algorithm == 'linbox':
1497-
g = (<Polynomial_integer_dense_flint> PolynomialRing(ZZ, names=var).gen())._new()
1498-
sig_on()
1499-
linbox_fmpz_mat_minpoly(g._poly, self._matrix)
1500-
sig_off()
1500+
while True:
1501+
g = (<Polynomial_integer_dense_flint> PolynomialRing(ZZ, names=var).gen())._new()
1502+
sig_on()
1503+
linbox_fmpz_mat_minpoly(g._poly, self._matrix)
1504+
sig_off()
1505+
if g.lc() == 1: # linbox is unreliable, see :issue:`37068`
1506+
break
15011507
elif algorithm == 'generic':
15021508
g = Matrix_dense.minpoly(self, var)
15031509
else:

src/sage/matrix/matrix_integer_sparse.pyx

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -901,16 +901,19 @@ cdef class Matrix_integer_sparse(Matrix_sparse):
901901
cdef linbox.DensePolynomial_integer * p = new linbox.DensePolynomial_integer(givZZ, <size_t> self._nrows)
902902
cdef Polynomial_integer_dense_flint g = (<Polynomial_integer_dense_flint> R.gen())._new()
903903

904-
sig_on()
905-
linbox.charpoly(p[0], M[0])
906-
sig_off()
904+
while True:
905+
sig_on()
906+
linbox.charpoly(p[0], M[0])
907+
sig_off()
907908

908-
cdef size_t i
909-
fmpz_poly_fit_length(g._poly, p.size())
910-
for i in range(p.size()):
911-
tmp = p[0][i].get_mpz_const()
912-
fmpz_poly_set_coeff_mpz(g._poly, i, tmp)
913-
_fmpz_poly_set_length(g._poly, p.size())
909+
fmpz_poly_fit_length(g._poly, p.size())
910+
for i in range(p.size()):
911+
tmp = p[0][i].get_mpz_const()
912+
fmpz_poly_set_coeff_mpz(g._poly, i, tmp)
913+
_fmpz_poly_set_length(g._poly, p.size())
914+
915+
if g.lc() == 1: # linbox is unreliable, see :issue:`37068`
916+
break
914917

915918
del M
916919
del p
@@ -1000,18 +1003,21 @@ cdef class Matrix_integer_sparse(Matrix_sparse):
10001003
cdef linbox.SparseMatrix_integer * M = new_linbox_matrix_integer_sparse(givZZ, self)
10011004
cdef linbox.DensePolynomial_integer * p = new linbox.DensePolynomial_integer(givZZ, <size_t> self._nrows)
10021005
cdef Polynomial_integer_dense_flint g = (<Polynomial_integer_dense_flint> R.gen())._new()
1006+
cdef mpz_t tmp
10031007

1004-
sig_on()
1005-
linbox.minpoly(p[0], M[0])
1006-
sig_off()
1008+
while True:
1009+
sig_on()
1010+
linbox.minpoly(p[0], M[0])
1011+
sig_off()
10071012

1008-
cdef size_t i
1009-
cdef mpz_t tmp
1010-
fmpz_poly_fit_length(g._poly, p.size())
1011-
for i in range(p.size()):
1012-
tmp = p[0][i].get_mpz_const()
1013-
fmpz_poly_set_coeff_mpz(g._poly, i, tmp)
1014-
_fmpz_poly_set_length(g._poly, p.size())
1013+
fmpz_poly_fit_length(g._poly, p.size())
1014+
for i in range(p.size()):
1015+
tmp = p[0][i].get_mpz_const()
1016+
fmpz_poly_set_coeff_mpz(g._poly, i, tmp)
1017+
_fmpz_poly_set_length(g._poly, p.size())
1018+
1019+
if g.lc() == 1: # linbox is unreliable, see :issue:`37068`
1020+
break
10151021

10161022
del M
10171023
del p

0 commit comments

Comments
 (0)