-def is_symmetric_pd(A):
- """
- Determine whether or not the matrix ``A`` is symmetric
- positive-definite.
-
- INPUT:
-
- - ``A`` - The matrix in question.
-
- OUTPUT:
-
- Either ``True`` if ``A`` is symmetric positive-definite, or
- ``False`` otherwise.
-
- SETUP::
-
- sage: from mjo.cone.symmetric_pd import (is_symmetric_pd,
- ....: random_symmetric_pd)
-
- EXAMPLES:
-
- The identity matrix is obviously symmetric and positive-definite::
-
- sage: set_random_seed()
- sage: A = identity_matrix(ZZ, ZZ.random_element(10))
- sage: is_symmetric_pd(A)
- True
-
- The following matrix is symmetric but not positive definite::
-
- sage: A = matrix(ZZ, [[1, 2], [2, 1]])
- sage: is_symmetric_pd(A)
- False
-
- This matrix isn't even symmetric::
-
- sage: A = matrix(ZZ, [[1, 2], [3, 4]])
- sage: is_symmetric_pd(A)
- False
-
- The trivial matrix in a trivial space is trivially symmetric and
- positive-definite::
-
- sage: A = matrix(QQ, 0,0)
- sage: is_symmetric_pd(A)
- True
-
- The implementation of "is_positive_definite" in Sage leaves a bit to
- be desired. This matrix is technically positive definite over the
- real numbers, but isn't symmetric::
-
- sage: A = matrix(RR,[[1,1],[-1,1]])
- sage: A.is_positive_definite()
- Traceback (most recent call last):
- ...
- ValueError: Could not see Real Field with 53 bits of precision as a
- subring of the real or complex numbers
- sage: is_symmetric_pd(A)
- False
-
- TESTS:
-
- Every gram matrix is positive-definite, and we can sum two
- positive-definite matrices (``A`` and its transpose) to get a new
- positive-definite matrix that happens to be symmetric::
-
- sage: set_random_seed()
- sage: V = VectorSpace(QQ, ZZ.random_element(5))
- sage: A = random_symmetric_pd(V)
- sage: is_symmetric_pd(A)
- True
-
- """
-
- if A.base_ring() == SR:
- msg = 'The matrix ``A`` cannot be symbolic.'
- raise ValueError.new(msg)
-
- # First make sure that ``A`` is symmetric.
- if not A.is_symmetric():
- return False
-
- # If ``A`` is symmetric, we only need to check that it is positive
- # definite. For that we can consult its minimum eigenvalue, which
- # should be greater than zero. Since ``A`` is symmetric, its
- # eigenvalues are guaranteed to be real.
- if A.is_zero():
- # A is trivial... so trivially positive-definite.
- return True
- else:
- return min(A.eigenvalues()) > 0
-
-