r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# ------------------------------------------------------------------------------

2# Copyright (C) 2019 Maximilian Stahlberg

3# Based on the original picos.expressions module by Guillaume Sagnol.

4#

5# This file is part of PICOS.

6#

7# PICOS is free software: you can redistribute it and/or modify it under the

9# Foundation, either version 3 of the License, or (at your option) any later

10# version.

11#

12# PICOS is distributed in the hope that it will be useful, but WITHOUT ANY

13# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR

14# A PARTICULAR PURPOSE. See the GNU General Public License for more details.

15#

16# You should have received a copy of the GNU General Public License along with

17# this program. If not, see <http://www.gnu.org/licenses/>.

18# ------------------------------------------------------------------------------

20"""Implements :class:ExponentialCone."""

22import operator

23from collections import namedtuple

25from .. import glyphs

26from ..apidoc import api_end, api_start

27from ..constraints import ExpConeConstraint

28from .cone import Cone

29from .exp_affine import AffineExpression

31_API_START = api_start(globals())

32# -------------------------------

35class ExponentialCone(Cone):

36 r"""The exponential cone.

38 Represents the convex cone

39 :math:\operatorname{cl}\{(x,y,z): y \exp(\frac{z}{y}) \leq x, x,y > 0\}.

40 """

42 def __init__(self):

43 """Construct an exponential cone."""

44 typeStr = "Exponential Cone"

45 symbStr = glyphs.closure(glyphs.set(glyphs.sep(

46 glyphs.col_vectorize("x", "y", "z"), ", ".join([

47 glyphs.le(

48 glyphs.mul("y", glyphs.exp(glyphs.div("z", "y"))), "x"),

49 glyphs.gt("x", 0),

50 glyphs.gt("y", 0)

51 ]))))

53 Cone.__init__(self, 3, typeStr, symbStr)

55 def _get_mutables(self):

56 return frozenset()

58 def _replace_mutables(self):

59 return self

61 Subtype = namedtuple("Subtype", ())

63 def _get_subtype(self):

64 return self.Subtype()

66 @classmethod

67 def _predict(cls, subtype, relation, other):

68 assert isinstance(subtype, cls.Subtype)

70 if relation == operator.__rshift__:

71 if issubclass(other.clstype, AffineExpression):

72 if other.subtype.dim == 3:

73 return ExpConeConstraint.make_type()

75 return Cone._predict_base(cls, subtype, relation, other)

77 def _rshift_implementation(self, element):

78 if isinstance(element, AffineExpression):

79 if len(element) != 3:

80 raise TypeError("Elements of the exponential cone must be "

81 "three-dimensional.")

83 return ExpConeConstraint(element)

85 # Handle scenario uncertainty for all cones.

86 return Cone._rshift_base(self, element)

88 @property

89 def dual_cone(self):

90 """Implement :attr:.cone.Cone.dual_cone."""

91 raise NotImplementedError(

92 "PICOS does not have an explicit representation for the dual of "

93 "the exponential cone yet.")

96# --------------------------------------

97__all__ = api_end(_API_START, globals())