From 428f058aad1389e6ac2a8dc5666a177b3dcf5e8d Mon Sep 17 00:00:00 2001 From: Michael Schneeberger Date: Mon, 19 Feb 2024 13:46:41 +0100 Subject: flatten package structure for better readibility --- sumofsquares/__init__.py | 10 +- sumofsquares/abc.py | 12 ++ sumofsquares/abc/__init__.py | 0 sumofsquares/abc/sosexpr.py | 12 -- sumofsquares/cvxopt.py | 2 +- sumofsquares/impl.py | 39 ++++++ sumofsquares/impl/__init__.py | 0 sumofsquares/impl/energyfunction2impl.py | 19 --- sumofsquares/impl/energyfunctionimpl.py | 19 --- sumofsquares/impl/interiorconstraintimpl.py | 14 -- sumofsquares/impl/putinarepsilonimpl.py | 15 --- sumofsquares/impl/sosexprimpl.py | 27 ---- sumofsquares/init.py | 148 ++++++++++++++++++++++ sumofsquares/init/initenergyfunction.py | 101 --------------- sumofsquares/init/initenergyfunction2.py | 110 ---------------- sumofsquares/init/initinteriorconstraint.py | 28 ---- sumofsquares/init/initputinarepsilon.py | 71 ----------- sumofsquares/init/initsosexpr.py | 85 ------------- sumofsquares/mixins/energyfunction2mixin.py | 53 -------- sumofsquares/mixins/energyfunctionmixin.py | 53 -------- sumofsquares/mixins/interiorconstraintmixin.py | 21 --- sumofsquares/mixins/putinarepsilonmixin.py | 2 +- sumofsquares/mixins/sosexprmixin.py | 2 +- sumofsquares/mixins/sosexpropmixin.py | 2 +- sumofsquares/sosconstraint/abc.py | 2 +- sumofsquares/sosconstraint/init.py | 14 ++ sumofsquares/sosconstraint/initsosconstraint.py | 14 -- sumofsquares/sosconstraint/mixins.py | 16 +++ sumofsquares/sosconstraint/sosconstraintmixin.py | 16 --- sumofsquares/sosexprbase/abc.py | 1 + sumofsquares/sosexprbase/init.py | 64 ++++++++++ sumofsquares/sosexprbase/init/initsosexprbase.py | 64 ---------- sumofsquares/sosexprbase/mixins/parametermixin.py | 4 + 33 files changed, 305 insertions(+), 735 deletions(-) create mode 100644 sumofsquares/abc.py delete mode 100644 sumofsquares/abc/__init__.py delete mode 100644 sumofsquares/abc/sosexpr.py create mode 100644 sumofsquares/impl.py delete mode 100644 sumofsquares/impl/__init__.py delete mode 100644 sumofsquares/impl/energyfunction2impl.py delete mode 100644 sumofsquares/impl/energyfunctionimpl.py delete mode 100644 sumofsquares/impl/interiorconstraintimpl.py delete mode 100644 sumofsquares/impl/putinarepsilonimpl.py delete mode 100644 sumofsquares/impl/sosexprimpl.py create mode 100644 sumofsquares/init.py delete mode 100644 sumofsquares/init/initenergyfunction.py delete mode 100644 sumofsquares/init/initenergyfunction2.py delete mode 100644 sumofsquares/init/initinteriorconstraint.py delete mode 100644 sumofsquares/init/initputinarepsilon.py delete mode 100644 sumofsquares/init/initsosexpr.py delete mode 100644 sumofsquares/mixins/energyfunction2mixin.py delete mode 100644 sumofsquares/mixins/energyfunctionmixin.py delete mode 100644 sumofsquares/mixins/interiorconstraintmixin.py create mode 100644 sumofsquares/sosconstraint/init.py delete mode 100644 sumofsquares/sosconstraint/initsosconstraint.py create mode 100644 sumofsquares/sosconstraint/mixins.py delete mode 100644 sumofsquares/sosconstraint/sosconstraintmixin.py create mode 100644 sumofsquares/sosexprbase/init.py delete mode 100644 sumofsquares/sosexprbase/init/initsosexprbase.py diff --git a/sumofsquares/__init__.py b/sumofsquares/__init__.py index fb40a64..48b8e85 100644 --- a/sumofsquares/__init__.py +++ b/sumofsquares/__init__.py @@ -1,9 +1,3 @@ -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr - -from sumofsquares.init.initsosexpr import init_sos_expr, init_param_expr, init_param_expr_from_reference -from sumofsquares.init.initenergyfunction import init_energy_function -from sumofsquares.init.initenergyfunction2 import init_energy_function2 -from sumofsquares.init.initinteriorconstraint import init_interior_constraint -from sumofsquares.init.initputinarepsilon import init_putinar_epsilon - +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.cvxopt import solve_cone, solve_cone2, solve_sos_problem, solve_sos_problem2 diff --git a/sumofsquares/abc.py b/sumofsquares/abc.py new file mode 100644 index 0000000..03e0b5d --- /dev/null +++ b/sumofsquares/abc.py @@ -0,0 +1,12 @@ +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/abc/__init__.py b/sumofsquares/abc/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/sumofsquares/abc/sosexpr.py b/sumofsquares/abc/sosexpr.py deleted file mode 100644 index 03e0b5d..0000000 --- a/sumofsquares/abc/sosexpr.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 f27212d..93346c3 100644 --- a/sumofsquares/cvxopt.py +++ b/sumofsquares/cvxopt.py @@ -3,8 +3,8 @@ import cvxopt import polymatrix import numpy as np import math -from sumofsquares.abc.sosexpr import ParamSOSExpr +from sumofsquares.abc import ParamSOSExpr from sumofsquares.sosconstraint.abc import SOSConstraint diff --git a/sumofsquares/impl.py b/sumofsquares/impl.py new file mode 100644 index 0000000..b58b674 --- /dev/null +++ b/sumofsquares/impl.py @@ -0,0 +1,39 @@ +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 + + +@dataclassabc.dataclassabc(frozen=True) +class SOSExprImpl(SOSExpr): + underlying: SOSExprBase + + +@dataclassabc.dataclassabc(frozen=True) +class ParamSOSExprImpl(ParamSOSExpr): + underlying: ParamSOSExprBase + + def __eq__(self, other): + if isinstance(other, ParamSOSExprImpl): + return self.underlying == other.underlying + + elif isinstance(other, ParamSOSExprBase): + return self.underlying == other + + else: + return False + + def __hash__(self): + return hash(self.underlying) + + +@dataclassabc.dataclassabc(frozen=True) +class PutinarEpsilonImpl(PutinarEpsilonMixin): + name: str + epsilon: ParamSOSExpr + gamma: dict[str, ParamSOSExpr] + sos_constraints: tuple[SOSConstraint] + condition: SOSExpr diff --git a/sumofsquares/impl/__init__.py b/sumofsquares/impl/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/sumofsquares/impl/energyfunction2impl.py b/sumofsquares/impl/energyfunction2impl.py deleted file mode 100644 index 7e6b091..0000000 --- a/sumofsquares/impl/energyfunction2impl.py +++ /dev/null @@ -1,19 +0,0 @@ -import dataclassabc -import polymatrix - -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr -from sumofsquares.mixins.energyfunction2mixin import EnergyFunction2Mixin -from sumofsquares.sosconstraint.abc import SOSConstraint - - -@dataclassabc.dataclassabc(frozen=True) -class EnergyFunction2Impl(EnergyFunction2Mixin): - name: str - h: SOSExpr - h_dot: SOSExpr - epsilon: ParamSOSExpr - gamma_b: ParamSOSExpr - gamma_roi: list[ParamSOSExpr] - # gamma_w_inner: ParamSOSExpr | None - # gamma_w_outer: ParamSOSExpr | None - sos_constraints: tuple[SOSConstraint] diff --git a/sumofsquares/impl/energyfunctionimpl.py b/sumofsquares/impl/energyfunctionimpl.py deleted file mode 100644 index 058ae58..0000000 --- a/sumofsquares/impl/energyfunctionimpl.py +++ /dev/null @@ -1,19 +0,0 @@ -import dataclassabc -import polymatrix - -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr -from sumofsquares.sosconstraint.abc import SOSConstraint -from sumofsquares.mixins.energyfunctionmixin import EnergyFunctionMixin - - -@dataclassabc.dataclassabc(frozen=True) -class EnergyFunctionImpl(EnergyFunctionMixin): - name: str - h: SOSExpr - h_dot: SOSExpr - epsilon: ParamSOSExpr - gamma_b: ParamSOSExpr - gamma_roi: ParamSOSExpr | None - gamma_w_inner: ParamSOSExpr | None - gamma_w_outer: ParamSOSExpr | None - sos_constraints: tuple[SOSConstraint] diff --git a/sumofsquares/impl/interiorconstraintimpl.py b/sumofsquares/impl/interiorconstraintimpl.py deleted file mode 100644 index ac76c19..0000000 --- a/sumofsquares/impl/interiorconstraintimpl.py +++ /dev/null @@ -1,14 +0,0 @@ -import dataclassabc -import polymatrix - -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr -from sumofsquares.mixins.energyfunction2mixin import EnergyFunction2Mixin -from sumofsquares.mixins.interiorconstraintmixin import InteriorConstraintMixin -from sumofsquares.sosconstraint.abc import SOSConstraint - - -@dataclassabc.dataclassabc(frozen=True) -class InteriorConstraintImpl(InteriorConstraintMixin): - name: str - gamma: ParamSOSExpr | None - sos_constraints: tuple[SOSConstraint] diff --git a/sumofsquares/impl/putinarepsilonimpl.py b/sumofsquares/impl/putinarepsilonimpl.py deleted file mode 100644 index dfba3f0..0000000 --- a/sumofsquares/impl/putinarepsilonimpl.py +++ /dev/null @@ -1,15 +0,0 @@ -import dataclassabc -import polymatrix - -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr -from sumofsquares.mixins.putinarepsilonmixin import PutinarEpsilonMixin -from sumofsquares.sosconstraint.abc import SOSConstraint - - -@dataclassabc.dataclassabc(frozen=True) -class PutinarEpsilonImpl(PutinarEpsilonMixin): - name: str - epsilon: ParamSOSExpr - gamma: dict[str, ParamSOSExpr] - sos_constraints: tuple[SOSConstraint] - condition: SOSExpr diff --git a/sumofsquares/impl/sosexprimpl.py b/sumofsquares/impl/sosexprimpl.py deleted file mode 100644 index c48143b..0000000 --- a/sumofsquares/impl/sosexprimpl.py +++ /dev/null @@ -1,27 +0,0 @@ -import dataclassabc - -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr -from sumofsquares.sosexprbase.abc import ParamSOSExprBase, SOSExprBase - - -@dataclassabc.dataclassabc(frozen=True) -class SOSExprImpl(SOSExpr): - underlying: SOSExprBase - - -@dataclassabc.dataclassabc(frozen=True) -class ParamSOSExprImpl(ParamSOSExpr): - underlying: ParamSOSExprBase - - def __eq__(self, other): - if isinstance(other, ParamSOSExprImpl): - return self.underlying == other.underlying - - elif isinstance(other, ParamSOSExprBase): - return self.underlying == other - - else: - return False - - def __hash__(self): - return hash(self.underlying) diff --git a/sumofsquares/init.py b/sumofsquares/init.py new file mode 100644 index 0000000..c36d2aa --- /dev/null +++ b/sumofsquares/init.py @@ -0,0 +1,148 @@ +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 + + +def init_sos_expr( + expr: polymatrix.Expression, + variables: polymatrix.Expression, + dependence: tuple[ParameterMixin], +): + return SOSExprImpl( + underlying=init_sos_expr_base( + expr=expr, + variables=variables, + dependence=dependence, + ), + ) + + +def init_param_expr( + name: str, + variables: polymatrix.Expression, + monom: polymatrix.Expression | None = None, + n_row: int | None = None, + n_col: int | None = None, +): + return ParamSOSExprImpl( + underlying=init_param_sos_expr_base( + name=name, + monom=monom, + variables=variables, + n_row=n_row, + n_col=n_col, + ), + ) + + +def init_param_expr_from_reference( + name: str, + reference: SOSExpr, + # variables: polymatrix.Expression, + multiplicand: SOSExpr | polymatrix.Expression | None = None, +): + variables = reference.variables + + if multiplicand is None: + multiplicand_expr = polymatrix.from_(1) + + elif isinstance(multiplicand, polymatrix.Expression): + multiplicand_expr = multiplicand + + elif isinstance(multiplicand, SOSExprMixin): + assert multiplicand.variables == variables, f'{multiplicand.variables=}, {variables=}' + + multiplicand_expr = multiplicand.expr + + else: + multiplicand_expr = polymatrix.from_(multiplicand) + + m_sos_monom = multiplicand_expr.quadratic_monomials(variables) + + max_degree = m_sos_monom.max_degree().T.max() + + m_max_monom = m_sos_monom.filter( + m_sos_monom.max_degree() - max_degree, + inverse=True, + ) + + sos_monom = reference.expr.quadratic_monomials(variables).subtract_monomials(m_max_monom) + + expr = (sos_monom @ sos_monom.T).reshape(1, -1).sum() + + monom = expr.linear_monomials(variables).cache() + + return init_param_expr( + name=name, + monom=monom, + variables=variables, + ) + + +def init_putinar_epsilon( + name: str, + f0: SOSExpr, + fi: dict[str, SOSExpr | polymatrix.Expression] = None, + gi: dict[str, SOSExpr | polymatrix.Expression] = None, + epsilon_min: SOSExpr | None = None, + decrease_rate: SOSExpr | polymatrix.Expression | None = None, +): + sos_constraints = tuple() + + condition = f0 + + def gen_gamma(fi): + for key, val in fi.items(): + yield key, init_param_expr_from_reference( + name=f'gamma_{key}_{name}', + reference=f0, + multiplicand=val, + ) + + if fi is None: + gamma_fi = {} + + else: + gamma_fi = dict(gen_gamma(fi)) + + for key, gamma_i in gamma_fi.items(): + sos_constraints += gamma_i.sos_constraints + condition = condition - gamma_i * fi[key] + + if gi is None: + gamma_gi = {} + + else: + gamma_gi = dict(gen_gamma(gi)) + + for key, gamma_i in gamma_gi.items(): + condition = condition - gamma_i * gi[key] + + if epsilon_min is None: + epsilon = None + + else: + epsilon = init_param_expr( + name=f'epsilon_{name}', + variables=f0.variables, + ) + + sos_constraints += (epsilon - epsilon_min).sos_constraints + condition += epsilon + + if decrease_rate is not None: + condition -= decrease_rate + + sos_constraints += condition.sos_constraints + + return PutinarEpsilonImpl( + name=name, + epsilon=epsilon, + gamma=gamma_fi | gamma_gi, + sos_constraints=sos_constraints, + condition=condition, + ) diff --git a/sumofsquares/init/initenergyfunction.py b/sumofsquares/init/initenergyfunction.py deleted file mode 100644 index 8b2f1bf..0000000 --- a/sumofsquares/init/initenergyfunction.py +++ /dev/null @@ -1,101 +0,0 @@ -import polymatrix - -from sumofsquares.abc.sosexpr import SOSExpr -from sumofsquares.impl.energyfunctionimpl import EnergyFunctionImpl -from sumofsquares.init.initsosexpr import init_param_expr, init_param_expr_from_reference, init_sos_expr - - -def init_energy_function( - name: str, - h: SOSExpr, - x_dot: SOSExpr, - positive_b: bool, - epsilon_min: SOSExpr | None = None, - roi: SOSExpr | polymatrix.Expression | None = None, - decrease_rate: SOSExpr | polymatrix.Expression | None = None, - w_outer: SOSExpr | polymatrix.Expression | None = None, - w_inner: SOSExpr | polymatrix.Expression | None = None, -): - sos_constraints = tuple() - - nh = h.diff().T - h_dot = (nh.T @ x_dot).cache() - - gamma_b = init_param_expr_from_reference( - name=f'gamma_b_{name}', - reference=h_dot, - multiplicand=h, - ) - if positive_b: - sos_constraints += gamma_b.sos_constraints - - energy_expr = -h_dot - energy_expr -= gamma_b * h - - if epsilon_min is None: - epsilon = None - - else: - epsilon = init_param_expr( - name=f'epsilon_{name}', - variables=h.variables, - ) - - sos_constraints += (epsilon - epsilon_min).sos_constraints - energy_expr += epsilon - - if roi is None: - gamma_roi = None, - - else: - gamma_roi = init_param_expr_from_reference( - name=f'gamma_roi_{name}', - reference=h_dot, - multiplicand=roi, - ) - sos_constraints += gamma_roi.sos_constraints - - energy_expr += gamma_roi * roi - - if decrease_rate is not None: - energy_expr -= decrease_rate - - sos_constraints += energy_expr.sos_constraints - - if w_outer is None: - gamma_w_outer = None - - else: - gamma_w_outer = init_param_expr_from_reference( - name=f'gamma_w_outer_{name}', - reference=h, - multiplicand=w_outer, - ) - - sos_constraints += gamma_w_outer.sos_constraints - sos_constraints += (h - gamma_w_outer * w_outer).sos_constraints - - if w_inner is None: - gamma_w_inner = None - - else: - gamma_w_inner = init_param_expr_from_reference( - name=f'gamma_w_inner_{name}', - reference=h, - multiplicand=w_inner, - ) - - sos_constraints += gamma_w_inner.sos_constraints - sos_constraints += (gamma_w_inner * w_inner - h).sos_constraints - - return EnergyFunctionImpl( - name=name, - h=h, - h_dot=h_dot, - epsilon=epsilon, - gamma_roi=gamma_roi, - gamma_b=gamma_b, - gamma_w_outer=gamma_w_outer, - gamma_w_inner=gamma_w_inner, - sos_constraints=sos_constraints, - ) diff --git a/sumofsquares/init/initenergyfunction2.py b/sumofsquares/init/initenergyfunction2.py deleted file mode 100644 index 785ef87..0000000 --- a/sumofsquares/init/initenergyfunction2.py +++ /dev/null @@ -1,110 +0,0 @@ -import polymatrix - -from sumofsquares.abc.sosexpr import SOSExpr -from sumofsquares.impl.energyfunction2impl import EnergyFunction2Impl -from sumofsquares.init.initsosexpr import init_param_expr, init_param_expr_from_reference - - -def init_energy_function2( - name: str, - # h: SOSExpr, - # x_dot: SOSExpr, - cond: SOSExpr, - h: SOSExpr, - positive_b: bool, - epsilon_min: SOSExpr | None = None, - roi: list[SOSExpr | polymatrix.Expression] = None, - decrease_rate: SOSExpr | polymatrix.Expression | None = None, - # w_outer: SOSExpr | polymatrix.Expression | None = None, - # w_inner: SOSExpr | polymatrix.Expression | None = None, -): - sos_constraints = tuple() - - cond = cond.cache() - - # nh = h.diff().T - # h_dot = (nh.T @ x_dot).cache() - - gamma_b = init_param_expr_from_reference( - name=f'gamma_b_{name}', - reference=cond, - multiplicand=h, - ) - if positive_b: - sos_constraints += gamma_b.sos_constraints - - energy_expr = -cond - energy_expr -= gamma_b * h - - if epsilon_min is None: - epsilon = None - - else: - epsilon = init_param_expr( - name=f'epsilon_{name}', - variables=h.variables, - ) - - sos_constraints += (epsilon - epsilon_min).sos_constraints - energy_expr += epsilon - - if roi is None: - gamma_roi = None, - - else: - def gen_gamma_roi(): - for idx, roi_i in enumerate(roi): - yield init_param_expr_from_reference( - name=f'gamma_roi{idx}_{name}', - reference=cond, - multiplicand=roi_i, - ) - gamma_roi = tuple(gen_gamma_roi()) - - for gamma_roi_i, roi_i in zip(gamma_roi, roi): - sos_constraints += gamma_roi_i.sos_constraints - - energy_expr += gamma_roi_i * roi_i - - if decrease_rate is not None: - energy_expr -= decrease_rate - - sos_constraints += energy_expr.sos_constraints - - # if w_outer is None: - # gamma_w_outer = None - - # else: - # gamma_w_outer = init_param_expr_from_reference( - # name=f'gamma_w_outer_{name}', - # reference=h, - # multiplicand=w_outer, - # ) - - # sos_constraints += gamma_w_outer.sos_constraints - # sos_constraints += (h - gamma_w_outer * w_outer).sos_constraints - - # if w_inner is None: - # gamma_w_inner = None - - # else: - # gamma_w_inner = init_param_expr_from_reference( - # name=f'gamma_w_inner_{name}', - # reference=h, - # multiplicand=w_inner, - # ) - - # sos_constraints += gamma_w_inner.sos_constraints - # sos_constraints += (gamma_w_inner * w_inner - h).sos_constraints - - return EnergyFunction2Impl( - name=name, - h=h, - h_dot=cond, - epsilon=epsilon, - gamma_roi=gamma_roi, - gamma_b=gamma_b, - # gamma_w_outer=gamma_w_outer, - # gamma_w_inner=gamma_w_inner, - sos_constraints=sos_constraints, - ) diff --git a/sumofsquares/init/initinteriorconstraint.py b/sumofsquares/init/initinteriorconstraint.py deleted file mode 100644 index 3daa44e..0000000 --- a/sumofsquares/init/initinteriorconstraint.py +++ /dev/null @@ -1,28 +0,0 @@ -import polymatrix - -from sumofsquares.abc.sosexpr import SOSExpr -from sumofsquares.impl.interiorconstraintimpl import InteriorConstraintImpl -from sumofsquares.init.initsosexpr import init_param_expr_from_reference - - -def init_interior_constraint( - name: str, - h: SOSExpr, - w: SOSExpr | polymatrix.Expression, -): - sos_constraints = tuple() - - gamma = init_param_expr_from_reference( - name=f'gamma_{name}', - reference=h, - multiplicand=w, - ) - - sos_constraints += gamma.sos_constraints - sos_constraints += (h - gamma * w).sos_constraints - - return InteriorConstraintImpl( - name=name, - gamma=gamma, - sos_constraints=sos_constraints, - ) diff --git a/sumofsquares/init/initputinarepsilon.py b/sumofsquares/init/initputinarepsilon.py deleted file mode 100644 index 6a4ccb2..0000000 --- a/sumofsquares/init/initputinarepsilon.py +++ /dev/null @@ -1,71 +0,0 @@ -import polymatrix - -from sumofsquares.abc.sosexpr import SOSExpr -from sumofsquares.impl.energyfunction2impl import EnergyFunction2Impl -from sumofsquares.impl.putinarepsilonimpl import PutinarEpsilonImpl -from sumofsquares.init.initsosexpr import init_param_expr, 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, - epsilon_min: SOSExpr | None = None, - decrease_rate: SOSExpr | polymatrix.Expression | None = None, -): - sos_constraints = tuple() - - condition = f0 - - def gen_gamma(fi): - for key, val in fi.items(): - yield key, init_param_expr_from_reference( - name=f'gamma_{key}_{name}', - reference=f0, - multiplicand=val, - ) - - if fi is None: - gamma_fi = {} - - else: - gamma_fi = dict(gen_gamma(fi)) - - for key, gamma_i in gamma_fi.items(): - sos_constraints += gamma_i.sos_constraints - condition = condition - gamma_i * fi[key] - - if gi is None: - gamma_gi = {} - - else: - gamma_gi = dict(gen_gamma(gi)) - - for key, gamma_i in gamma_gi.items(): - condition = condition - gamma_i * gi[key] - - if epsilon_min is None: - epsilon = None - - else: - epsilon = init_param_expr( - name=f'epsilon_{name}', - variables=f0.variables, - ) - - sos_constraints += (epsilon - epsilon_min).sos_constraints - condition += epsilon - - if decrease_rate is not None: - condition -= decrease_rate - - sos_constraints += condition.sos_constraints - - return PutinarEpsilonImpl( - name=name, - epsilon=epsilon, - gamma=gamma_fi | gamma_gi, - sos_constraints=sos_constraints, - condition=condition, - ) diff --git a/sumofsquares/init/initsosexpr.py b/sumofsquares/init/initsosexpr.py deleted file mode 100644 index 214bb0d..0000000 --- a/sumofsquares/init/initsosexpr.py +++ /dev/null @@ -1,85 +0,0 @@ -import polymatrix -from sumofsquares.abc.sosexpr import SOSExpr - -from sumofsquares.impl.sosexprimpl import ParamSOSExprImpl, SOSExprImpl -from sumofsquares.mixins.sosexprmixin import SOSExprMixin -from sumofsquares.sosexprbase.init.initsosexprbase import init_param_sos_expr_base, init_sos_expr_base -from sumofsquares.sosexprbase.mixins.parametermixin import ParameterMixin - - -def init_sos_expr( - expr: polymatrix.Expression, - variables: polymatrix.Expression, - dependence: tuple[ParameterMixin], -): - return SOSExprImpl( - underlying=init_sos_expr_base( - expr=expr, - variables=variables, - dependence=dependence, - ), - ) - - -def init_param_expr( - name: str, - variables: polymatrix.Expression, - monom: polymatrix.Expression | None = None, - n_row: int | None = None, - n_col: int | None = None, -): - return ParamSOSExprImpl( - underlying=init_param_sos_expr_base( - name=name, - monom=monom, - variables=variables, - n_row=n_row, - n_col=n_col, - ), - ) - - -def init_param_expr_from_reference( - name: str, - reference: SOSExpr, - # variables: polymatrix.Expression, - multiplicand: SOSExpr | polymatrix.Expression | None = None, -): - variables = reference.variables - - if multiplicand is None: - multiplicand_expr = polymatrix.from_(1) - - elif isinstance(multiplicand, polymatrix.Expression): - multiplicand_expr = multiplicand - - elif isinstance(multiplicand, SOSExprMixin): - assert multiplicand.variables == variables, f'{multiplicand.variables=}, {variables=}' - - multiplicand_expr = multiplicand.expr - - else: - multiplicand_expr = polymatrix.from_(multiplicand) - - m_sos_monom = multiplicand_expr.quadratic_monomials(variables) - - max_degree = m_sos_monom.max_degree().T.max() - - m_max_monom = m_sos_monom.filter( - m_sos_monom.max_degree() - max_degree, - inverse=True, - ) - - sos_monom = reference.expr.quadratic_monomials(variables).subtract_monomials(m_max_monom) - - expr = (sos_monom @ sos_monom.T).reshape(1, -1).sum() - - monom = expr.linear_monomials(variables).cache() - - return init_param_expr( - name=name, - monom=monom, - variables=variables, - ) - - diff --git a/sumofsquares/mixins/energyfunction2mixin.py b/sumofsquares/mixins/energyfunction2mixin.py deleted file mode 100644 index f96abb6..0000000 --- a/sumofsquares/mixins/energyfunction2mixin.py +++ /dev/null @@ -1,53 +0,0 @@ -import abc -import polymatrix - -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr -from sumofsquares.mixins.getsosconstraintmixin import GetSOSConstraintMixin -from sumofsquares.sosconstraint.abc import SOSConstraint - - -class EnergyFunction2Mixin(GetSOSConstraintMixin, abc.ABC): - @property - @abc.abstractmethod - def name(self) -> str: - ... - - @property - @abc.abstractmethod - def h(self) -> SOSExpr: - ... - - @property - @abc.abstractmethod - def h_dot(self) -> SOSExpr: - ... - - # @property - # @abc.abstractmethod - # def variables(self) -> polymatrix.Expression: - # ... - - @property - @abc.abstractmethod - def epsilon(self) -> ParamSOSExpr: - ... - - @property - @abc.abstractmethod - def gamma_b(self) -> ParamSOSExpr: - ... - - @property - @abc.abstractmethod - def gamma_roi(self) -> list[ParamSOSExpr]: - ... - - # @property - # @abc.abstractmethod - # def gamma_w_outer(self) -> ParamSOSExpr | None: - # ... - - # @property - # @abc.abstractmethod - # def gamma_w_inner(self) -> ParamSOSExpr | None: - # ... diff --git a/sumofsquares/mixins/energyfunctionmixin.py b/sumofsquares/mixins/energyfunctionmixin.py deleted file mode 100644 index f73f225..0000000 --- a/sumofsquares/mixins/energyfunctionmixin.py +++ /dev/null @@ -1,53 +0,0 @@ -import abc -import polymatrix - -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr -from sumofsquares.mixins.getsosconstraintmixin import GetSOSConstraintMixin -from sumofsquares.sosconstraint.abc import SOSConstraint - - -class EnergyFunctionMixin(GetSOSConstraintMixin, abc.ABC): - @property - @abc.abstractmethod - def name(self) -> str: - ... - - @property - @abc.abstractmethod - def h(self) -> SOSExpr: - ... - - @property - @abc.abstractmethod - def h_dot(self) -> SOSExpr: - ... - - # @property - # @abc.abstractmethod - # def variables(self) -> polymatrix.Expression: - # ... - - @property - @abc.abstractmethod - def epsilon(self) -> ParamSOSExpr: - ... - - @property - @abc.abstractmethod - def gamma_b(self) -> ParamSOSExpr: - ... - - @property - @abc.abstractmethod - def gamma_roi(self) -> ParamSOSExpr | None: - ... - - @property - @abc.abstractmethod - def gamma_w_outer(self) -> ParamSOSExpr | None: - ... - - @property - @abc.abstractmethod - def gamma_w_inner(self) -> ParamSOSExpr | None: - ... diff --git a/sumofsquares/mixins/interiorconstraintmixin.py b/sumofsquares/mixins/interiorconstraintmixin.py deleted file mode 100644 index 781a3d4..0000000 --- a/sumofsquares/mixins/interiorconstraintmixin.py +++ /dev/null @@ -1,21 +0,0 @@ -import abc - -from sumofsquares.abc.sosexpr import ParamSOSExpr -from sumofsquares.mixins.getsosconstraintmixin import GetSOSConstraintMixin - - -class InteriorConstraintMixin(GetSOSConstraintMixin, abc.ABC): - @property - @abc.abstractmethod - def name(self) -> str: - ... - - # @property - # @abc.abstractmethod - # def h(self) -> SOSExpr: - # ... - - @property - @abc.abstractmethod - def gamma(self) -> ParamSOSExpr | None: - ... diff --git a/sumofsquares/mixins/putinarepsilonmixin.py b/sumofsquares/mixins/putinarepsilonmixin.py index 6c1cd53..7f08f18 100644 --- a/sumofsquares/mixins/putinarepsilonmixin.py +++ b/sumofsquares/mixins/putinarepsilonmixin.py @@ -1,7 +1,7 @@ import abc import polymatrix -from sumofsquares.abc.sosexpr import ParamSOSExpr, SOSExpr +from sumofsquares.abc import ParamSOSExpr, SOSExpr from sumofsquares.mixins.getsosconstraintmixin import GetSOSConstraintMixin from sumofsquares.sosconstraint.abc import SOSConstraint diff --git a/sumofsquares/mixins/sosexprmixin.py b/sumofsquares/mixins/sosexprmixin.py index f3d4dc9..ed3fa65 100644 --- a/sumofsquares/mixins/sosexprmixin.py +++ b/sumofsquares/mixins/sosexprmixin.py @@ -2,7 +2,7 @@ import abc import polymatrix from sumofsquares.sosconstraint.abc import SOSConstraint -from sumofsquares.sosconstraint.initsosconstraint import init_sos_constraint +from sumofsquares.sosconstraint.init import init_sos_constraint from sumofsquares.mixins.getsosconstraintmixin import GetSOSConstraintMixin from sumofsquares.sosexprbase.abc import SOSExprBase diff --git a/sumofsquares/mixins/sosexpropmixin.py b/sumofsquares/mixins/sosexpropmixin.py index ce75bbc..bce2a02 100644 --- a/sumofsquares/mixins/sosexpropmixin.py +++ b/sumofsquares/mixins/sosexpropmixin.py @@ -5,7 +5,7 @@ import polymatrix import polymatrix.expression.from_ from sumofsquares.mixins.sosexprmixin import SOSExprMixin -from sumofsquares.sosexprbase.init.initsosexprbase import init_sos_expr_base +from sumofsquares.sosexprbase.init import init_sos_expr_base class SOSExprOPMixin(SOSExprMixin): diff --git a/sumofsquares/sosconstraint/abc.py b/sumofsquares/sosconstraint/abc.py index 5ce0b47..1894b94 100644 --- a/sumofsquares/sosconstraint/abc.py +++ b/sumofsquares/sosconstraint/abc.py @@ -1,4 +1,4 @@ -from sumofsquares.sosconstraint.sosconstraintmixin import SOSConstraintMixin +from sumofsquares.sosconstraint.mixins import SOSConstraintMixin class SOSConstraint(SOSConstraintMixin): diff --git a/sumofsquares/sosconstraint/init.py b/sumofsquares/sosconstraint/init.py new file mode 100644 index 0000000..68a2f25 --- /dev/null +++ b/sumofsquares/sosconstraint/init.py @@ -0,0 +1,14 @@ +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/initsosconstraint.py b/sumofsquares/sosconstraint/initsosconstraint.py deleted file mode 100644 index 68a2f25..0000000 --- a/sumofsquares/sosconstraint/initsosconstraint.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 new file mode 100644 index 0000000..be49620 --- /dev/null +++ b/sumofsquares/sosconstraint/mixins.py @@ -0,0 +1,16 @@ +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/sosconstraint/sosconstraintmixin.py b/sumofsquares/sosconstraint/sosconstraintmixin.py deleted file mode 100644 index be49620..0000000 --- a/sumofsquares/sosconstraint/sosconstraintmixin.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/sosexprbase/abc.py b/sumofsquares/sosexprbase/abc.py index c979919..e6b6d89 100644 --- a/sumofsquares/sosexprbase/abc.py +++ b/sumofsquares/sosexprbase/abc.py @@ -1,4 +1,5 @@ import abc + from sumofsquares.sosexprbase.mixins.selfdependencemixin import SelfDependenceMixin from sumofsquares.sosexprbase.mixins.sosexprbasemixin import SOSExprBaseMixin from sumofsquares.sosexprbase.mixins.exprfrommonommixin import ExprFromMonomMixin diff --git a/sumofsquares/sosexprbase/init.py b/sumofsquares/sosexprbase/init.py new file mode 100644 index 0000000..f8f97fd --- /dev/null +++ b/sumofsquares/sosexprbase/init.py @@ -0,0 +1,64 @@ +import polymatrix + +from sumofsquares.sosexprbase.impl import ParamSOSExprBaseImpl, SOSExprBaseImpl +from sumofsquares.sosexprbase.mixins.parametermixin import ParameterMixin + + +def init_sos_expr_base( + expr: polymatrix.Expression, + variables: polymatrix.Expression, + dependence: tuple[ParameterMixin] | None = None, +): + + if not isinstance(expr, polymatrix.Expression): + expr = polymatrix.from_(expr) + + # if variables is None: + # variables = polymatrix.from_(1) + + if dependence is None: + dependence = tuple() + + return SOSExprBaseImpl( + expr=expr, + variables=variables, + dependence=dependence, + ) + + +def init_param_sos_expr_base( + name: str, + variables: polymatrix.Expression, + monom: polymatrix.Expression | None = None, + n_row: int | None = None, + n_col: int | None = None, +): + if monom is None: + monom = polymatrix.from_(1) + + if n_row == None: + n_row = 1 + + if n_col == None: + n_col = 1 + + if n_row == 1 and n_col == 1: + param = monom.parametrize(f'{name}') + param_matrix = param.T + + else: + param = monom.rep_mat(n_col * n_row, 1).parametrize(f'{name}') + param_matrix = param.reshape(monom, -1).T + + # params = tuple(monom.parametrize(f'{name}_{row+1}_{col+1}') for col in range(n_col) for row in range(n_row)) + # param = polymatrix.v_stack(params) + # param_matrix = polymatrix.v_stack(tuple(param.T for param in params)) + + return ParamSOSExprBaseImpl( + name=name, + param=param, + monom=monom, + variables=variables, + param_matrix=param_matrix, + n_row=n_row, + ) diff --git a/sumofsquares/sosexprbase/init/initsosexprbase.py b/sumofsquares/sosexprbase/init/initsosexprbase.py deleted file mode 100644 index f8f97fd..0000000 --- a/sumofsquares/sosexprbase/init/initsosexprbase.py +++ /dev/null @@ -1,64 +0,0 @@ -import polymatrix - -from sumofsquares.sosexprbase.impl import ParamSOSExprBaseImpl, SOSExprBaseImpl -from sumofsquares.sosexprbase.mixins.parametermixin import ParameterMixin - - -def init_sos_expr_base( - expr: polymatrix.Expression, - variables: polymatrix.Expression, - dependence: tuple[ParameterMixin] | None = None, -): - - if not isinstance(expr, polymatrix.Expression): - expr = polymatrix.from_(expr) - - # if variables is None: - # variables = polymatrix.from_(1) - - if dependence is None: - dependence = tuple() - - return SOSExprBaseImpl( - expr=expr, - variables=variables, - dependence=dependence, - ) - - -def init_param_sos_expr_base( - name: str, - variables: polymatrix.Expression, - monom: polymatrix.Expression | None = None, - n_row: int | None = None, - n_col: int | None = None, -): - if monom is None: - monom = polymatrix.from_(1) - - if n_row == None: - n_row = 1 - - if n_col == None: - n_col = 1 - - if n_row == 1 and n_col == 1: - param = monom.parametrize(f'{name}') - param_matrix = param.T - - else: - param = monom.rep_mat(n_col * n_row, 1).parametrize(f'{name}') - param_matrix = param.reshape(monom, -1).T - - # params = tuple(monom.parametrize(f'{name}_{row+1}_{col+1}') for col in range(n_col) for row in range(n_row)) - # param = polymatrix.v_stack(params) - # param_matrix = polymatrix.v_stack(tuple(param.T for param in params)) - - return ParamSOSExprBaseImpl( - name=name, - param=param, - monom=monom, - variables=variables, - param_matrix=param_matrix, - n_row=n_row, - ) diff --git a/sumofsquares/sosexprbase/mixins/parametermixin.py b/sumofsquares/sosexprbase/mixins/parametermixin.py index 3df6ab4..61755a5 100644 --- a/sumofsquares/sosexprbase/mixins/parametermixin.py +++ b/sumofsquares/sosexprbase/mixins/parametermixin.py @@ -3,6 +3,10 @@ import polymatrix class ParameterMixin(abc.ABC): + """ + + """ + @property @abc.abstractmethod def name(self) -> str: -- cgit v1.2.1