]>
gitweb.michael.orlitzky.com - dunshire.git/blob - src/dunshire/cones.py
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 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
40 def __contains__(self
, point
):
42 Return whether or not ``point`` belongs to this cone.
46 >>> K = SymmetricCone(5)
47 >>> matrix([1,2]) in K
48 Traceback (most recent call last):
53 raise NotImplementedError
55 def contains_strict(self
, point
):
57 Return whether or not ``point`` belongs to the interior
62 >>> K = SymmetricCone(5)
63 >>> K.contains_strict(matrix([1,2]))
64 Traceback (most recent call last):
68 raise NotImplementedError
72 Return the dimension of this symmetric cone.
74 The dimension of this symmetric cone is recorded during its
75 creation. This method simply returns the recorded value, and
76 should not need to be overridden in subclasses. We prefer to do
77 any special computation in ``__init__()`` and record the result
78 in ``self._dimension``.
82 >>> K = SymmetricCone(5)
87 return self
._dimension
90 class NonnegativeOrthant(SymmetricCone
):
92 The nonnegative orthant in ``n`` dimensions.
96 >>> K = NonnegativeOrthant(3)
98 Nonnegative orthant in the real 3-space
103 Output a human-readable description of myself.
105 tpl
= 'Nonnegative orthant in the real {:d}-space'
106 return tpl
.format(self
.dimension())
108 def __contains__(self
, point
):
110 Return whether or not ``point`` belongs to this cone.
114 An instance of the ``cvxopt.base.matrix`` class having
115 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
119 >>> K = NonnegativeOrthant(3)
120 >>> matrix([1,2,3]) in K
123 >>> K = NonnegativeOrthant(3)
124 >>> matrix([1,-0.1,3]) in K
127 >>> K = NonnegativeOrthant(3)
129 Traceback (most recent call last):
131 TypeError: the given point is not a cvxopt.base.matrix
133 >>> K = NonnegativeOrthant(3)
134 >>> matrix([1,2]) in K
135 Traceback (most recent call last):
137 TypeError: the given point has the wrong dimensions
140 if not isinstance(point
, matrix
):
141 raise TypeError('the given point is not a cvxopt.base.matrix')
142 if not point
.size
== (self
.dimension(), 1):
143 raise TypeError('the given point has the wrong dimensions')
145 return all([x
>= 0 for x
in point
])
148 def contains_strict(self
, point
):
150 Return whether or not ``point`` belongs to the interior of this
155 An instance of the ``cvxopt.base.matrix`` class having
156 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
160 >>> K = NonnegativeOrthant(3)
161 >>> K.contains_strict(matrix([1,2,3]))
164 >>> K = NonnegativeOrthant(3)
165 >>> K.contains_strict(matrix([1,0,1]))
168 >>> K = NonnegativeOrthant(3)
169 >>> K.contains_strict(matrix([1,-0.1,3]))
172 >>> K = NonnegativeOrthant(3)
173 >>> K.contains_strict([1,2,3])
174 Traceback (most recent call last):
176 TypeError: the given point is not a cvxopt.base.matrix
178 >>> K = NonnegativeOrthant(3)
179 >>> K.contains_strict(matrix([1,2]))
180 Traceback (most recent call last):
182 TypeError: the given point has the wrong dimensions
185 if not isinstance(point
, matrix
):
186 raise TypeError('the given point is not a cvxopt.base.matrix')
187 if not point
.size
== (self
.dimension(), 1):
188 raise TypeError('the given point has the wrong dimensions')
190 return all([x
> 0 for x
in point
])
194 class IceCream(SymmetricCone
):
196 The nonnegative orthant in ``n`` dimensions.
202 Lorentz "ice cream" cone in the real 3-space
207 Output a human-readable description of myself.
209 tpl
= 'Lorentz "ice cream" cone in the real {:d}-space'
210 return tpl
.format(self
.dimension())
213 def __contains__(self
, point
):
215 Return whether or not ``point`` belongs to this cone.
219 An instance of the ``cvxopt.base.matrix`` class having
220 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
225 >>> matrix([1,0.5,0.5]) in K
229 >>> matrix([1,0,1]) in K
233 >>> matrix([1,1,1]) in K
238 Traceback (most recent call last):
240 TypeError: the given point is not a cvxopt.base.matrix
243 >>> matrix([1,2]) in K
244 Traceback (most recent call last):
246 TypeError: the given point has the wrong dimensions
249 if not isinstance(point
, matrix
):
250 raise TypeError('the given point is not a cvxopt.base.matrix')
251 if not point
.size
== (self
.dimension(), 1):
252 raise TypeError('the given point has the wrong dimensions')
255 if self
.dimension() == 1:
256 # In one dimension, the ice cream cone is the nonnegative
261 return height
>= norm(radius
)
264 def contains_strict(self
, point
):
266 Return whether or not ``point`` belongs to the interior
271 An instance of the ``cvxopt.base.matrix`` class having
272 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
277 >>> K.contains_strict(matrix([1,0.5,0.5]))
281 >>> K.contains_strict(matrix([1,0,1]))
285 >>> K.contains_strict(matrix([1,1,1]))
289 >>> K.contains_strict([1,2,3])
290 Traceback (most recent call last):
292 TypeError: the given point is not a cvxopt.base.matrix
295 >>> K.contains_strict(matrix([1,2]))
296 Traceback (most recent call last):
298 TypeError: the given point has the wrong dimensions
301 if not isinstance(point
, matrix
):
302 raise TypeError('the given point is not a cvxopt.base.matrix')
303 if not point
.size
== (self
.dimension(), 1):
304 raise TypeError('the given point has the wrong dimensions')
307 if self
.dimension() == 1:
308 # In one dimension, the ice cream cone is the nonnegative
313 return height
> norm(radius
)
316 class SymmetricPSD(SymmetricCone
):
318 The nonnegative orthant in ``n`` dimensions.
322 >>> K = SymmetricPSD(3)
324 Cone of symmetric positive-semidefinite matrices on the real 3-space
329 Output a human-readable description of myself.
331 tpl
= 'Cone of symmetric positive-semidefinite matrices ' \
332 'on the real {:d}-space'
333 return tpl
.format(self
.dimension())
336 class CartesianProduct(SymmetricCone
):
338 A cartesian product of symmetric cones, which is itself a symmetric
343 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(2))
345 Cartesian product of dimension 5 with 2 factors:
346 * Nonnegative orthant in the real 3-space
347 * Lorentz "ice cream" cone in the real 2-space
350 def __init__(self
, *factors
):
351 my_dimension
= sum([f
.dimension() for f
in factors
])
352 super().__init
__(my_dimension
)
353 self
._factors
= factors
357 Output a human-readable description of myself.
359 tpl
= 'Cartesian product of dimension {:d} with {:d} factors:'
360 tpl
+= '\n * {!s}' * len(self
.factors())
361 format_args
= [self
.dimension(), len(self
.factors())]
362 format_args
+= list(self
.factors())
363 return tpl
.format(*format_args
)
365 def __contains__(self
, point
):
367 Return whether or not ``point`` belongs to this cone.
371 An instance of the ``cvxopt.base.matrix`` class having
372 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
376 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
377 >>> matrix([1,2,3,1,0.5,0.5]) in K
380 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
381 >>> matrix([0,0,0,1,0,1]) in K
384 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
385 >>> matrix([1,1,1,1,1,1]) in K
388 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
389 >>> matrix([1,-1,1,1,0,1]) in K
392 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
393 >>> [1,2,3,4,5,6] in K
394 Traceback (most recent call last):
396 TypeError: the given point is not a cvxopt.base.matrix
398 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
399 >>> matrix([1,2]) in K
400 Traceback (most recent call last):
402 TypeError: the given point has the wrong dimensions
405 if not isinstance(point
, matrix
):
406 raise TypeError('the given point is not a cvxopt.base.matrix')
407 if not point
.size
== (self
.dimension(), 1):
408 raise TypeError('the given point has the wrong dimensions')
410 for factor
in self
.factors():
411 # Split off the components of ``point`` corresponding to
413 factor_part
= point
[0:factor
.dimension()]
414 if not factor_part
in factor
:
416 point
= point
[factor
.dimension():]
421 def contains_strict(self
, point
):
423 Return whether or not ``point`` belongs to the interior
428 An instance of the ``cvxopt.base.matrix`` class having
429 dimensions ``(n,1)`` where ``n`` is the dimension of this cone.
433 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
434 >>> K.contains_strict(matrix([1,2,3,1,0.5,0.5]))
437 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
438 >>> K.contains_strict(matrix([1,2,3,1,0,1]))
441 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
442 >>> K.contains_strict(matrix([0,1,1,1,0.5,0.5]))
445 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
446 >>> K.contains_strict(matrix([1,1,1,1,1,1]))
449 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
450 >>> K.contains_strict(matrix([1,-1,1,1,0,1]))
453 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
454 >>> K.contains_strict([1,2,3,4,5,6])
455 Traceback (most recent call last):
457 TypeError: the given point is not a cvxopt.base.matrix
459 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(3))
460 >>> K.contains_strict(matrix([1,2]))
461 Traceback (most recent call last):
463 TypeError: the given point has the wrong dimensions
466 if not isinstance(point
, matrix
):
467 raise TypeError('the given point is not a cvxopt.base.matrix')
468 if not point
.size
== (self
.dimension(), 1):
469 raise TypeError('the given point has the wrong dimensions')
471 for factor
in self
.factors():
472 # Split off the components of ``point`` corresponding to
474 factor_part
= point
[0:factor
.dimension()]
475 if not factor
.contains_strict(factor_part
):
477 point
= point
[factor
.dimension():]
484 Return a tuple containing the factors (in order) of this
489 >>> K = CartesianProduct(NonnegativeOrthant(3), IceCream(2))
496 def cvxopt_dims(self
):
498 Return a dictionary of dimensions corresponding to the factors
499 of this cartesian product. The format of this dictionary is
500 described in the CVXOPT user's guide:
502 http://cvxopt.org/userguide/coneprog.html#linear-cone-programs
506 >>> K = CartesianProduct(NonnegativeOrthant(3),
509 >>> d = K.cvxopt_dims()
510 >>> (d['l'], d['q'], d['s'])
514 dims
= {'l':0, 'q':[], 's':[]}
515 dims
['l'] += sum([K
.dimension()
516 for K
in self
.factors()
517 if isinstance(K
, NonnegativeOrthant
)])
518 dims
['q'] = [K
.dimension()
519 for K
in self
.factors()
520 if isinstance(K
, IceCream
)]
521 dims
['s'] = [K
.dimension()
522 for K
in self
.factors()
523 if isinstance(K
, SymmetricPSD
)]