Repository: sympy/sympy

Issue:
is_positive_semidefinite() gives wrong result on sympy==1.6
The code
```
from sympy import Matrix
A = Matrix([[0,0,0],[0,1,2],[0,2,1]])
A.is_positive_semidefinite
```
gives a wrong result `True` for sympy version 1.6. The result is `False` for version 1.5.1.
The reason for this is because the following function introduced in #19205 only checks the leading diagonal minors, thus failing to check det([[1, 2],[2,1]]) < 0.
https://github.com/sympy/sympy/blob/bfd2fa05de2db76a73c16e5c94604cdfd9d74e60/sympy/matrices/eigen.py#L744-L753

Discussion:

Patch:
diff --git a/sympy/matrices/eigen.py b/sympy/matrices/eigen.py
index 359009f5d7..48b9317b60 100644
--- a/sympy/matrices/eigen.py
+++ b/sympy/matrices/eigen.py
@@ -1,5 +1,6 @@
 from types import FunctionType
 from collections import Counter
+import itertools
 
 from mpmath import mp, workprec
 from mpmath.libmp.libmpf import prec_to_dps
@@ -699,7 +700,7 @@ def _is_positive_semidefinite(M):
     if nonnegative_diagonals and M.is_weakly_diagonally_dominant:
         return True
 
-    return _is_positive_semidefinite_minors(M)
+    return _is_positive_semidefinite_by_minors(M)
 
 
 def _is_negative_definite(M):
@@ -741,16 +742,14 @@ def _is_positive_definite_GE(M):
     return True
 
 
-def _is_positive_semidefinite_minors(M):
+def _is_positive_semidefinite_by_minors(M):
     """A method to evaluate all principal minors for testing
-    positive-semidefiniteness."""
-    size = M.rows
-    for i in range(size):
-        minor = M[:i+1, :i+1].det(method='berkowitz')
-        is_nonnegative = minor.is_nonnegative
-        if is_nonnegative is not True:
-            return is_nonnegative
-    return True
+    positive-semidefiniteness by using Sylvestre's crieterion."""
+    return all(
+        M[idx, idx].det(method='berkowitz').is_nonnegative
+        for minor_size in range(1, M.rows+1)
+        for idx in itertools.combinations(range(M.rows), minor_size)
+    )
 
 
 _doc_positive_definite = \


Test patch:
diff --git a/sympy/matrices/tests/test_eigen.py b/sympy/matrices/tests/test_eigen.py
index 26d82163d9..5feaa5a733 100644
--- a/sympy/matrices/tests/test_eigen.py
+++ b/sympy/matrices/tests/test_eigen.py
@@ -572,3 +572,12 @@ def test_definite():
     assert m.is_positive_definite == True
     assert m.is_positive_semidefinite == True
     assert m.is_indefinite == False
+
+    # test for issue 19547: https://github.com/sympy/sympy/issues/19547
+    m = Matrix([
+        [0, 0, 0],
+        [0, 1, 2],
+        [0, 2, 1]
+    ])
+    assert not m.is_positive_definite
+    assert not m.is_positive_semidefinite