def test_numerical_instability_almost_canceling(self):
        # It's possible that we get almost-but-not-quite zero on the variable
        # being eliminated when we are doing this with floating point
        # arithmetic. This can get ugly later becuase it might get muliplied by
        # a large number later and start to "reappear"
        m = ConcreteModel()
        m.x = Var()
        m.x0 = Var()
        m.y = Var()

        m.cons1 = Constraint(expr=(1.342 + 2.371e-8)*m.x0 <= m.x + 17*m.y)
        m.cons2 = Constraint(expr=(17.56 + 3.2e-7)*m.x0 >= m.y)
        
        fme = TransformationFactory('contrib.fourier_motzkin_elimination')
        
        fme.apply_to(m, vars_to_eliminate=[m.x0], verbose=True,
                     zero_tolerance=1e-9)

        constraints = m._pyomo_contrib_fme_transformation.projected_constraints

        # There's going to be numerical error here, and I can't really help
        # it. What I care about is that x0 really is gone.

        useful = constraints[1]
        repn = generate_standard_repn(useful.body)
        self.assertTrue(repn.is_linear())
        self.assertEqual(len(repn.linear_coefs), 2) # this is the real test
        self.assertEqual(useful.lower, 0)
        self.assertIs(repn.linear_vars[0], m.x)
        self.assertAlmostEqual(repn.linear_coefs[0], 0.7451564696962295)
        self.assertIs(repn.linear_vars[1], m.y)
        self.assertAlmostEqual(repn.linear_coefs[1], 12.610712377673217)
        self.assertEqual(repn.constant, 0)
        self.assertIsNone(useful.upper)
    def test_simple_hull_example(self):
        m = ConcreteModel()
        m.x0 = Var(bounds=(0, 3))
        m.x1 = Var(bounds=(0, 3))
        m.x = Var(bounds=(0, 3))
        m.disaggregation = Constraint(expr=m.x == m.x0 + m.x1)
        m.y = Var(domain=Binary)
        m.cons = Constraint(expr=2 * m.y <= m.x1)

        fme = TransformationFactory('contrib.fourier_motzkin_elimination')
        fme.apply_to(m, vars_to_eliminate=[m.x0, m.x1])

        constraints = m._pyomo_contrib_fme_transformation.projected_constraints
        constraints.pprint()

        self.assertEqual(len(constraints), 1)
        cons = constraints[1]
        self.assertIsNone(cons.upper)
        self.assertEqual(value(cons.lower), 0)
        repn = generate_standard_repn(cons.body)
        self.assertEqual(repn.constant, 0)
        self.assertEqual(len(repn.linear_vars), 2)
        self.assertIs(repn.linear_vars[0], m.x)
        self.assertEqual(repn.linear_coefs[0], 1)
        self.assertIs(repn.linear_vars[1], m.y)
        self.assertEqual(repn.linear_coefs[1], -2)
        self.assertTrue(repn.is_linear())
    def test_project_disaggregated_vars(self):
        """This is a little bit more of an integration test with GDP, 
        but also an example of why FME is 'useful.' We will give a GDP, 
        take hull relaxation, and then project out the disaggregated 
        variables."""
        m, disaggregatedVars = self.create_hull_model()

        filtered = TransformationFactory('contrib.fourier_motzkin_elimination').\
                   create_using(m, vars_to_eliminate=disaggregatedVars)
        TransformationFactory('contrib.fourier_motzkin_elimination').apply_to(
            m,
            vars_to_eliminate=disaggregatedVars,
            constraint_filtering_callback=None)

        constraints = m._pyomo_contrib_fme_transformation.projected_constraints
        # we of course get tremendous amounts of garbage, but we make sure that
        # what should be here is:
        self.check_hull_projected_constraints(
            m, constraints, [21, 16, 57, 59, 55, 33, 27, 1, 2, 4, 5])
        # and when we filter, it's still there.
        constraints = filtered._pyomo_contrib_fme_transformation.\
                      projected_constraints
        constraints.pprint()
        self.check_hull_projected_constraints(
            filtered, constraints, [6, 5, 16, 17, 15, 9, 8, 1, 2, 3, 4])
    def test_projected_constraints_named_correctly(self):
        m = self.make_tiny_model_where_bounds_matter()
        fme = TransformationFactory('contrib.fourier_motzkin_elimination')
        fme.apply_to(m.b, vars_to_eliminate=[m.y],
                     projected_constraints_name='fme_constraints')
        self.assertIsInstance(m.b.component("fme_constraints"), Constraint)
        self.check_tiny_model_constraints(m.b.fme_constraints)

        self.assertIsNone(m.b._pyomo_contrib_fme_transformation.component(
            "projected_constraints"))
    def test_use_all_var_bounds(self):
        m = self.make_tiny_model_where_bounds_matter()

        fme = TransformationFactory('contrib.fourier_motzkin_elimination')
        fme.apply_to(m.b, vars_to_eliminate=[m.y])
        constraints = m.b.\
                      _pyomo_contrib_fme_transformation.projected_constraints

        # if we hadn't included y's bounds, then we wouldn't get any constraints
        # and y wouldn't be eliminated. If we do include y's bounds, we get new
        # information that x <= 5:
        self.check_tiny_model_constraints(constraints)
    def create_hull_model(self):
        m = ConcreteModel()
        m.p = Var([1, 2], bounds=(0, 10))
        m.time1 = Disjunction(expr=[m.p[1] >= 1, m.p[1] == 0])

        m.on = Disjunct()
        m.on.above_min = Constraint(expr=m.p[2] >= 1)
        m.on.ramping = Constraint(expr=m.p[2] - m.p[1] <= 3)
        m.on.on_before = Constraint(expr=m.p[1] >= 1)

        m.startup = Disjunct()
        m.startup.startup_limit = Constraint(expr=(1, m.p[2], 2))
        m.startup.off_before = Constraint(expr=m.p[1] == 0)

        m.off = Disjunct()
        m.off.off = Constraint(expr=m.p[2] == 0)
        m.time2 = Disjunction(expr=[m.on, m.startup, m.off])

        m.obj = Objective(expr=m.p[1] + m.p[2])

        hull = TransformationFactory('gdp.hull')
        hull.apply_to(m)
        disaggregatedVars = ComponentSet([
            hull.get_disaggregated_var(m.p[1], m.time1.disjuncts[0]),
            hull.get_disaggregated_var(m.p[1], m.time1.disjuncts[1]),
            hull.get_disaggregated_var(m.p[1], m.on),
            hull.get_disaggregated_var(m.p[2], m.on),
            hull.get_disaggregated_var(m.p[1], m.startup),
            hull.get_disaggregated_var(m.p[2], m.startup),
            hull.get_disaggregated_var(m.p[1], m.off),
            hull.get_disaggregated_var(m.p[2], m.off)
        ])

        return m, disaggregatedVars
Example #7
0
 def _presolve(self, *args, **kwds):
     if not isinstance(args[0], six.string_types):
         self._instance = args[0]
         xfrm = TransformationFactory('mpec.nl')
         xfrm.apply_to(self._instance)
         if len(self._instance._transformation_data['mpec.nl'].compl_cuids) == 0:
             # There were no complementarity conditions
             # so we don't hold onto the instance
             self._instance = None
         else:
             args = (self._instance,)
     else:
         self._instance = None
     #
     SystemCallSolver._presolve(self, *args, **kwds)
Example #8
0
    def _apply_to_impl(self, instance, **kwds):
        if not instance.ctype in (Block, Disjunct):
            raise GDP_Error("Transformation called on %s of type %s. "
                            "'instance' must be a ConcreteModel, Block, or "
                            "Disjunct (in the case of nested disjunctions)." %
                            (instance.name, instance.ctype))

        config = self.CONFIG(kwds.pop('options', {}))

        # We will let args override suffixes and estimate as a last
        # resort. More specific args/suffixes override ones anywhere in
        # the tree. Suffixes lower down in the tree override ones higher
        # up.
        config.set_value(kwds)
        bigM = config.bigM
        self.assume_fixed_vars_permanent = config.assume_fixed_vars_permanent

        targets = config.targets
        # We need to check that all the targets are in fact on instance. As we
        # do this, we will use the set below to cache components we know to be
        # in the tree rooted at instance.
        knownBlocks = {}
        if targets is None:
            targets = (instance, )
        # we need to preprocess targets to make sure that if there are any
        # disjunctions in targets that their disjuncts appear before them in
        # the list.
        targets = preprocess_targets(targets, instance, knownBlocks)

        for t in targets:
            if t.ctype is Disjunction:
                if t.is_indexed():
                    self._transform_disjunction(t, bigM)
                else:
                    self._transform_disjunctionData(t, bigM, t.index())
            else:  # We know t.ctype in (Block, Disjunct) after preprocessing
                if t.is_indexed():
                    self._transform_block(t, bigM)
                else:
                    self._transform_blockData(t, bigM)

        # issue warnings about anything that was in the bigM args dict that we
        # didn't use
        if bigM is not None:
            unused_args = ComponentSet(bigM.keys()) - \
                          ComponentSet(self.used_args.keys())
            if len(unused_args) > 0:
                warning_msg = ("Unused arguments in the bigM map! "
                               "These arguments were not used by the "
                               "transformation:\n")
                for component in unused_args:
                    if hasattr(component, 'name'):
                        warning_msg += "\t%s\n" % component.name
                    else:
                        warning_msg += "\t%s\n" % component
                logger.warning(warning_msg)

        # at the end, transform any logical constraints that might be on
        # instance
        TransformationFactory('core.logical_to_linear').apply_to(instance)
Example #9
0
 def _presolve(self, *args, **kwds):
     if not isinstance(args[0], six.string_types):
         self._instance = args[0]
         xfrm = TransformationFactory('mpec.nl')
         xfrm.apply_to(self._instance)
         if len(self._instance._transformation_data['mpec.nl'].compl_cuids
                ) == 0:
             # There were no complementarity conditions
             # so we don't hold onto the instance
             self._instance = None
         else:
             args = (self._instance, )
     else:
         self._instance = None
     #
     SystemCallSolver._presolve(self, *args, **kwds)
 def test_transformed_constraints_indexed_var_arg(self):
     m = self.makeModel()
     TransformationFactory('contrib.fourier_motzkin_elimination').apply_to(
         m, vars_to_eliminate=m.lamb, constraint_filtering_callback=None)
     # we get some trivial constraints too, but let's check that the ones
     # that should be there really are
     self.check_projected_constraints(m, self.unfiltered_indices)
    def test_transformed_constraints_varData_list_arg(self):
        m = self.makeModel()
        TransformationFactory('contrib.fourier_motzkin_elimination').apply_to(
            m,
            vars_to_eliminate=[m.lamb[1], m.lamb[2]],
            constraint_filtering_callback=None)

        self.check_projected_constraints(m, self.unfiltered_indices)
 def test_no_vars_specified(self):
     m = self.makeModel()
     self.assertRaisesRegexp(
         RuntimeError,
         "The Fourier-Motzkin Elimination transformation "
         "requires the argument vars_to_eliminate, a "
         "list of Vars to be projected out of the model.",
         TransformationFactory('contrib.fourier_motzkin_elimination').\
         apply_to,
         m)
Example #13
0
 def _transform_blockData(self, obj, bigM):
     # Transform every (active) disjunction in the block
     for disjunction in obj.component_objects(
             Disjunction,
             active=True,
             sort=SortComponents.deterministic,
             descend_into=(Block, Disjunct),
             descent_order=TraversalStrategy.PostfixDFS):
         self._transform_disjunction(disjunction, bigM)
     # transform any logical constraints
     TransformationFactory('core.logical_to_linear').apply_to(obj)
    def test_original_constraints_deactivated(self):
        m = self.makeModel()
        TransformationFactory('contrib.fourier_motzkin_elimination').apply_to(
            m, vars_to_eliminate=m.lamb)

        self.assertFalse(m.primal1.active)
        self.assertFalse(m.dual1.active)
        self.assertFalse(m.dual2.active)
        self.assertFalse(m.bound_lambdas[1].active)
        self.assertFalse(m.bound_lambdas[2].active)
        self.assertFalse(m.bound_y.active)
    def test_integer_arithmetic_non1_coefficients(self):
        m = ConcreteModel()
        m.x = Var(bounds=(0, 9))
        m.y = Var(bounds=(-5, 5))
        m.c1 = Constraint(expr=4 * m.x + m.y >= 4)
        m.c2 = Constraint(expr=m.y >= 2 * m.x)

        fme = TransformationFactory('contrib.fourier_motzkin_elimination')

        fme.apply_to(m,
                     vars_to_eliminate=m.x,
                     constraint_filtering_callback=None,
                     do_integer_arithmetic=True,
                     verbose=True)

        constraints = m._pyomo_contrib_fme_transformation.projected_constraints

        self.assertEqual(len(constraints), 3)

        cons = constraints[3]
        self.assertEqual(value(cons.lower), -32)
        self.assertIs(cons.body, m.y)
        self.assertIsNone(cons.upper)

        cons = constraints[2]
        self.assertEqual(value(cons.lower), 0)
        self.assertIsNone(cons.upper)
        repn = generate_standard_repn(cons.body)
        self.assertTrue(repn.is_linear())
        self.assertEqual(len(repn.linear_coefs), 1)
        self.assertIs(repn.linear_vars[0], m.y)
        self.assertEqual(repn.linear_coefs[0], 2)

        cons = constraints[1]
        self.assertEqual(value(cons.lower), 4)
        self.assertIsNone(cons.upper)
        repn = generate_standard_repn(cons.body)
        self.assertTrue(repn.is_linear())
        self.assertEqual(len(repn.linear_coefs), 1)
        self.assertIs(repn.linear_vars[0], m.y)
        self.assertEqual(repn.linear_coefs[0], 3)
Example #16
0
 def test_non_unique_constraint_name_error(self):
     m = self.make_tiny_model_where_bounds_matter()
     fme = TransformationFactory('contrib.fourier_motzkin_elimination')
     self.assertRaisesRegex(RuntimeError,
                            "projected_constraints_name was specified "
                            "as 'c', but this is already a component on "
                            "the instance! Please specify a unique "
                            "name.",
                            fme.apply_to,
                            m.b,
                            vars_to_eliminate=[m.y],
                            projected_constraints_name='c')
    def test_infeasible_model_no_var_bounds(self):
        m = ConcreteModel()
        m.x = Var()
        m.cons1 = Constraint(expr=m.x >= 6)
        m.cons2 = Constraint(expr=m.x <= 2)

        self.assertRaisesRegexp(
            RuntimeError,
            "Fourier-Motzkin found the model is infeasible!",
            TransformationFactory('contrib.fourier_motzkin_elimination').\
            apply_to,
            m,
            vars_to_eliminate=m.x)
    def test_default_constraint_filtering(self):
        # We will filter constraints which are trivial based on variable bounds
        # during the transformation. This checks that we removed the constraints
        # we expect.
        m = self.makeModel()
        TransformationFactory('contrib.fourier_motzkin_elimination').apply_to(
            m, vars_to_eliminate=m.lamb)

        # we still have all the right constraints
        self.check_projected_constraints(m, self.filtered_indices)
        # but now we *only* have the right constraints
        constraints = m._pyomo_contrib_fme_transformation.projected_constraints
        self.assertEqual(len(constraints), 4)
 def test_constraint_filtering_callback_not_callable_error(self):
     m = self.makeModel()
     fme = TransformationFactory('contrib.fourier_motzkin_elimination')
     log = StringIO()
     with LoggingIntercept(log, 'pyomo.contrib.fme', logging.ERROR):
         self.assertRaisesRegexp(TypeError,
                                 "'int' object is not callable",
                                 fme.apply_to,
                                 m,
                                 vars_to_eliminate=m.x,
                                 constraint_filtering_callback=5)
     self.assertRegexpMatches(
         log.getvalue(), "Problem calling constraint filter callback "
         "on constraint with right-hand side -1.0 and body:*")
    def test_use_all_var_bounds(self):
        m = ConcreteModel()
        m.b = Block()
        m.x = Var(bounds=(0, 15))
        m.y = Var(bounds=(3, 5))
        m.b.c = Constraint(expr=m.x + m.y <= 8)

        fme = TransformationFactory('contrib.fourier_motzkin_elimination')
        fme.apply_to(m.b, vars_to_eliminate=[m.y])
        constraints = m.b.\
                      _pyomo_contrib_fme_transformation.projected_constraints

        # if we hadn't included y's bounds, then we wouldn't get any constraints
        # and y wouldn't be eliminated. If we do include y's bounds, we get new
        # information that x <= 5:
        self.assertEqual(len(constraints), 1)
        cons = constraints[1]
        self.assertEqual(value(cons.lower), -5)
        self.assertIsNone(cons.upper)
        repn = generate_standard_repn(cons.body)
        self.assertEqual(repn.constant, 0)
        self.assertEqual(len(repn.linear_vars), 1)
        self.assertIs(repn.linear_vars[0], m.x)
        self.assertEqual(repn.linear_coefs[0], -1)
Example #21
0
    def create_chull_model(self):
        m = ConcreteModel()
        m.p = Var([1, 2], bounds=(0, 10))
        m.time1 = Disjunction(expr=[m.p[1] >= 1, m.p[1] == 0])

        m.on = Disjunct()
        m.on.above_min = Constraint(expr=m.p[2] >= 1)
        m.on.ramping = Constraint(expr=m.p[2] - m.p[1] <= 3)
        m.on.on_before = Constraint(expr=m.p[1] >= 1)

        m.startup = Disjunct()
        m.startup.startup_limit = Constraint(expr=(1, m.p[2], 2))
        m.startup.off_before = Constraint(expr=m.p[1] == 0)

        m.off = Disjunct()
        m.off.off = Constraint(expr=m.p[2] == 0)
        m.time2 = Disjunction(expr=[m.on, m.startup, m.off])

        m.obj = Objective(expr=m.p[1] + m.p[2])

        chull = TransformationFactory('gdp.chull')
        chull.apply_to(m)
        disaggregatedVars = ComponentSet([
            chull.get_disaggregated_var(m.p[1], m.time1.disjuncts[0]),
            chull.get_disaggregated_var(m.p[1], m.time1.disjuncts[1]),
            chull.get_disaggregated_var(m.p[1], m.on),
            chull.get_disaggregated_var(m.p[2], m.on),
            chull.get_disaggregated_var(m.p[1], m.startup),
            chull.get_disaggregated_var(m.p[2], m.startup),
            chull.get_disaggregated_var(m.p[1], m.off),
            chull.get_disaggregated_var(m.p[2], m.off)
        ])

        # from nose.tools import set_trace
        # set_trace()
        # disaggregatedVars = ComponentSet([relaxationBlocks[0].component("p[1]"),
        #                                   relaxationBlocks[1].component("p[1]"),
        #                                   relaxationBlocks[2].component("p[1]"),
        #                                   relaxationBlocks[2].component("p[2]"),
        #                                   relaxationBlocks[3].component("p[1]"),
        #                                   relaxationBlocks[3].component("p[2]"),
        #                                   relaxationBlocks[4].component("p[1]"),
        #                                   relaxationBlocks[4].component("p[2]")])

        return m, disaggregatedVars
    def test_components_we_do_not_understand_error(self):
        m = self.makeModel()
        m.disj = Disjunction(expr=[m.x == 0, m.y >= 2])

        self.assertRaisesRegexp(
            RuntimeError,
            "Found active component %s of type %s. The "
            "Fourier-Motzkin Elimination transformation can only "
            "handle purely algebraic models. That is, only "
            "Sets, Params, Vars, Constraints, Expressions, Blocks, "
            "and Objectives may be active on the model." % (m.disj.name,
                                                            m.disj.type()),
            TransformationFactory('contrib.fourier_motzkin_elimination').\
            apply_to,
            m,
            vars_to_eliminate=m.x)
Example #23
0
def make_model():
    m = ConcreteModel()
    m.time = ContinuousSet(bounds=(0, 10))
    m.space = ContinuousSet(bounds=(0, 5))
    m.set1 = Set(initialize=['a', 'b', 'c'])
    m.set2 = Set(initialize=['d', 'e', 'f'])
    m.fs = Block()

    m.fs.v0 = Var(m.space, initialize=1)

    @m.fs.Block()
    def b1(b):
        b.v = Var(m.time, m.space, initialize=1)
        b.dv = DerivativeVar(b.v, wrt=m.time, initialize=0)

        b.con = Constraint(m.time,
                           m.space,
                           rule=lambda b, t, x: b.dv[t, x] == 7 - b.v[t, x])
        # Inconsistent

        @b.Block(m.time)
        def b2(b, t):
            b.v = Var(initialize=2)

    @m.fs.Block(m.time, m.space)
    def b2(b, t, x):
        b.v = Var(m.set1, initialize=2)

        @b.Block(m.set1)
        def b3(b, c):
            b.v = Var(m.set2, initialize=3)

            @b.Constraint(m.set2)
            def con(b, s):
                return (5 * b.v[s] == m.fs.b2[m.time.first(),
                                              m.space.first()].v[c])
                # inconsistent

    @m.fs.Constraint(m.time)
    def con1(fs, t):
        return fs.b1.v[t, m.space.last()] == 5

    # Will be inconsistent

    @m.fs.Constraint(m.space)
    def con2(fs, x):
        return fs.b1.v[m.time.first(), x] == fs.v0[x]

    # will be consistent

    disc = TransformationFactory('dae.collocation')
    disc.apply_to(m, wrt=m.time, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')
    disc.apply_to(m, wrt=m.space, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')

    return m
    def test_nonlinear_error(self):
        m = ConcreteModel()
        m.x = Var()
        m.cons = Constraint(expr=m.x**2 >= 2)
        m.cons2 = Constraint(expr=m.x <= 10)

        self.assertRaisesRegexp(
            RuntimeError,
            "Variable x appears in a nonlinear "
            "constraint. The Fourier-Motzkin "
            "Elimination transformation can only "
            "be used to eliminate variables "
            "which only appear linearly.",
            TransformationFactory('contrib.fourier_motzkin_elimination').\
            apply_to,
            m,
            vars_to_eliminate=m.x)
Example #25
0
    def _apply_to(self, model, **kwds):
        """Fix all disjuncts in the given model and reclassify them to 
        Blocks."""
        config = self.config = self.CONFIG(kwds.pop('options', {}))
        config.set_value(kwds)

        self._transformContainer(model)

        # Reclassify all disjuncts
        for disjunct_object in model.component_objects(Disjunct,
                                                       descend_into=(Block,
                                                                     Disjunct)):
            disjunct_object.parent_block().reclassify_component_type(
                disjunct_object, Block)

        # Transform any remaining logical stuff
        TransformationFactory('core.logical_to_linear').apply_to(model)
 def test_bad_constraint_filtering_callback_error(self):
     m = self.makeModel()
     def not_a_callback(cons):
         raise RuntimeError("I don't know how to do my job.")
     fme = TransformationFactory('contrib.fourier_motzkin_elimination')
     log = StringIO()
     with LoggingIntercept(log, 'pyomo.contrib.fme', logging.ERROR):
         self.assertRaisesRegex(
             RuntimeError,
             "I don't know how to do my job.",
             fme.apply_to,
             m,
             vars_to_eliminate=m.x,
             constraint_filtering_callback=not_a_callback)
     self.assertRegex(
         log.getvalue(),
         "Problem calling constraint filter callback "
         "on constraint with right-hand side -1.0 and body:*")
Example #27
0
    def subproblem_solve(gdp, solver, config):
        subproblem = gdp.clone()
        TransformationFactory('gdp.fix_disjuncts').apply_to(subproblem)

        result = solver.solve(subproblem, **config.solver_args)
        main_obj = next(
            subproblem.component_data_objects(Objective, active=True))
        obj_sign = 1 if main_obj.sense == minimize else -1
        if (result.solver.status is SolverStatus.ok
                and result.solver.termination_condition is tc.optimal):
            return value(
                main_obj.expr), result, subproblem.GDPbb_utils.variable_list
        elif result.solver.termination_condition is tc.unbounded:
            return obj_sign * float(
                '-inf'), result, subproblem.GDPbb_utils.variable_list
        else:
            return obj_sign * float(
                'inf'), result, subproblem.GDPbb_utils.variable_list
    def test_noninteger_coefficients_of_vars_not_being_projected_error(self):
        m = ConcreteModel()
        m.x = Var(bounds=(0, 9))
        m.y = Var(bounds=(-5, 5))
        m.c1 = Constraint(expr=2 * m.x + 0.5 * m.y >= 2)
        m.c2 = Constraint(expr=0.25 * m.y >= 5 * m.x)

        fme = TransformationFactory('contrib.fourier_motzkin_elimination')
        self.assertRaisesRegexp(
            ValueError, "The do_integer_arithmetic flag was "
            "set to True, but the coefficient of "
            "y is non-integer within the specified tolerance, "
            "with value 0.5. \n"
            "Please set do_integer_arithmetic="
            "False, increase integer_tolerance, or make your data integer.",
            fme.apply_to,
            m,
            vars_to_eliminate=m.x,
            do_integer_arithmetic=True)
    def test_combine_three_inequalities_and_flatten_blocks(self):
        m = ConcreteModel()
        m.x = Var()
        m.y = Var()
        m.b = Block()
        m.b.c = Constraint(expr=m.x >= 2)
        m.c = Constraint(expr=m.y <= m.x)
        m.b.b2 = Block()
        m.b.b2.c = Constraint(expr=m.y >= 4)
        TransformationFactory('contrib.fourier_motzkin_elimination').apply_to(
            m, vars_to_eliminate=m.y)

        constraints = m._pyomo_contrib_fme_transformation.projected_constraints
        self.assertEqual(len(constraints), 2)
        cons = constraints[1]
        self.assertEqual(value(cons.lower), 2)
        self.assertIsNone(cons.upper)
        self.assertIs(cons.body, m.x)

        cons = constraints[2]
        self.assertEqual(value(cons.lower), 4)
        self.assertIsNone(cons.upper)
        self.assertIs(cons.body, m.x)
    def test_post_processing(self):
        m, disaggregatedVars = self.create_hull_model()
        fme = TransformationFactory('contrib.fourier_motzkin_elimination')
        fme.apply_to(m, vars_to_eliminate=disaggregatedVars)
        # post-process
        fme.post_process_fme_constraints(m, SolverFactory('glpk'))

        constraints = m._pyomo_contrib_fme_transformation.projected_constraints
        self.assertEqual(len(constraints), 11)

        # They should be the same as the above, but now these are *all* the
        # constraints
        self.check_hull_projected_constraints(
            m, constraints, [6, 5, 16, 17, 15, 9, 8, 1, 2, 3, 4])

        # and check that we didn't change the model
        for disj in m.component_data_objects(Disjunct):
            self.assertIs(disj.indicator_var.domain, Binary)
        self.assertEqual(len([o for o in m.component_data_objects(Objective)]),
                         1)
        self.assertIsInstance(m.component("obj"), Objective)
        self.assertTrue(m.obj.active)
Example #31
0
    def apply_discretization(self, transformation, **kwargs):
        """Discretizes the model.

        :param str transformation: The type of transformation (only dae.collocation...)
        :param dict kwargs: The options for the discretization

        :return: None

        """
        fixed_times = kwargs.pop('fixed_times', None)

        if not self.model.alltime.get_discretization_info():

            discretizer = TransformationFactory(transformation)

            if fixed_times == None:
                discretizer.apply_to(self.model,
                                     wrt=self.model.alltime,
                                     **kwargs)
            else:
                discretizer.apply_to(self.model, wrt=fixed_times, **kwargs)

            self._alltimes = sorted(self.model.alltime)
            self._n_alltimes = len(self._alltimes)

            # This needs to be looked at in more detail to see if it is still needed.

            #added for optional smoothing parameter with reading values from file CS:
            # if self._smoothparam_given:
            #     dfps = pd.DataFrame(index=self.model.alltime, columns=self.model.smoothparameter_names)
            #     for t in self.model.alltime:
            #         if t not in self.model.allsmooth_times:  # for points that are the same in original meas times and feed times
            #             dfps.loc[t] = float(22.) #something that is not between 0 and 1
            #         else:
            #             ps_dict_help = dict()
            #             for p in self.model.smoothparameter_names:
            #                 ps_dict_help[t, p] = value(self.model.smooth_param_data[t, p])
            #             dfps.loc[t] = [ps_dict_help[t, p] for p in self.model.smoothparameter_names]
            #     dfallps = dfps
            #     dfallps.sort_index(inplace=True)
            #     dfallps.index = dfallps.index.to_series().apply(
            #         lambda x: np.round(x, 6))  # time from data rounded to 6 digits

            #     dfallpsall = pd.DataFrame(index=self.model.alltime, columns=self.model.smoothparameter_names)
            #     dfsmoothdata = pd.DataFrame(index=sorted(self.model.smooth_param_datatimes), columns=self.model.smoothparameter_names)

            #     for t in self.model.smooth_param_datatimes:
            #         dfsmoothdata.loc[t] = [value(self.model.smooth_param_data[t, p]) for p in self.model.smoothparameter_names]

            #     for p in self.model.smoothparameter_names:
            #         values = interpolate_trajectory(self.model.alltime, dfsmoothdata[p])
            #         for i, ti in enumerate(self.model.alltime):
            #             if float(dfallps[p][ti]) > 1:
            #                 valueinterp=values[i]
            #                 dfallpsall[p][ti] = float(valueinterp)
            #             else:
            #                 dfallpsall.loc[ti] = float(dfallps[p][ti])

            self._default_initialization()

            # if hasattr(self.model, 'K'):
            #     print('Scaling the parameters')
            #     self.scale_parameters()

        else:
            print(
                '***WARNING: Model already discretized. Ignoring second discretization'
            )