]>
gitweb.michael.orlitzky.com - dunshire.git/blob - src/dunshire/cones.py
b1e07e9d6c607c823334aecb74ea774cb073bf35
2 Class definitions for all of the symmetric cones (and their superclass,
3 SymmetricCone) supported by CVXOPT.
6 from cvxopt
import matrix
7 from matrices
import eigenvalues
, norm
11 An instance of a symmetric (self-dual and homogeneous) cone.
13 There are three types of symmetric cones supported by CVXOPT:
15 1. The nonnegative orthant in the real n-space.
16 2. The Lorentz "ice cream" cone, or the second-order cone.
17 3. The cone of symmetric positive-semidefinite matrices.
19 This class is intended to encompass them all.
21 def __init__(self
, dimension
):
23 A generic constructor for symmetric cones.
25 When constructing a single symmetric cone (i.e. not a cartesian
26 product of them), the only information that we need is its
27 dimension. We take that dimension as a parameter, and store it
32 - ``dimension`` -- the dimension of this cone.
36 raise ValueError('cones must have dimension greater than zero')
38 self
._dimension
= dimension
41 def __contains__(self
, point
):
43 Return whether or not ``point`` belongs to this cone.
47 >>> K = SymmetricCone(5)
48 >>> matrix([1,2]) in K
49 Traceback (most recent call last):
54 raise NotImplementedError
56 def contains_strict(self
, point
):
58 Return whether or not ``point`` belongs to the interior
63 >>> K = SymmetricCone(5)
64 >>> K.contains_strict(matrix([1,2]))
65 Traceback (most recent call last):
69 raise NotImplementedError
73 Return the dimension of this symmetric cone.
75 The dimension of this symmetric cone is recorded during its
76 creation. This method simply returns the recorded value, and
77 should not need to be overridden in subclasses. We prefer to do
78 any special computation in ``__init__()`` and record the result
79 in ``self._dimension``.
83 >>> K = SymmetricCone(5)
88 return self
._dimension
91 class NonnegativeOrthant(SymmetricCone
):
93 The nonnegative orthant in ``n`` dimensions.
97 >>> K = NonnegativeOrthant(3)
99 Nonnegative orthant in the real 3-space
104 Output a human-readable description of myself.
106 tpl
= 'Nonnegative orthant in the real {:d}-space'
107 return tpl
.format(self
.dimension())
109 def __contains__(self
, point
):
111 Return whether or not ``point`` belongs to this cone.
115 An instance of the ``cvxopt.base.matrix`` class having
116 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
120 >>> K = NonnegativeOrthant(3)
121 >>> matrix([1,2,3]) in K
124 >>> K = NonnegativeOrthant(3)
125 >>> matrix([1,-0.1,3]) in K
128 >>> K = NonnegativeOrthant(3)
130 Traceback (most recent call last):
132 TypeError: the given point is not a cvxopt.base.matrix
134 >>> K = NonnegativeOrthant(3)
135 >>> matrix([1,2]) in K
136 Traceback (most recent call last):
138 TypeError: the given point has the wrong dimensions
141 if not isinstance(point
, matrix
):
142 raise TypeError('the given point is not a cvxopt.base.matrix')
143 if not point
.size
== (self
.dimension(), 1):
144 raise TypeError('the given point has the wrong dimensions')
146 return all([x
>= 0 for x
in point
])
149 def contains_strict(self
, point
):
151 Return whether or not ``point`` belongs to the interior of this
156 An instance of the ``cvxopt.base.matrix`` class having
157 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
161 >>> K = NonnegativeOrthant(3)
162 >>> K.contains_strict(matrix([1,2,3]))
165 >>> K = NonnegativeOrthant(3)
166 >>> K.contains_strict(matrix([1,0,1]))
169 >>> K = NonnegativeOrthant(3)
170 >>> K.contains_strict(matrix([1,-0.1,3]))
173 >>> K = NonnegativeOrthant(3)
174 >>> K.contains_strict([1,2,3])
175 Traceback (most recent call last):
177 TypeError: the given point is not a cvxopt.base.matrix
179 >>> K = NonnegativeOrthant(3)
180 >>> K.contains_strict(matrix([1,2]))
181 Traceback (most recent call last):
183 TypeError: the given point has the wrong dimensions
186 if not isinstance(point
, matrix
):
187 raise TypeError('the given point is not a cvxopt.base.matrix')
188 if not point
.size
== (self
.dimension(), 1):
189 raise TypeError('the given point has the wrong dimensions')
191 return all([x
> 0 for x
in point
])
195 class IceCream(SymmetricCone
):
197 The nonnegative orthant in ``n`` dimensions.
203 Lorentz "ice cream" cone in the real 3-space
208 Output a human-readable description of myself.
210 tpl
= 'Lorentz "ice cream" cone in the real {:d}-space'
211 return tpl
.format(self
.dimension())
214 def __contains__(self
, point
):
216 Return whether or not ``point`` belongs to this cone.
220 An instance of the ``cvxopt.base.matrix`` class having
221 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
226 >>> matrix([1,0.5,0.5]) in K
230 >>> matrix([1,0,1]) in K
234 >>> matrix([1,1,1]) in K
239 Traceback (most recent call last):
241 TypeError: the given point is not a cvxopt.base.matrix
244 >>> matrix([1,2]) in K
245 Traceback (most recent call last):
247 TypeError: the given point has the wrong dimensions
250 if not isinstance(point
, matrix
):
251 raise TypeError('the given point is not a cvxopt.base.matrix')
252 if not point
.size
== (self
.dimension(), 1):
253 raise TypeError('the given point has the wrong dimensions')
256 if self
.dimension() == 1:
257 # In one dimension, the ice cream cone is the nonnegative
262 return height
>= norm(radius
)
265 def contains_strict(self
, point
):
267 Return whether or not ``point`` belongs to the interior
272 An instance of the ``cvxopt.base.matrix`` class having
273 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
278 >>> K.contains_strict(matrix([1,0.5,0.5]))
282 >>> K.contains_strict(matrix([1,0,1]))
286 >>> K.contains_strict(matrix([1,1,1]))
290 >>> K.contains_strict([1,2,3])
291 Traceback (most recent call last):
293 TypeError: the given point is not a cvxopt.base.matrix
296 >>> K.contains_strict(matrix([1,2]))
297 Traceback (most recent call last):
299 TypeError: the given point has the wrong dimensions
302 if not isinstance(point
, matrix
):
303 raise TypeError('the given point is not a cvxopt.base.matrix')
304 if not point
.size
== (self
.dimension(), 1):
305 raise TypeError('the given point has the wrong dimensions')
308 if self
.dimension() == 1:
309 # In one dimension, the ice cream cone is the nonnegative
314 return height
> norm(radius
)
317 class SymmetricPSD(SymmetricCone
):
319 The nonnegative orthant in ``n`` dimensions.
323 >>> K = SymmetricPSD(3)
325 Cone of symmetric positive-semidefinite matrices on the real 3-space
330 Output a human-readable description of myself.
332 tpl
= 'Cone of symmetric positive-semidefinite matrices ' \
333 'on the real {:d}-space'
334 return tpl
.format(self
.dimension())
337 def __contains__(self
, point
):
339 Return whether or not ``point`` belongs to this cone.
343 An instance of the ``cvxopt.base.matrix`` class having
344 dimensions ``(n,n)`` where ``n`` is the dimension of this cone.
348 >>> K = SymmetricPSD(2)
349 >>> matrix([[1,0],[0,1]]) in K
352 >>> K = SymmetricPSD(2)
353 >>> matrix([[0,0],[0,0]]) in K
356 >>> K = SymmetricPSD(3)
357 >>> matrix([[2,-1,0],[-1,2,-1],[0,-1,2]]) in K
360 >>> K = SymmetricPSD(5)
361 >>> A = matrix([[5,4,3,2,1],
369 >>> K = SymmetricPSD(5)
370 >>> A = matrix([[1,0,0,0,0],
378 >>> K = SymmetricPSD(2)
379 >>> [[1,2],[2,3]] in K
380 Traceback (most recent call last):
382 TypeError: the given point is not a cvxopt.base.matrix
384 >>> K = SymmetricPSD(3)
385 >>> matrix([[1,2],[3,4]]) in K
386 Traceback (most recent call last):
388 TypeError: the given point has the wrong dimensions
391 if not isinstance(point
, matrix
):
392 raise TypeError('the given point is not a cvxopt.base.matrix')
393 if not point
.size
== (self
.dimension(), self
.dimension()):
394 raise TypeError('the given point has the wrong dimensions')
395 if not point
.typecode
== 'd':
396 point
= matrix(point
, (self
.dimension(), self
.dimension()), 'd')
397 return all([e
>= 0 for e
in eigenvalues(point
)])
400 def contains_strict(self
, point
):
402 Return whether or not ``point`` belongs to the interior
407 An instance of the ``cvxopt.base.matrix`` class having
408 dimensions ``(n,n)`` where ``n`` is the dimension of this cone.
409 Its type code must be 'd'.
413 >>> K = SymmetricPSD(2)
414 >>> K.contains_strict(matrix([[1,0],[0,1]]))
417 >>> K = SymmetricPSD(2)
418 >>> K.contains_strict(matrix([[0,0],[0,0]]))
421 >>> K = SymmetricPSD(3)
422 >>> matrix([[2,-1,0],[-1,2,-1],[0,-1,2]]) in K
425 >>> K = SymmetricPSD(5)
426 >>> A = matrix([[5,4,3,2,1],
434 >>> K = SymmetricPSD(5)
435 >>> A = matrix([[1,0,0,0,0],
440 >>> K.contains_strict(A)
443 >>> K = SymmetricPSD(2)
444 >>> K.contains_strict([[1,2],[2,3]])
445 Traceback (most recent call last):
447 TypeError: the given point is not a cvxopt.base.matrix
449 >>> K = SymmetricPSD(3)
450 >>> K.contains_strict(matrix([[1,2],[3,4]]))
451 Traceback (most recent call last):
453 TypeError: the given point has the wrong dimensions
456 if not isinstance(point
, matrix
):
457 raise TypeError('the given point is not a cvxopt.base.matrix')
458 if not point
.size
== (self
.dimension(), self
.dimension()):
459 raise TypeError('the given point has the wrong dimensions')
460 if not point
.typecode
== 'd':
461 point
= matrix(point
, (self
.dimension(), self
.dimension()), 'd')
462 return all([e
> 0 for e
in eigenvalues(point
)])
465 class CartesianProduct(SymmetricCone
):
467 A cartesian product of symmetric cones, which is itself a symmetric
472 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(2))
474 Cartesian product of dimension 5 with 2 factors:
475 * Nonnegative orthant in the real 3-space
476 * Lorentz "ice cream" cone in the real 2-space
479 def __init__(self
, *factors
):
480 my_dimension
= sum([f
.dimension() for f
in factors
])
481 super().__init
__(my_dimension
)
482 self
._factors
= factors
486 Output a human-readable description of myself.
488 tpl
= 'Cartesian product of dimension {:d} with {:d} factors:'
489 tpl
+= '\n * {!s}' * len(self
.factors())
490 format_args
= [self
.dimension(), len(self
.factors())]
491 format_args
+= list(self
.factors())
492 return tpl
.format(*format_args
)
494 def __contains__(self
, point
):
496 Return whether or not ``point`` belongs to this cone.
500 An instance of the ``cvxopt.base.matrix`` class having
501 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
505 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
506 >>> matrix([1,2,3,1,0.5,0.5]) in K
509 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
510 >>> matrix([0,0,0,1,0,1]) in K
513 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
514 >>> matrix([1,1,1,1,1,1]) in K
517 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
518 >>> matrix([1,-1,1,1,0,1]) in K
521 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
522 >>> [1,2,3,4,5,6] in K
523 Traceback (most recent call last):
525 TypeError: the given point is not a cvxopt.base.matrix
527 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
528 >>> matrix([1,2]) in K
529 Traceback (most recent call last):
531 TypeError: the given point has the wrong dimensions
534 if not isinstance(point
, matrix
):
535 raise TypeError('the given point is not a cvxopt.base.matrix')
536 if not point
.size
== (self
.dimension(), 1):
537 raise TypeError('the given point has the wrong dimensions')
539 for factor
in self
.factors():
540 # Split off the components of ``point`` corresponding to
542 factor_part
= point
[0:factor
.dimension()]
543 if not factor_part
in factor
:
545 point
= point
[factor
.dimension():]
550 def contains_strict(self
, point
):
552 Return whether or not ``point`` belongs to the interior
557 An instance of the ``cvxopt.base.matrix`` class having
558 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
562 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
563 >>> K.contains_strict(matrix([1,2,3,1,0.5,0.5]))
566 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
567 >>> K.contains_strict(matrix([1,2,3,1,0,1]))
570 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
571 >>> K.contains_strict(matrix([0,1,1,1,0.5,0.5]))
574 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
575 >>> K.contains_strict(matrix([1,1,1,1,1,1]))
578 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
579 >>> K.contains_strict(matrix([1,-1,1,1,0,1]))
582 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
583 >>> K.contains_strict([1,2,3,4,5,6])
584 Traceback (most recent call last):
586 TypeError: the given point is not a cvxopt.base.matrix
588 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
589 >>> K.contains_strict(matrix([1,2]))
590 Traceback (most recent call last):
592 TypeError: the given point has the wrong dimensions
595 if not isinstance(point
, matrix
):
596 raise TypeError('the given point is not a cvxopt.base.matrix')
597 if not point
.size
== (self
.dimension(), 1):
598 raise TypeError('the given point has the wrong dimensions')
600 for factor
in self
.factors():
601 # Split off the components of ``point`` corresponding to
603 factor_part
= point
[0:factor
.dimension()]
604 if not factor
.contains_strict(factor_part
):
606 point
= point
[factor
.dimension():]
613 Return a tuple containing the factors (in order) of this
618 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(2))
625 def cvxopt_dims(self
):
627 Return a dictionary of dimensions corresponding to the factors
628 of this cartesian product. The format of this dictionary is
629 described in the CVXOPT user's guide:
631 http://cvxopt.org/userguide/coneprog.html#linear-cone-programs
635 >>> K = CartesianProduct(NonnegativeOrthant(3),
638 >>> d = K.cvxopt_dims()
639 >>> (d['l'], d['q'], d['s'])
643 dims
= {'l':0, 'q':[], 's':[]}
644 dims
['l'] += sum([K
.dimension()
645 for K
in self
.factors()
646 if isinstance(K
, NonnegativeOrthant
)])
647 dims
['q'] = [K
.dimension()
648 for K
in self
.factors()
649 if isinstance(K
, IceCream
)]
650 dims
['s'] = [K
.dimension()
651 for K
in self
.factors()
652 if isinstance(K
, SymmetricPSD
)]