Ejemplo n.º 1
0
 def load_init_state_nmpc(self, src_kind, **kwargs):
     """Loads ref state for set-point
     Args:
         src_kind (str): the kind of source
         **kwargs: Arbitrary keyword arguments.
     Returns:
         None
     Keyword Args:
         src_kind (str) : if == mod use reference model, otw use the internal dictionary
         ref (pyomo.core.base.PyomoModel.ConcreteModel): The reference model (default PlantPred)
         fe (int): The required finite element
         cp (int): The required collocation point
     """
     # src_kind = kwargs.pop("src_kind", "mod")
     self.journalist("I", self._iteration_count, "load_init_state_nmpc", "Load State to nmpc src_kind=" + src_kind)
     ref = kwargs.pop("ref", None)
     fe = kwargs.pop("fe", self.nfe_tnmpc)
     cp = kwargs.pop("cp", self.ncp_tnmpc)
     if src_kind == "mod":
         if not ref:
             self.journalist("W", self._iteration_count, "load_init_state_nmpc", "No model was given")
             self.journalist("W", self._iteration_count, "load_init_state_nmpc", "No update on state performed")
             sys.exit()
         for x in self.states:
             xic = getattr(self.olnmpc, x + "_ic")
             xvar = getattr(self.olnmpc, x)
             xsrc = getattr(ref, x)
             for j in self.state_vars[x]:
                 xic[j].value = value(xsrc[(fe, cp) + j])
                 xvar[(0, 0) + j].set_value(value(xsrc[(fe, cp) + j]))
     else:
         state_dict = kwargs.pop("state_dict", None)
         if state_dict == "real":  #: Load from the real state dict
             for x in self.states:
                 xic = getattr(self.olnmpc, x + "_ic")
                 xvar = getattr(self.olnmpc, x)
                 for j in self.state_vars[x]:
                     xic[j].value = self.curr_rstate[(x, j)]
                     xvar[(0, 0) + j].set_value(self.curr_rstate[(x, j)])
         elif state_dict == "estimated":  #: Load from the estimated state dict
             for x in self.states:
                 xic = getattr(self.olnmpc, x + "_ic")
                 xvar = getattr(self.olnmpc, x)
                 for j in self.state_vars[x]:
                     xic[j].value = self.curr_estate[(x, j)]
                     xvar[(0, 0) + j].set_value(self.curr_estate[(x, j)])
         elif state_dict == "predicted":  #: Load from the estimated state dict
             for x in self.states:
                 xic = getattr(self.olnmpc, x + "_ic")
                 xvar = getattr(self.olnmpc, x)
                 for j in self.state_vars[x]:
                     try:
                         xic[j].value = self.curr_pstate[(x, j)]
                     except KeyError:
                         print(self.curr_pstate)
                     xvar[(0, 0) + j].set_value(self.curr_pstate[(x, j)])
         else:
             self.journalist("W", self._iteration_count, "load_init_state_nmpc", "No dict w/state was specified")
             self.journalist("W", self._iteration_count, "load_init_state_nmpc", "No update on state performed")
             raise ValueError("Unexpeted state_dict %s" % state_dict)
Ejemplo n.º 2
0
def _build_equality_set(m):
    """Construct an equality set map.

    Maps all variables to the set of variables that are linked to them by
    equality. Mapping takes place using id(). That is, if you have x = y, then
    you would have id(x) -> ComponentSet([x, y]) and id(y) -> ComponentSet([x,
    y]) in the mapping.

    """
    #: dict: map of var UID to the set of all equality-linked var UIDs
    eq_var_map = ComponentMap()
    relevant_vars = ComponentSet()
    for constr in m.component_data_objects(ctype=Constraint,
                                           active=True,
                                           descend_into=True):
        # Check to make sure the constraint is of form v1 - v2 == 0
        if (value(constr.lower) == 0 and value(constr.upper) == 0
                and constr.body.polynomial_degree() == 1):
            repn = generate_canonical_repn(constr.body)
            # only take the variables with nonzero coefficients
            vars_ = [v for i, v in enumerate(repn.variables) if repn.linear[i]]
            if (len(vars_) == 2
                    and sorted(l for l in repn.linear if l) == [-1, 1]):
                # this is an a == b constraint.
                v1 = vars_[0]
                v2 = vars_[1]
                set1 = eq_var_map.get(v1, ComponentSet([v1]))
                set2 = eq_var_map.get(v2, ComponentSet([v2]))
                relevant_vars.update([v1, v2])
                set1.update(set2)  # set1 is now the union
                for v in set1:
                    eq_var_map[v] = set1

    return eq_var_map, relevant_vars
Ejemplo n.º 3
0
    def update_var(self, var):
        """
        Update a variable in the solver's model. This will update bounds, fix/unfix the variable as needed, and update
        the variable type.

        Parameters
        ----------
        var: Var
        """
        if var.is_indexed():
            for child_var in var.values():
                self.compile_var(child_var)
            return
        if var not in self._pyomo_var_to_solver_var_map:
            raise ValueError('The Var provided to compile_var needs to be added first: {0}'.format(var))
        cplex_var = self._pyomo_var_to_solver_var_map[var]
        vtype = self._cplex_vtype_from_var(var)
        if var.is_fixed():
            lb = var.value
            ub = var.value
        else:
            lb = -self._cplex.infinity
            ub = self._cplex.infinity
            if var.has_lb():
                lb = value(var.lb)
            if var.has_ub():
                ub = value(var.ub)
        self._solver_model.variables.set_lower_bounds(cplex_var, lb)
        self._solver_model.variables.set_upper_bounds(cplex_var, ub)
        self._solver_model.variables.set_types(cplex_var, vtype)
Ejemplo n.º 4
0
    def cycle_ics(self, curr_fe):
        """Cycles the initial conditions of the initializing model.
        Take the values of states (initializing model) at t=last and patch them into t=0.
        Check:
        https://github.com/dthierry/cappresse/blob/pyomodae-david/nmpc_mhe/aux/utils.py
        fe_cp function!
        """
        
        #For checking whether jump happens in right element:
        #print('*'* 20)
        #print("Current Finite element [cycle_ics]{}".format(curr_fe)) #comment out these lines?
        #print('*' * 20)

        ts = getattr(self.mod, self.time_set)
        t_last = t_ij(ts, 0, self.ncp)
        
        #Inclusion of discrete jumps: (CS)
        ttgt = getattr(self.tgt, self.time_set)

        for i in self.dvs_names:
            dv = getattr(self.mod, i)
            for s in self.remaining_set[i]:
                if s is None:
                    val = value(dv[t_last])
                    dv[0].set_value(val)
                    if not dv[0].fixed:
                        dv[0].fix()
                    continue
                for k in s:
                    k = k if isinstance(k, tuple) else (k,)
                    val = value(dv[(t_last,) + k])
                    dv[(0,) + k].set_value(val)
                    if not dv[(0,) + k].fixed:
                        dv[(0,) + k].fix()
Ejemplo n.º 5
0
    def update_var(self, var):
        """
        Update a variable in the solver's model. This will update bounds, fix/unfix the variable as needed, and update
        the variable type.

        Parameters
        ----------
        var: Var
        """
        if var.is_indexed():
            for child_var in var.values():
                self.update_var(child_var)
            return
        if var not in self._pyomo_var_to_solver_var_map:
            raise ValueError(
                'The Var provided to update_var needs to be added first: {0}'.
                format(var))
        gurobipy_var = self._pyomo_var_to_solver_var_map[var]
        vtype = self._gurobi_vtype_from_var(var)
        if var.is_fixed():
            lb = var.value
            ub = var.value
        else:
            lb = -self._gurobipy.GRB.INFINITY
            ub = self._gurobipy.GRB.INFINITY
            if var.has_lb():
                lb = value(var.lb)
            if var.has_ub():
                ub = value(var.ub)
        gurobipy_var.setAttr('lb', lb)
        gurobipy_var.setAttr('ub', ub)
        gurobipy_var.setAttr('vtype', vtype)
Ejemplo n.º 6
0
    def _add_var(self, var):
        varname = self._symbol_map.getSymbol(var, self._labeler)
        vtype = self._cplex_vtype_from_var(var)
        if var.has_lb():
            lb = value(var.lb)
        else:
            lb = -self._cplex.infinity
        if var.has_ub():
            ub = value(var.ub)
        else:
            ub = self._cplex.infinity

        self._solver_model.variables.add(lb=[lb],
                                         ub=[ub],
                                         types=[vtype],
                                         names=[varname])

        self._pyomo_var_to_solver_var_map[var] = varname
        self._solver_var_to_pyomo_var_map[varname] = var
        self._pyomo_var_to_ndx_map[var] = self._ndx_count
        self._ndx_count += 1
        self._referenced_variables[var] = 0

        if var.is_fixed():
            self._solver_model.variables.set_lower_bounds(varname, var.value)
            self._solver_model.variables.set_upper_bounds(varname, var.value)
Ejemplo n.º 7
0
    def test_pickle(self):
        v = variable()
        e = noclone(v)
        self.assertEqual(type(e), noclone)
        self.assertIs(type(e.expr), variable)
        eup = pickle.loads(pickle.dumps(e))
        self.assertEqual(type(eup), noclone)
        self.assertTrue(e is not eup)
        self.assertIs(type(eup.expr), variable)
        self.assertIs(type(e.expr), variable)
        self.assertTrue(eup.expr is not e.expr)

        del e
        del v

        v = variable(value=1)
        b = block()
        b.v = v
        eraw = b.v + 1
        b.e = 1 + noclone(eraw)
        bup = pickle.loads(pickle.dumps(b))
        self.assertTrue(isinstance(bup.e, NumericValue))
        self.assertEqual(value(bup.e), 3.0)
        b.v.value = 2
        self.assertEqual(value(b.e), 4.0)
        self.assertEqual(value(bup.e), 3.0)
        bup.v.value = -1
        self.assertEqual(value(b.e), 4.0)
        self.assertEqual(value(bup.e), 1.0)

        self.assertIs(b.v.parent, b)
        self.assertIs(bup.v.parent, bup)

        del b.v
Ejemplo n.º 8
0
    def update_var(self, var):
        """Update a single variable in the solver's model.

        This will update bounds, fix/unfix the variable as needed, and
        update the variable type.

        Parameters
        ----------
        var: Var (scalar Var or single _VarData)

        """
        # see PR #366 for discussion about handling indexed
        # objects and keeping compatibility with the
        # pyomo.kernel objects
        #if var.is_indexed():
        #    for child_var in var.values():
        #        self.update_var(child_var)
        #    return
        if var not in self._pyomo_var_to_solver_var_map:
            raise ValueError('The Var provided to update_var needs to be added first: {0}'.format(var))
        gurobipy_var = self._pyomo_var_to_solver_var_map[var]
        vtype = self._gurobi_vtype_from_var(var)
        if var.is_fixed():
            lb = var.value
            ub = var.value
        else:
            lb = -self._gurobipy.GRB.INFINITY
            ub = self._gurobipy.GRB.INFINITY
            if var.has_lb():
                lb = value(var.lb)
            if var.has_ub():
                ub = value(var.ub)
        gurobipy_var.setAttr('lb', lb)
        gurobipy_var.setAttr('ub', ub)
        gurobipy_var.setAttr('vtype', vtype)
Ejemplo n.º 9
0
 def update_targets_nmpc(self):
     """Use the reference model to update  the current state and control targets dictionaries"""
     for x in self.states:
         xvar = getattr(self.SteadyRef2, x)
         for j in self.state_vars[x]:
             self.curr_state_target[(x, j)] = value(xvar[0, 1, j])
     for u in self.u:
         uvar = getattr(self.SteadyRef2, u)
         self.curr_u_target[u] = value(uvar[0])
Ejemplo n.º 10
0
    def _apply_to(self, instance, tmp=False):
        """Apply the transformation.

        Args:
            instance (Block): the block on which to search for x == y
                constraints. Note that variables may be located anywhere in
                the model.
            tmp (bool, optional): Whether the bound modifications will be
                temporary

        Returns:
            None

        """
        if tmp and not hasattr(instance, '_tmp_propagate_original_bounds'):
            instance._tmp_propagate_original_bounds = Suffix(
                direction=Suffix.LOCAL)
        eq_var_map, relevant_vars = _build_equality_set(instance)
        processed = ComponentSet()
        # Go through each variable in an equality set to propagate the variable
        # bounds to all equality-linked variables.
        for var in relevant_vars:
            # If we have already processed the variable, skip it.
            if var in processed:
                continue

            var_equality_set = eq_var_map.get(var, ComponentSet([var]))

            #: variable lower bounds in the equality set
            lbs = [v.lb for v in var_equality_set if v.has_lb()]
            max_lb = max(lbs) if len(lbs) > 0 else None
            #: variable upper bounds in the equality set
            ubs = [v.ub for v in var_equality_set if v.has_ub()]
            min_ub = min(ubs) if len(ubs) > 0 else None

            # Check  for error due to bound cross-over
            if max_lb is not None and min_ub is not None and max_lb > min_ub:
                # the lower bound is above the upper bound. Raise a ValueError.
                # get variable with the highest lower bound
                v1 = next(v for v in var_equality_set if v.lb == max_lb)
                # get variable with the lowest upper bound
                v2 = next(v for v in var_equality_set if v.ub == min_ub)
                raise ValueError(
                    'Variable {} has a lower bound {} '
                    ' > the upper bound {} of variable {}, '
                    'but they are linked by equality constraints.'.format(
                        v1.name, value(v1.lb), value(v2.ub), v2.name))

            for v in var_equality_set:
                if tmp:
                    # TODO warn if overwriting
                    instance._tmp_propagate_original_bounds[v] = (v.lb, v.ub)
                v.setlb(max_lb)
                v.setub(min_ub)

            processed.update(var_equality_set)
Ejemplo n.º 11
0
def main():
    ipopt = SolverFactory('ipopt')
    ipopt.solve(model, tee=True)
    for key in model.X.keys():
        print('X[{}]=\t{}'.format(key, value(model.X[key])))
    for key in model.P.keys():
        print('P[{}]=\t{}'.format(key, value(model.P[key])))
    for key in model.Z.keys():
        print('Z[{}]=\t{}'.format(key, value(model.Z[key])))
    print('OILPUR =\t{}'.format(value(model.OILPUR)))
Ejemplo n.º 12
0
 def is_binary(self):
     """Returns :const:`True` when the domain type is
     :class:`IntegerSet` and the bounds are within
     [0,1]."""
     lb, ub = self.bounds
     return self.is_integer() and \
         (lb is not None) and \
         (ub is not None) and \
         (value(lb) >= 0) and \
         (value(ub) <= 1)
Ejemplo n.º 13
0
    def _apply_to(self, model):
        """Apply the transformation to the given model."""
        m = model

        for constr in m.component_data_objects(ctype=Constraint,
                                               active=True,
                                               descend_into=True):
            # Check if the constraint is k * x + c1 <= c2 or c2 <= k * x + c1
            if constr.body.polynomial_degree() == 1:
                repn = generate_canonical_repn(constr.body)
                if repn.variables is not None and len(repn.variables) == 1:
                    var = repn.variables[0]
                    const = repn.constant if repn.constant is not None else 0
                    coef = float(repn.linear[0])
                    if coef == 0:
                        # This can happen when a one element of a bilinear term
                        # is fixed to zero. Obviously, do not divide by zero.
                        pass
                    else:
                        if constr.upper is not None:
                            newbound = (value(constr.upper) - const) / coef
                            if coef > 0:
                                var.setub(
                                    min(var.ub, newbound) if var.
                                    ub is not None else newbound)
                            elif coef < 0:
                                var.setlb(
                                    max(var.lb, newbound) if var.
                                    lb is not None else newbound)
                        if constr.lower is not None:
                            newbound = (value(constr.lower) - const) / coef
                            if coef > 0:
                                var.setlb(
                                    max(var.lb, newbound) if var.
                                    lb is not None else newbound)
                            elif coef < 0:
                                var.setub(
                                    min(var.ub, newbound) if var.
                                    ub is not None else newbound)
                    constr.deactivate()
                    # Sometimes deactivating the constraint will remove a
                    # variable from all active constraints, so that it won't be
                    # updated during the optimization. Therefore, we need to
                    # shift the value of var as necessary in order to keep it
                    # within its implied bounds, as the constraint we are
                    # deactivating is not an invalid constraint, but rather we
                    # are moving its implied bound directly onto the variable.
                    if (var.has_lb() and var.value is not None
                            and var.value < var.lb):
                        var.set_value(var.lb)
                    if (var.has_ub() and var.value is not None
                            and var.value > var.ub):
                        var.set_value(var.ub)
Ejemplo n.º 14
0
 def compute_QR_nmpc(self, src="plant", n=-1, **kwargs):
     """Using the current state & control targets, computes the Qk and Rk matrices (diagonal)
     Strategy: take the inverse of the absolute difference between reference and current state such that every
     offset in the objective is normalized or at least dimensionless
     Args:
         src (str): The source of the update (default mhe) (mhe or plant)
         n (int): The exponent of the weight"""
     check_values = kwargs.pop("check_values", False)
     if check_values:
         max_w_value = kwargs.pop("max_w_value", 1e+06)
         min_w_value = kwargs.pop("min_w_value", 0.0)
     self.update_targets_nmpc()
     if src == "mhe":
         for x in self.states:
             for j in self.state_vars[x]:
                 k = self.xmpc_key[(x, j)]
                 temp = abs(self.curr_estate[(x, j)] - self.curr_state_target[(x, j)])
                 if temp > 1e-08:
                     self.olnmpc.Q_nmpc[k].value = temp**n
                 else:
                     self.olnmpc.Q_nmpc[k].value = max_w_value
                 self.olnmpc.xmpc_ref_nmpc[k].value = self.curr_state_target[(x, j)]
     elif src == "plant":
         for x in self.states:
             for j in self.state_vars[x]:
                 k = self.xmpc_key[(x, j)]
                 # self.olnmpc.Q_nmpc[k].value = abs(self.curr_rstate[(x, j)] - self.curr_state_target[(x, j)])**n
                 temp = abs(self.curr_rstate[(x, j)] - self.curr_state_target[(x, j)])
                 if temp > 1e-08:
                     self.olnmpc.Q_nmpc[k].value = temp ** n
                 else:
                     self.olnmpc.Q_nmpc[k].value = max_w_value
                 self.olnmpc.xmpc_ref_nmpc[k].value = self.curr_state_target[(x, j)]
     k = 0
     for u in self.u:
         self.olnmpc.R_nmpc[k].value = abs(self.curr_u[u] - self.curr_u_target[u])**n
         self.olnmpc.umpc_ref_nmpc[k].value = self.curr_u_target[u]
         k += 1
     if check_values:
         for k in self.olnmpc.xmpcS_nmpc:
             if value(self.olnmpc.Q_nmpc[k]) < min_w_value:
                 self.olnmpc.Q_nmpc[k].value = min_w_value
             if value(self.olnmpc.Q_nmpc[k]) > max_w_value:
                 self.olnmpc.Q_nmpc[k].value = max_w_value
         k = 0
         for u in self.u:
             if value(self.olnmpc.R_nmpc[k]) < min_w_value:
                 self.olnmpc.R_nmpc[k].value = min_w_value
             if value(self.olnmpc.R_nmpc[k]) > max_w_value:
                 self.olnmpc.R_nmpc[k].value = max_w_value
             k += 1
Ejemplo n.º 15
0
    def _apply_to(self, instance):
        """Apply the transformation.

        Args:
            instance (Block): the block on which to search for x == sum(var)
                constraints. Note that variables may be located anywhere in
                the model.

        Returns:
            None

        """
        for constr in instance.component_data_objects(ctype=Constraint,
                                                      active=True,
                                                      descend_into=True):
            if not constr.body.polynomial_degree() == 1:
                continue  # constraint not linear. Skip.

            repn = generate_canonical_repn(constr.body)
            if (constr.has_ub() and (
                (repn.constant is None and value(constr.upper) == 0) or
                repn.constant == value(constr.upper)
                    )):
                # term1 + term2 + term3 + ... <= 0
                # all var terms need to be non-negative
                if all(
                    # variable has 0 coefficient
                    coef == 0 or
                    # variable is non-negative and has non-negative coefficient
                    (repn.variables[i].has_lb() and
                     value(repn.variables[i].lb) >= 0 and
                     coef >= 0) or
                    # variable is non-positive and has non-positive coefficient
                    (repn.variables[i].has_ub() and
                     value(repn.variables[i].ub) <= 0 and
                     coef <= 0) for i, coef in enumerate(repn.linear)):
                    for i, coef in enumerate(repn.linear):
                        if not coef == 0:
                            repn.variables[i].fix(0)
                    continue
            if (constr.has_lb() and (
                (repn.constant is None and value(constr.lower) == 0) or
                repn.constant == value(constr.lower)
                    )):
                # term1 + term2 + term3 + ... >= 0
                # all var terms need to be non-positive
                if all(
                    # variable has 0 coefficient
                    coef == 0 or
                    # variable is non-negative and has non-positive coefficient
                    (repn.variables[i].has_lb() and
                     value(repn.variables[i].lb) >= 0 and
                     coef <= 0) or
                    # variable is non-positive and has non-negative coefficient
                    (repn.variables[i].has_ub() and
                     value(repn.variables[i].ub) <= 0 and
                     coef >= 0) for i, coef in enumerate(repn.linear)):
                    for i, coef in enumerate(repn.linear):
                        if not coef == 0:
                            repn.variables[i].fix(0)
Ejemplo n.º 16
0
    def _apply_to(self, instance, tmp=False):
        """Apply the transformation.

        Args:
            instance (Block): the block on which to search for x == y
                constraints. Note that variables may be located anywhere in
                the model.
            tmp (bool, optional): Whether the variable fixing will be temporary

        Returns:
            None

        Raises:
            ValueError: if two fixed variables x = y have different values.

        """
        if tmp and not hasattr(instance, '_tmp_propagate_fixed'):
            instance._tmp_propagate_fixed = ComponentSet()
        eq_var_map, relevant_vars = _build_equality_set(instance)
        #: ComponentSet: The set of all fixed variables
        fixed_vars = ComponentSet((v for v in relevant_vars if v.fixed))
        newly_fixed = _detect_fixed_variables(instance)
        if tmp:
            instance._tmp_propagate_fixed.update(newly_fixed)
        fixed_vars.update(newly_fixed)
        processed = ComponentSet()
        # Go through each fixed variable to propagate the 'fixed' status to all
        # equality-linked variabes.
        for v1 in fixed_vars:
            # If we have already processed the variable, skip it.
            if v1 in processed:
                continue

            eq_set = eq_var_map.get(v1, ComponentSet([v1]))
            for v2 in eq_set:
                if (v2.fixed and value(v1) != value(v2)):
                    raise ValueError(
                        'Variables {} and {} have conflicting fixed '
                        'values of {} and {}, but are linked by '
                        'equality constraints.'.format(v1.name, v2.name,
                                                       value(v1), value(v2)))
                elif not v2.fixed:
                    v2.fix(value(v1))
                    if tmp:
                        instance._tmp_propagate_fixed.add(v2)
            # Add all variables in the equality set to the set of processed
            # variables.
            processed.update(eq_set)
    def _apply_to(self, instance, **kwargs):
        """Apply the transformation.

        Args:
            instance: Pyomo model object to transform.

        Kwargs:
            tmp: True to store a set of transformed constraints for future
                reversion of the transformation
            ignore_infeasible: True to skip over trivial constraints that are
                infeasible instead of raising a ValueError.
            tol: tolerance on constraint violations
        """
        tmp = kwargs.pop('tmp', False)
        ignore_infeasible = kwargs.pop('ignore_infeasible', False)
        tol = kwargs.pop('tolerance', 1E-13)
        if tmp and not hasattr(instance, '_tmp_trivial_deactivated_constrs'):
            instance._tmp_trivial_deactivated_constrs = ComponentSet()

        # Trivial constraints are those that do not contain any variables, ie.
        # the polynomial degree is 0
        trivial_constraints = (c for c in instance.component_data_objects(
            ctype=Constraint, active=True, descend_into=True)
                               if c.body.polynomial_degree() == 0)

        for constr in trivial_constraints:
            # We need to check each constraint to sure that it is not violated.

            # Check if the lower bound is violated outside a given tolerance
            if (constr.has_lb()
                    and value(constr.body) + tol <= value(constr.lower)):
                # Trivial constraint is infeasible.
                if ignore_infeasible:
                    # do nothing, move on to next constraint
                    continue
                else:
                    raise ValueError(
                        'Trivial constraint {} violates LB {} ≤ BODY {}.'.
                        format(constr.name, value(constr.lower),
                               value(constr.body)))

            # Check if the upper bound is violated outside a given tolerance
            if (constr.has_ub()
                    and value(constr.body) >= value(constr.upper) + tol):
                # Trivial constraint is infeasible.
                if ignore_infeasible:
                    # do nothing, move on to next constraint
                    continue
                else:
                    raise ValueError(
                        'Trivial constraint {} violates BODY {} ≤ UB {}.'.
                        format(constr.name, value(constr.body),
                               value(constr.upper)))

            # Constraint is not infeasible. Deactivate it.
            if tmp:
                instance._tmp_trivial_deactivated_constrs.add(constr)
            constr.deactivate()
Ejemplo n.º 18
0
    def _transformDisjunctionData(self, disjunction):
        # the sum of all the indicator variable values of disjuncts in the
        # disjunction
        logical_sum = sum(
            value(disj.indicator_var) for disj in disjunction.disjuncts)

        # Check that the disjunctions are not being fixed to an infeasible
        # realization.
        if disjunction.xor and not logical_sum == 1:
            # for XOR disjunctions, the sum of all disjunct values should be 1
            raise GDP_Error(
                "Disjunction %s violated. "
                "Expected 1 disjunct to be active, but %s were active." %
                (disjunction.name, logical_sum))
        elif not logical_sum >= 1:
            # for non-XOR disjunctions, the sum of all disjunct values should
            # be at least 1
            raise GDP_Error("Disjunction %s violated. "
                            "Expected at least 1 disjunct to be active, "
                            "but none were active.")
        else:
            # disjunction is in feasible realization. Deactivate it.
            disjunction.deactivate()

        # Process the disjuncts associatd with the disjunction that have not
        # already been transformed.
        for disj in ComponentSet(
                disjunction.disjuncts) - self._transformedDisjuncts:
            self._transformDisjunctData(disj)
        # Update the set of transformed disjuncts with those from this
        # disjunction
        self._transformedDisjuncts.update(disjunction.disjuncts)
Ejemplo n.º 19
0
def _detect_fixed_variables(m):
    """Detect fixed variables due to constraints of form var = const."""
    new_fixed_vars = ComponentSet()
    for constr in m.component_data_objects(ctype=Constraint,
                                           active=True,
                                           descend_into=True):
        if constr.equality and constr.body.polynomial_degree() == 1:
            repn = generate_canonical_repn(constr.body)
            if len(repn.variables) == 1 and repn.linear[0]:
                var = repn.variables[0]
                coef = float(repn.linear[0])
                const = repn.constant if repn.constant is not None else 0
                var_val = (value(constr.lower) - value(const)) / coef
                var.fix(var_val)
                new_fixed_vars.add(var)
    return new_fixed_vars
Ejemplo n.º 20
0
    def _apply_to(self, instance, **kwargs):
        """Apply the transformation.

        Args:
            instance: Pyomo model object to transform.

        Kwargs:
            tmp: True to store the set of transformed variables and their old
                values so that they can be restored.
            tol: tolerance on bound equality (LB == UB)
        """
        tmp = kwargs.pop('tmp', False)
        tol = kwargs.pop('tolerance', 1E-13)

        if tmp:
            instance._xfrm_detect_fixed_vars_old_values = ComponentMap()

        for var in instance.component_data_objects(ctype=Var,
                                                   descend_into=True):
            if var.fixed or var.lb is None or var.ub is None:
                # if the variable is already fixed, or if it is missing a
                # bound, we skip it.
                continue
            if fabs(value(var.lb - var.ub)) <= tol:
                if tmp:
                    instance._xfrm_detect_fixed_vars_old_values[var] = \
                        var.value
                var.fix(var.lb)
Ejemplo n.º 21
0
 def __call__(self, exception=True):
     try:
         return sum(value(c, exception=exception) * \
                    v(exception=exception) for v,c in self.terms)
     except (ValueError, TypeError):
         if exception:
             raise ValueError("one or more terms " "could not be evaluated")
         return None
Ejemplo n.º 22
0
def log_close_to_bounds(m, tol=1E-6):
    """Print the variables and constraints that are near their bounds.

    Fixed variables and equality constraints are excluded from this analysis.

    Args:
        m (Block): Pyomo block or model to check
        tol (float): bound tolerance
    """
    for var in m.component_data_objects(
            ctype=Var, descend_into=True):
        if var.fixed:
            continue
        if (var.has_lb() and var.has_ub() and
                fabs(value(var.ub - var.lb)) <= 2 * tol):
            continue  # if the bounds are too close, skip.
        if var.has_lb() and fabs(value(var.lb - var)) <= tol:
            logger.info('{} near LB of {}'.format(var.name, value(var.lb)))
        elif var.has_ub() and fabs(value(var.ub - var)) <= tol:
            logger.info('{} near UB of {}'.format(var.name, value(var.ub)))

    for constr in m.component_data_objects(
            ctype=Constraint, descend_into=True, active=True):
        if not constr.equality:
            if (constr.has_ub() and
                    fabs(value(constr.body - constr.upper)) <= tol):
                logger.info('{} near UB'.format(constr.name))
            if (constr.has_lb() and
                    fabs(value(constr.body - constr.lower)) <= tol):
                logger.info('{} near LB'.format(constr.name))
Ejemplo n.º 23
0
    def validate(self,
                 equal_slopes_tolerance=1e-6):
        """
        Validate this piecewise linear function by verifying
        various properties of the breakpoints and values
        lists (e.g., that the list of breakpoints is
        nondecreasing).

        Args:
            equal_slopes_tolerance (float): Tolerance used
                check if consecutive slopes are nearly
                equal. If any are found, validation will
                fail. Default is 1e-6.

        Returns:
            int:
                a function characterization code (see \
                :func:`util.characterize_function`)

        Raises:
            PiecewiseValidationError: if validation fails
        """

        breakpoints = [value(x) for x in self._breakpoints]
        values = [value(x) for x in self._values]
        if not is_nondecreasing(breakpoints):
            raise PiecewiseValidationError(
                "The list of breakpoints is not nondecreasing: %s"
                % (str(breakpoints)))

        ftype, slopes = characterize_function(breakpoints, values)
        for i in xrange(1, len(slopes)):
            if (slopes[i-1] is not None) and \
               (slopes[i] is not None) and \
               (abs(slopes[i-1] - slopes[i]) <= equal_slopes_tolerance):
                raise PiecewiseValidationError(
                    "Piecewise function validation detected slopes "
                    "of consecutive line segments to be within %s "
                    "of one another. This may cause numerical issues. "
                    "To avoid this error, set the 'equal_slopes_tolerance' "
                    "keyword to a smaller value or disable validation."
                    % (equal_slopes_tolerance))

        return ftype
Ejemplo n.º 24
0
    def change_setpoint(self, ref_state, **kwargs):
        """Change the update the ref_state dictionary, and attempt to find a new reference state"""
        if ref_state:
            self.ref_state = ref_state
        else:
            if not ref_state:
                self.journalist("W", self._iteration_count, "change_setpoint", "No reference state was given, using default")
            if not self.ref_state:
                self.journalist("W", self._iteration_count, "change_setpoint", "No default reference state was given, exit")
                sys.exit()
        #: Create a dictionary whose keys are the same as the ref state
        weights_ref = dict.fromkeys(self.ref_state.keys())
        model_ref = self.PlantSample  #: I am not sure about this
        for i in self.ref_state.keys():
            v = getattr(model_ref, i[0])
            vkey = i[1]
            vss0 = value(v[(0, 1) + vkey])
            val = abs(self.ref_state[i] - vss0)
            if val < 1e-09:
                val = 1e+06
            else:
                val = 1/val
            weights_ref[i] = val


        #: If no weights are passed, use the reference that we have just calculated
        weights = kwargs.pop("weights", weights_ref)

        ofexp = 0.0
        for i in self.ref_state.keys():
            v = getattr(self.SteadyRef2, i[0])
            vkey = i[1]
            ofexp += weights[i] * (v[(0, 1) + vkey] - self.ref_state[i]) ** 2

        self.SteadyRef2.obfun_SteadyRef2.set_value(ofexp)
        self.solve_dyn(self.SteadyRef2, iter_max=500, stop_if_nopt=True, **kwargs)

        for i in self.ref_state.keys():
            v = getattr(self.SteadyRef2, i[0])
            vkey = i[1]
            val = value(v[(0, 1) + vkey])
            print("target {:}".format(i[0]), "key {:}".format(i[1]), "weight {:f}".format(weights[i]),
                  "value {:f}".format(val))
        self.update_targets_nmpc()
Ejemplo n.º 25
0
    def _warm_start(self):
        var_names = []
        var_values = []
        for pyomo_var, cplex_var in self._pyomo_var_to_solver_var_map.items():
            if pyomo_var.value is not None:
                var_names.append(cplex_var)
                var_values.append(value(pyomo_var))

        if len(var_names):
            self._solver_model.MIP_starts.add([var_names, var_values], self._solver_model.MIP_starts.effort_level.auto)
Ejemplo n.º 26
0
    def _apply_to(self, instance, overwrite=False):
        """Apply the transformation.

        Kwargs:
            overwrite: if False, transformation will not overwrite existing
                variable values.
        """
        for var in instance.component_data_objects(
                ctype=Var, descend_into=True):
            if var.fixed:
                continue
            if var.value is not None and not overwrite:
                continue
            if var.lb is not None and value(var.lb) > 0:
                var.set_value(value(var.lb))
            elif var.ub is not None and value(var.ub) < 0:
                var.set_value(value(var.ub))
            else:
                var.set_value(0)
Ejemplo n.º 27
0
    def redo_cost_calculation(m):
        commitments_costs = []
        for c in m.c:
            commitment_cost = 0
            for j in m.j:

                ems_power_in_j = sum(m.power[d, j] for d in m.d)
                ems_power_deviation = ems_power_in_j - m.commitment_quantity[c,
                                                                             j]

                if value(ems_power_deviation) >= 0:
                    commitment_cost += round(
                        value(ems_power_deviation * m.up_price[c, j]), 3)

                else:
                    commitment_cost += round(
                        value(ems_power_deviation * m.down_price[c, j]), 3)

            commitments_costs.append(commitment_cost)
        return commitments_costs
Ejemplo n.º 28
0
 def uslack(self):
     """Upper slack (ub - value). Returns :const:`None` if
     the variable value is :const:`None`."""
     val = self.value
     if val is None:
         return None
     ub = self.ub
     if ub is None:
         ub = _pos_inf
     else:
         ub = value(ub)
     return ub - val
Ejemplo n.º 29
0
 def lslack(self):
     """Lower slack (value - lb). Returns :const:`None` if
     the variable value is :const:`None`."""
     val = self.value
     if val is None:
         return None
     lb = self.lb
     if lb is None:
         lb = _neg_inf
     else:
         lb = value(lb)
     return val - lb
Ejemplo n.º 30
0
    def __init__(self, var_list, symbol_map):
        self.binary = []
        self.ints = []
        self.positive = []
        self.reals = []

        # categorize variables
        for var in var_list:
            v = symbol_map.getObject(var)
            if v.is_binary():
                self.binary.append(var)
            elif v.is_integer():
                if (v.has_lb() and (value(v.lb) >= 0)) and \
                   (v.has_ub() and (value(v.ub) <= 1)):
                    self.binary.append(var)
                else:
                    self.ints.append(var)
            elif value(v.lb) == 0:
                self.positive.append(var)
            else:
                self.reals.append(var)