X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fdunshire%2Fcones.py;h=7fc8bf94993e4df86b2f57c2e6b6d6aefa65d8c4;hb=08abee864006192c364c25f22c3755e89e310b9b;hp=d7c9b62e02314e1b637a3c1caf00f1d68612b050;hpb=4f0bc24d81ecbce9b2220d042b407529917ef5c6;p=dunshire.git diff --git a/src/dunshire/cones.py b/src/dunshire/cones.py index d7c9b62..7fc8bf9 100644 --- a/src/dunshire/cones.py +++ b/src/dunshire/cones.py @@ -4,8 +4,9 @@ Class definitions for all of the symmetric cones (and their superclass, """ from cvxopt import matrix -from matrices import eigenvalues, norm -import options + +from .matrices import eigenvalues, norm +from . import options class SymmetricCone: """ @@ -134,12 +135,6 @@ class NonnegativeOrthant(SymmetricCone): distinguish between strict and non-strict containment -- the test uses a tolerance parameter. - This test will err on the side of caution, and return ``True`` - only when the ``point`` lies inside this cone *past* the - tolerance guarantee. That means if you ask whether or not a - boundary point lies in this cone, you will get ``False`` as your - answer. - Parameters ---------- @@ -178,10 +173,10 @@ class NonnegativeOrthant(SymmetricCone): >>> matrix([1,-0.1,3]) in K False - However, not even a boundary point is considered inside of ``K``: + A boundary point is considered inside of ``K``: >>> K = NonnegativeOrthant(3) >>> matrix([1,0,3]) in K - False + True Junk arguments don't work: @@ -203,7 +198,7 @@ class NonnegativeOrthant(SymmetricCone): if not point.size == (self.dimension(), 1): raise TypeError('the given point has the wrong dimensions') - return all([x > options.ABS_TOL for x in point]) + return all([x > -options.ABS_TOL for x in point]) @@ -236,12 +231,6 @@ class IceCream(SymmetricCone): distinguish between strict and non-strict containment -- the test uses a tolerance parameter. - This test will err on the side of caution, and return ``True`` - only when the ``point`` lies inside this cone *past* the - tolerance guarantee. That means if you ask whether or not a - boundary point lies in this cone, you will get ``False`` as your - answer. - Parameters ---------- @@ -274,11 +263,11 @@ class IceCream(SymmetricCone): >>> matrix([1,0.5,0.5]) in K True - But this one lies on its boundary and runs foul of the tolerance: + This one lies on its boundary: >>> K = IceCream(3) >>> matrix([1,0,1]) in K - False + True This point lies entirely outside of the ice cream cone: @@ -310,10 +299,10 @@ class IceCream(SymmetricCone): if self.dimension() == 1: # In one dimension, the ice cream cone is the nonnegative # orthant. - return height > options.ABS_TOL + return height > -options.ABS_TOL else: radius = point[1:] - return norm(radius) < (height - options.ABS_TOL) + return norm(radius) < (height + options.ABS_TOL) @@ -358,12 +347,6 @@ class SymmetricPSD(SymmetricCone): distinguish between strict and non-strict containment -- the test uses a tolerance parameter. - This test will err on the side of caution, and return ``True`` - only when the ``point`` lies inside this cone *past* the - tolerance guarantee. That means if you ask whether or not a - boundary point lies in this cone, you will get ``False`` as your - answer. - Parameters ---------- @@ -402,28 +385,43 @@ class SymmetricPSD(SymmetricCone): >>> K = SymmetricPSD(5) >>> A = matrix([[5,4,3,2,1], - ... [4,5,4,3,2], - ... [3,4,5,4,3], - ... [2,3,4,5,4], - ... [1,2,3,4,5]]) + ... [4,5,4,3,2], + ... [3,4,5,4,3], + ... [2,3,4,5,4], + ... [1,2,3,4,5]]) >>> A in K True - But any matrix with a zero eigenvalue will lie on the boundary - of the Symmetric PSD cone and run foul of our tolerance: + Boundary points lie in the cone as well: >>> K = SymmetricPSD(2) >>> matrix([[0,0],[0,0]]) in K - False + True >>> K = SymmetricPSD(5) >>> A = matrix([[1,0,0,0,0], - ... [0,1,0,0,0], - ... [0,0,0,0,0], - ... [0,0,0,1,0], - ... [0,0,0,0,1]]) + ... [0,1,0,0,0], + ... [0,0,0,0,0], + ... [0,0,0,1,0], + ... [0,0,0,0,1]]) >>> A in K - False + True + + However, this matrix has a negative eigenvalue: + + >>> K = SymmetricPSD(2) + >>> A = matrix([[ 1, -2], + ... [-2, 1]]) + >>> A in K + False + + An asymmetric cone with positive eigenvalues is not in the cone: + + >>> K = SymmetricPSD(2) + >>> A = matrix([[10, 2], + ... [4, 8]]) + >>> A in K + False Junk arguments don't work: @@ -446,7 +444,10 @@ class SymmetricPSD(SymmetricCone): raise TypeError('the given point has the wrong dimensions') if not point.typecode == 'd': point = matrix(point, (self.dimension(), self.dimension()), 'd') - return all([e > options.ABS_TOL for e in eigenvalues(point)]) + if not norm(point - point.trans()) < options.ABS_TOL: + # It's not symmetric. + return False + return all([e > -options.ABS_TOL for e in eigenvalues(point)]) @@ -525,7 +526,7 @@ class CartesianProduct(SymmetricCone): >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3)) >>> (matrix([0,0,0]), matrix([1,0,1])) in K - False + True >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3)) >>> (matrix([1,1,1]), matrix([1,1,1])) in K @@ -550,7 +551,7 @@ class CartesianProduct(SymmetricCone): TypeError: the given point has the wrong dimensions """ - return all([p in f for (p,f) in zip(point, self.factors())]) + return all([p in f for (p, f) in zip(point, self.factors())])