Coverage for picos/expressions/cone.py: 88.24%
51 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-15 14:21 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-15 14:21 +0000
1# ------------------------------------------------------------------------------
2# Copyright (C) 2020 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
8# terms of the GNU General Public License as published by the Free Software
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"""Backend for mathematical set type implementations."""
22import operator
23from abc import abstractmethod
25from .. import glyphs
26from ..apidoc import api_end, api_start
27from ..constraints.uncertain import ScenarioUncertainConicConstraint
28from .expression import ExpressionType
29from .set import Set
31_API_START = api_start(globals())
32# -------------------------------
35class Cone(Set):
36 """Abstract base class for a cone."""
38 def __init__(self, dim, typeStr, symbStr):
39 """Perform basic initialization for :class:`Cone` instances.
41 :param int or None dim: Fixed member dimensionality, or :obj:`None`.
42 :param str typeStr: Short string denoting the set type.
43 :param str symbStr: Algebraic string description of the set.
44 """
45 if dim:
46 typeStr = "{}-dim. {}".format(dim, typeStr)
48 Set.__init__(self, typeStr, symbStr)
50 if dim is not None and not isinstance(dim, int):
51 raise TypeError(
52 "The cone's fixed dimensionality must be an integer or None.")
54 if dim == 0:
55 raise ValueError("Zero-dimensional cones are not supported.")
57 self._dim = dim
59 @property
60 def dim(self):
61 """The fixed member dimensionality, or :obj:`None`.
63 If this is :obj:`None`, the instance represents any finite dimensional
64 version of the cone. Such an abstract cone can not be used to define a
65 :class:`~.cone_product.ProductCone`.
66 """
67 return self._dim
69 @property
70 @abstractmethod
71 def dual_cone(self):
72 """The dual cone."""
73 pass
75 def _check_dimension(self, element):
76 if self.dim and self.dim != len(element):
77 raise TypeError("The shape {} of {} does not match the fixed "
78 "dimensionality {} of the cone {}.".format(glyphs.shape(
79 element.shape), element.string, self.dim, self.string))
81 @staticmethod
82 def _predict_base(cls, subtype, relation, other):
83 """Base :meth:`_predict` method for all cone types."""
84 from .uncertain.pert_scenario import ScenarioPerturbationSet
85 from .uncertain.uexp_affine import UncertainAffineExpression
87 assert isinstance(subtype, cls.Subtype)
89 cone = ExpressionType(cls, subtype)
91 if relation == operator.__rshift__:
92 if issubclass(other.clstype, UncertainAffineExpression) \
93 and not subtype.dim or subtype.dim == other.subtype.dim:
94 universe = other.subtype.universe_type
96 if issubclass(universe.clstype, ScenarioPerturbationSet):
97 return ScenarioUncertainConicConstraint.make_type(
98 dim=other.subtype.dim,
99 scenario_count=universe.subtype.scenario_count,
100 cone_type=cone)
102 return NotImplemented
104 @staticmethod
105 def _rshift_base(self, element):
106 """Base :meth:`__rshift__` method for all cone types."""
107 from .uncertain.pert_scenario import ScenarioPerturbationSet
108 from .uncertain.uexp_affine import UncertainAffineExpression
110 if isinstance(element, UncertainAffineExpression):
111 self._check_dimension(element)
113 if isinstance(element.universe, ScenarioPerturbationSet):
114 return ScenarioUncertainConicConstraint(element, self)
116 return NotImplemented
119# --------------------------------------
120__all__ = api_end(_API_START, globals())