diff options
Diffstat (limited to '')
20 files changed, 74 insertions, 134 deletions
diff --git a/sumofsquares/__init__.py b/sumofsquares/__init__.py index 48b8e85..0aa52d6 100644 --- a/sumofsquares/__init__.py +++ b/sumofsquares/__init__.py @@ -1,3 +1,3 @@ -from sumofsquares.abc import ParamSOSExpr, SOSExpr -from sumofsquares.init import init_sos_expr, init_param_expr, init_param_expr_from_reference, init_putinar_epsilon +from sumofsquares.sosexpr.abc import ParamSOSExpr, SOSExpr +from sumofsquares.sosexpr.init import init_sos_expr, init_param_expr, init_param_expr_from_reference, init_putinar_epsilon from sumofsquares.cvxopt import solve_cone, solve_cone2, solve_sos_problem, solve_sos_problem2 diff --git a/sumofsquares/abc.py b/sumofsquares/abc.py deleted file mode 100644 index 03e0b5d..0000000 --- a/sumofsquares/abc.py +++ /dev/null @@ -1,12 +0,0 @@ -import abc - -from sumofsquares.mixins.parametermixin import ParamSOSExprMixin -from sumofsquares.mixins.sosexpropmixin import SOSExprOPMixin - - -class SOSExpr(SOSExprOPMixin, abc.ABC): - pass - - -class ParamSOSExpr(SOSExprOPMixin, ParamSOSExprMixin, abc.ABC): - pass diff --git a/sumofsquares/cvxopt.py b/sumofsquares/cvxopt.py index 93346c3..ec31892 100644 --- a/sumofsquares/cvxopt.py +++ b/sumofsquares/cvxopt.py @@ -4,8 +4,7 @@ import polymatrix import numpy as np import math -from sumofsquares.abc import ParamSOSExpr -from sumofsquares.sosconstraint.abc import SOSConstraint +from sumofsquares.sosexpr.abc import ParamSOSExpr, SOSExpr @dataclasses.dataclass @@ -348,18 +347,17 @@ def solve_cone2( def solve_sos_problem( cost: tuple[polymatrix.Expression], - sos_constraints: tuple[SOSConstraint], + sos_constraints: tuple[SOSExpr], state: polymatrix.ExpressionState, - free_param: tuple[ParamSOSExpr] = None, - x0: dict[ParamSOSExpr, np.ndarray] = None, + free_param: tuple[ParamSOSExpr] | None = None, + x0: dict[ParamSOSExpr, np.ndarray] | None = None, ): if x0 is None: x0 = {} def gen_all_param_expr(): for sos_constraint in sos_constraints: - for param_expr in sos_constraint.dependence: - yield param_expr + yield from sos_constraint.dependence all_param_expr = tuple(set(gen_all_param_expr())) @@ -371,7 +369,7 @@ def solve_sos_problem( def gen_inequality(): for sos_constraint in sos_constraints: if any(param_expr in free_param for param_expr in sos_constraint.dependence): - yield sos_constraint.constraint.eval(sub_vals) + yield sos_constraint.sos_matrix_vec.eval(sub_vals) inequality = tuple(gen_inequality()) @@ -387,10 +385,10 @@ def solve_sos_problem( def solve_sos_problem2( cost: tuple[polymatrix.Expression], - sos_constraints: tuple[SOSConstraint], + sos_constraints: tuple[SOSExpr], state: polymatrix.ExpressionState, - subs: tuple[ParamSOSExpr] = None, - x0: dict[ParamSOSExpr, np.ndarray] = None, + subs: tuple[ParamSOSExpr] | None = None, + x0: dict[ParamSOSExpr, np.ndarray] | None = None, print_info = False, ): if x0 is None: @@ -414,7 +412,7 @@ def solve_sos_problem2( def gen_inequality(): for sos_constraint in sos_constraints: if any(param_expr in free_param_expr for param_expr in sos_constraint.dependence): - yield sos_constraint.constraint.eval(sub_vals) + yield sos_constraint.sos_matrix_vec.eval(sub_vals) inequality = tuple(gen_inequality()) diff --git a/sumofsquares/mixins/getsosconstraintmixin.py b/sumofsquares/mixins/getsosconstraintmixin.py deleted file mode 100644 index 23f3813..0000000 --- a/sumofsquares/mixins/getsosconstraintmixin.py +++ /dev/null @@ -1,10 +0,0 @@ -import abc - -from sumofsquares.sosconstraint.abc import SOSConstraint - - -class GetSOSConstraintMixin(abc.ABC): - @property - @abc.abstractmethod - def sos_constraints(self) -> tuple[SOSConstraint]: - ... diff --git a/sumofsquares/sosconstraint/__init__.py b/sumofsquares/sosconstraint/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/sumofsquares/sosconstraint/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/sumofsquares/sosconstraint/abc.py b/sumofsquares/sosconstraint/abc.py deleted file mode 100644 index 1894b94..0000000 --- a/sumofsquares/sosconstraint/abc.py +++ /dev/null @@ -1,5 +0,0 @@ -from sumofsquares.sosconstraint.mixins import SOSConstraintMixin - - -class SOSConstraint(SOSConstraintMixin): - pass diff --git a/sumofsquares/sosconstraint/impl.py b/sumofsquares/sosconstraint/impl.py deleted file mode 100644 index e0d6cec..0000000 --- a/sumofsquares/sosconstraint/impl.py +++ /dev/null @@ -1,11 +0,0 @@ -import dataclassabc -import polymatrix - -from sumofsquares.sosexprbase.mixins.parametermixin import ParameterMixin -from sumofsquares.sosconstraint.abc import SOSConstraint - - -@dataclassabc.dataclassabc -class SOSConstraintImpl(SOSConstraint): - dependence: tuple[ParameterMixin] - constraint: polymatrix.Expression
\ No newline at end of file diff --git a/sumofsquares/sosconstraint/init.py b/sumofsquares/sosconstraint/init.py deleted file mode 100644 index 68a2f25..0000000 --- a/sumofsquares/sosconstraint/init.py +++ /dev/null @@ -1,14 +0,0 @@ -import polymatrix - -from sumofsquares.sosexprbase.mixins.parametermixin import ParameterMixin -from sumofsquares.sosconstraint.impl import SOSConstraintImpl - - -def init_sos_constraint( - dependence: tuple[ParameterMixin], - constraint: polymatrix.Expression -): - return SOSConstraintImpl( - dependence=dependence, - constraint=constraint, - ) diff --git a/sumofsquares/sosconstraint/mixins.py b/sumofsquares/sosconstraint/mixins.py deleted file mode 100644 index be49620..0000000 --- a/sumofsquares/sosconstraint/mixins.py +++ /dev/null @@ -1,16 +0,0 @@ -import abc -import polymatrix - -from sumofsquares.sosexprbase.mixins.parametermixin import ParameterMixin - - -class SOSConstraintMixin(abc.ABC): - @property - @abc.abstractmethod - def dependence(self) -> tuple[ParameterMixin]: - ... - - @property - @abc.abstractmethod - def constraint(self) -> polymatrix.Expression: - ... diff --git a/sumofsquares/mixins/__init__.py b/sumofsquares/sosexpr/__init__.py index e69de29..e69de29 100644 --- a/sumofsquares/mixins/__init__.py +++ b/sumofsquares/sosexpr/__init__.py diff --git a/sumofsquares/sosexpr/abc.py b/sumofsquares/sosexpr/abc.py new file mode 100644 index 0000000..389956f --- /dev/null +++ b/sumofsquares/sosexpr/abc.py @@ -0,0 +1,12 @@ +import abc + +from sumofsquares.sosexpr.mixins.parametermixin import ParamSOSExprMixin +from sumofsquares.sosexpr.mixins.sosexpropmixin import SOSExprOPMixin + + +class SOSExpr(SOSExprOPMixin, abc.ABC): + pass + + +class ParamSOSExpr(SOSExprOPMixin, ParamSOSExprMixin, abc.ABC): + pass diff --git a/sumofsquares/impl.py b/sumofsquares/sosexpr/impl.py index b58b674..4453588 100644 --- a/sumofsquares/impl.py +++ b/sumofsquares/sosexpr/impl.py @@ -1,10 +1,8 @@ import dataclassabc -import polymatrix from sumofsquares.sosexprbase.abc import ParamSOSExprBase, SOSExprBase -from sumofsquares.sosconstraint.abc import SOSConstraint -from sumofsquares.mixins.putinarepsilonmixin import PutinarEpsilonMixin -from sumofsquares.abc import ParamSOSExpr, SOSExpr +from sumofsquares.sosexpr.mixins.putinarepsilonmixin import PutinarEpsilonMixin +from sumofsquares.sosexpr.abc import ParamSOSExpr, SOSExpr @dataclassabc.dataclassabc(frozen=True) @@ -35,5 +33,5 @@ class PutinarEpsilonImpl(PutinarEpsilonMixin): name: str epsilon: ParamSOSExpr gamma: dict[str, ParamSOSExpr] - sos_constraints: tuple[SOSConstraint] + sos_constraints: tuple[SOSExpr] condition: SOSExpr diff --git a/sumofsquares/init.py b/sumofsquares/sosexpr/init.py index c36d2aa..c94df85 100644 --- a/sumofsquares/init.py +++ b/sumofsquares/sosexpr/init.py @@ -2,9 +2,9 @@ import polymatrix from sumofsquares.sosexprbase.mixins.parametermixin import ParameterMixin from sumofsquares.sosexprbase.init import init_param_sos_expr_base, init_sos_expr_base -from sumofsquares.mixins.sosexprmixin import SOSExprMixin -from sumofsquares.abc import SOSExpr -from sumofsquares.impl import ParamSOSExprImpl, SOSExprImpl, PutinarEpsilonImpl +from sumofsquares.sosexpr.mixins.sosexprmixin import SOSExprMixin +from sumofsquares.sosexpr.abc import SOSExpr +from sumofsquares.sosexpr.impl import ParamSOSExprImpl, SOSExprImpl, PutinarEpsilonImpl def init_sos_expr( @@ -63,10 +63,10 @@ def init_param_expr_from_reference( m_sos_monom = multiplicand_expr.quadratic_monomials(variables) - max_degree = m_sos_monom.max_degree().T.max() + max_degree = m_sos_monom.degree().T.max() m_max_monom = m_sos_monom.filter( - m_sos_monom.max_degree() - max_degree, + m_sos_monom.degree() - max_degree, inverse=True, ) @@ -86,8 +86,8 @@ def init_param_expr_from_reference( def init_putinar_epsilon( name: str, f0: SOSExpr, - fi: dict[str, SOSExpr | polymatrix.Expression] = None, - gi: dict[str, SOSExpr | polymatrix.Expression] = None, + fi: dict[str, SOSExpr | polymatrix.Expression] | None = None, + gi: dict[str, SOSExpr | polymatrix.Expression] | None = None, epsilon_min: SOSExpr | None = None, decrease_rate: SOSExpr | polymatrix.Expression | None = None, ): @@ -110,7 +110,7 @@ def init_putinar_epsilon( gamma_fi = dict(gen_gamma(fi)) for key, gamma_i in gamma_fi.items(): - sos_constraints += gamma_i.sos_constraints + sos_constraints += (gamma_i,) condition = condition - gamma_i * fi[key] if gi is None: @@ -131,13 +131,13 @@ def init_putinar_epsilon( variables=f0.variables, ) - sos_constraints += (epsilon - epsilon_min).sos_constraints + sos_constraints += (epsilon - epsilon_min,) condition += epsilon - if decrease_rate is not None: + if decrease_rate is not None: condition -= decrease_rate - sos_constraints += condition.sos_constraints + sos_constraints += (condition,) return PutinarEpsilonImpl( name=name, diff --git a/sumofsquares/sosexpr/mixins/__init__.py b/sumofsquares/sosexpr/mixins/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sumofsquares/sosexpr/mixins/__init__.py diff --git a/sumofsquares/sosexpr/mixins/getsosconstraintmixin.py b/sumofsquares/sosexpr/mixins/getsosconstraintmixin.py new file mode 100644 index 0000000..f3a0710 --- /dev/null +++ b/sumofsquares/sosexpr/mixins/getsosconstraintmixin.py @@ -0,0 +1,10 @@ +import abc + +from sumofsquares.sosexpr.abc import SOSExpr + + +class GetSOSConstraintMixin(abc.ABC): + @property + @abc.abstractmethod + def sos_constraints(self) -> tuple[SOSExpr]: + ... diff --git a/sumofsquares/mixins/parametermixin.py b/sumofsquares/sosexpr/mixins/parametermixin.py index 5281f35..5f8dd5f 100644 --- a/sumofsquares/mixins/parametermixin.py +++ b/sumofsquares/sosexpr/mixins/parametermixin.py @@ -1,7 +1,7 @@ import abc import polymatrix -from sumofsquares.mixins.sosexprmixin import SOSExprMixin +from sumofsquares.sosexpr.mixins.sosexprmixin import SOSExprMixin from sumofsquares.sosexprbase.abc import ParamSOSExprBase from sumofsquares.sosexprbase.mixins.parametermixin import ParameterMixin diff --git a/sumofsquares/mixins/putinarepsilonmixin.py b/sumofsquares/sosexpr/mixins/putinarepsilonmixin.py index 7f08f18..fdf6e9a 100644 --- a/sumofsquares/mixins/putinarepsilonmixin.py +++ b/sumofsquares/sosexpr/mixins/putinarepsilonmixin.py @@ -1,9 +1,7 @@ import abc -import polymatrix -from sumofsquares.abc import ParamSOSExpr, SOSExpr -from sumofsquares.mixins.getsosconstraintmixin import GetSOSConstraintMixin -from sumofsquares.sosconstraint.abc import SOSConstraint +from sumofsquares.sosexpr.abc import ParamSOSExpr, SOSExpr +from sumofsquares.sosexpr.mixins.getsosconstraintmixin import GetSOSConstraintMixin class PutinarEpsilonMixin(GetSOSConstraintMixin, abc.ABC): diff --git a/sumofsquares/mixins/sosexprmixin.py b/sumofsquares/sosexpr/mixins/sosexprmixin.py index ed3fa65..2e7eaa6 100644 --- a/sumofsquares/mixins/sosexprmixin.py +++ b/sumofsquares/sosexpr/mixins/sosexprmixin.py @@ -1,13 +1,10 @@ import abc import polymatrix -from sumofsquares.sosconstraint.abc import SOSConstraint -from sumofsquares.sosconstraint.init import init_sos_constraint -from sumofsquares.mixins.getsosconstraintmixin import GetSOSConstraintMixin from sumofsquares.sosexprbase.abc import SOSExprBase -class SOSExprMixin(GetSOSConstraintMixin, abc.ABC): +class SOSExprMixin(abc.ABC): @property @abc.abstractmethod def underlying(self) -> SOSExprBase: @@ -31,11 +28,4 @@ class SOSExprMixin(GetSOSConstraintMixin, abc.ABC): @property def sos_matrix_vec(self) -> polymatrix.Expression: - return self.underlying.sos_matrix_as_vector - - @property - def sos_constraints(self) -> tuple[SOSConstraint]: - return (init_sos_constraint( - dependence=self.dependence, - constraint=self.underlying.sos_matrix_as_vector, - ),) + return self.underlying.sos_matrix_vec diff --git a/sumofsquares/mixins/sosexpropmixin.py b/sumofsquares/sosexpr/mixins/sosexpropmixin.py index bce2a02..c410ea5 100644 --- a/sumofsquares/mixins/sosexpropmixin.py +++ b/sumofsquares/sosexpr/mixins/sosexpropmixin.py @@ -1,10 +1,12 @@ import dataclasses import typing +from numpy import isin + import polymatrix import polymatrix.expression.from_ -from sumofsquares.mixins.sosexprmixin import SOSExprMixin +from sumofsquares.sosexpr.mixins.sosexprmixin import SOSExprMixin from sumofsquares.sosexprbase.init import init_sos_expr_base @@ -16,24 +18,27 @@ class SOSExprOPMixin(SOSExprMixin): right: typing.Union[polymatrix.Expression, 'SOSExprOPMixin'], ) -> 'SOSExprOPMixin': - if not isinstance(left, SOSExprOPMixin): - left = polymatrix.expression.from_.from_expr_or_none(left) + # if not isinstance(left, SOSExprOPMixin): + # left = polymatrix.expression.from_.from_expr_or_none(left) - if left is None: - return NotImplemented + # if left is None: + # return NotImplemented - underlying = init_sos_expr_base( - expr=op(polymatrix.from_(left), right.expr), - variables=right.variables, - dependence=right.dependence, - ) + # underlying = init_sos_expr_base( + # expr=op(polymatrix.from_(left), right.expr), + # variables=right.variables, + # dependence=right.dependence, + # ) - return dataclasses.replace( - right, - underlying=underlying, - ) + # return dataclasses.replace( + # right, + # underlying=underlying, + # ) + + if not isinstance(right, SOSExprOPMixin): + if isinstance(right, tuple): + return NotImplemented - elif not isinstance(right, SOSExprOPMixin): right = polymatrix.expression.from_.from_expr_or_none(right) if right is None: @@ -52,8 +57,6 @@ class SOSExprOPMixin(SOSExprMixin): assert left.variables == right.variables, f'{left.variables=}, {right.variables=}' - # print(left.dependence + right.dependence) - underlying=init_sos_expr_base( expr=op(left.expr, right.expr), variables=left.variables, diff --git a/sumofsquares/sosexprbase/mixins/sosexprbasemixin.py b/sumofsquares/sosexprbase/mixins/sosexprbasemixin.py index c8cee19..e9eabac 100644 --- a/sumofsquares/sosexprbase/mixins/sosexprbasemixin.py +++ b/sumofsquares/sosexprbase/mixins/sosexprbasemixin.py @@ -19,5 +19,5 @@ class SOSExprBaseMixin(ExprBaseMixin): return sos_matrix @property - def sos_matrix_as_vector(self) -> polymatrix.Expression: + def sos_matrix_vec(self) -> polymatrix.Expression: return self.sos_matrix.reshape(-1, 1) |