]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
New module: cone.doubly_nonnegative.
authorMichael Orlitzky <michael@orlitzky.com>
Thu, 30 Oct 2014 12:36:49 +0000 (08:36 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Thu, 30 Oct 2014 12:36:49 +0000 (08:36 -0400)
mjo/cone/doubly_nonnegative.py [new file with mode: 0644]

diff --git a/mjo/cone/doubly_nonnegative.py b/mjo/cone/doubly_nonnegative.py
new file mode 100644 (file)
index 0000000..b071e41
--- /dev/null
@@ -0,0 +1,81 @@
+"""
+The doubly-nonnegative cone in `S^{n}` is the set of all such matrices
+that both,
+
+  a) are positive semidefinite
+
+  b) have only nonnegative entries
+
+It is represented typically by either `\mathcal{D}^{n}` or
+`\mathcal{DNN}`.
+
+"""
+
+from sage.all import *
+
+# Sage doesn't load ~/.sage/init.sage during testing (sage -t), so we
+# have to explicitly mangle our sitedir here so that "mjo.cone"
+# resolves.
+from os.path import abspath
+from site import addsitedir
+addsitedir(abspath('../../'))
+from mjo.cone.symmetric_psd import factor_psd
+
+
+
+def is_doubly_nonnegative(A):
+    """
+    Determine whether or not the matrix ``A`` is doubly-nonnegative.
+
+    INPUT:
+
+      - ``A`` - The matrix in question
+
+    OUTPUT:
+
+    Either ``True`` if ``A`` is doubly-nonnegative, or ``False``
+    otherwise.
+
+    EXAMPLES:
+
+    Every completely positive matrix is doubly-nonnegative::
+
+        sage: v = vector(map(abs, random_vector(ZZ, 10)))
+        sage: A = v.column() * v.row()
+        sage: is_doubly_nonnegative(A)
+        True
+
+    The following matrix is nonnegative but non positive semidefinite::
+
+        sage: A = matrix(ZZ, [[1, 2], [2, 1]])
+        sage: is_doubly_nonnegative(A)
+        False
+
+    """
+
+    if A.base_ring() == SR:
+        msg = 'The base ring of ``A`` cannot be the Symbolic Ring'
+        raise ValueError.new(msg)
+
+    # First make sure that ``A`` is symmetric.
+    if not A.is_symmetric():
+        return False
+
+    # Check that all of the entries of ``A`` are nonnegative.
+    if not all([ a >= 0 for a in A.list() ]):
+        return False
+
+    # If ``A`` is symmetric and non-negative, we only need to check
+    # that it is positive semidefinite. For that we can consult its
+    # minimum eigenvalue, which should be zero or greater. Since ``A``
+    # is symmetric, its eigenvalues are guaranteed to be real.
+    return min(A.eigenvalues()) >= 0
+
+
+
+def is_extreme_doubly_nonnegative(A):
+    """
+    Returns ``True`` if the given matrix is an extreme matrix of the
+    doubly-nonnegative cone, and ``False`` otherwise.
+    """
+    raise NotImplementedError()