From 3076563f6dc460b219cc3b27f8538d427b297604 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 30 Oct 2014 08:36:49 -0400 Subject: [PATCH] New module: cone.doubly_nonnegative. --- mjo/cone/doubly_nonnegative.py | 81 ++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 mjo/cone/doubly_nonnegative.py diff --git a/mjo/cone/doubly_nonnegative.py b/mjo/cone/doubly_nonnegative.py new file mode 100644 index 0000000..b071e41 --- /dev/null +++ b/mjo/cone/doubly_nonnegative.py @@ -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() -- 2.43.2