X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Fdunshire%2Fcones.py;h=61feab453bd0866b54c053d2871d722a63ec3730;hb=23a5893ede3a22653128d3e7a66fb3f6b80616b8;hp=d7c9b62e02314e1b637a3c1caf00f1d68612b050;hpb=4f0bc24d81ecbce9b2220d042b407529917ef5c6;p=dunshire.git diff --git a/src/dunshire/cones.py b/src/dunshire/cones.py index d7c9b62..61feab4 100644 --- a/src/dunshire/cones.py +++ b/src/dunshire/cones.py @@ -134,12 +134,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 +172,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 +197,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 +230,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 +262,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 +298,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 +346,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 +384,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 +443,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 +525,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 +550,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())])