コード例 #1
0
ファイル: test_derivs.py プロジェクト: wangcj05/pyomo
 def test_cos(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2.0)
     e = pe.cos(m.x)
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
コード例 #2
0
ファイル: test_derivs.py プロジェクト: Pyomo/pyomo
 def test_cos(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2.0)
     e = pe.cos(m.x)
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
コード例 #3
0
ファイル: test_derivs.py プロジェクト: wangcj05/pyomo
 def test_sum(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2.0)
     m.y = pe.Var(initialize=3.0)
     e = 2.0*m.x + 3.0*m.y - m.x*m.y
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.y], pe.value(symbolic[m.y]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
     self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
コード例 #4
0
ファイル: test_derivs.py プロジェクト: Pyomo/pyomo
 def test_sum(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2.0)
     m.y = pe.Var(initialize=3.0)
     e = 2.0*m.x + 3.0*m.y - m.x*m.y
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.y], pe.value(symbolic[m.y]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
     self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
コード例 #5
0
ファイル: test_derivs.py プロジェクト: wangcj05/pyomo
 def test_nested(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2)
     m.y = pe.Var(initialize=3)
     m.p = pe.Param(initialize=0.5, mutable=True)
     e = pe.exp(m.x**m.p + 3.2*m.y - 12)
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.y], pe.value(symbolic[m.y]), tol+3)
     self.assertAlmostEqual(derivs[m.p], pe.value(symbolic[m.p]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
     self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
     self.assertAlmostEqual(derivs[m.p], approx_deriv(e, m.p), tol)
コード例 #6
0
ファイル: test_derivs.py プロジェクト: Pyomo/pyomo
 def test_nested(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2)
     m.y = pe.Var(initialize=3)
     m.p = pe.Param(initialize=0.5, mutable=True)
     e = pe.exp(m.x**m.p + 3.2*m.y - 12)
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.y], pe.value(symbolic[m.y]), tol+3)
     self.assertAlmostEqual(derivs[m.p], pe.value(symbolic[m.p]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
     self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
     self.assertAlmostEqual(derivs[m.p], approx_deriv(e, m.p), tol)
コード例 #7
0
ファイル: test_derivs.py プロジェクト: Pyomo/pyomo
    def test_expressiondata(self):
        m = pe.ConcreteModel()
        m.x = pe.Var(initialize=3)
        m.e = pe.Expression(expr=m.x * 2)

        @m.Expression([1, 2])
        def e2(m, i):
            if i == 1:
                return m.x + 4
            else:
                return m.x ** 2
        m.o = pe.Objective(expr=m.e + 1 + m.e2[1] + m.e2[2])
        derivs = reverse_ad(m.o.expr)
        symbolic = reverse_sd(m.o.expr)
        self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol)
コード例 #8
0
    def test_expressiondata(self):
        m = pe.ConcreteModel()
        m.x = pe.Var(initialize=3)
        m.e = pe.Expression(expr=m.x * 2)

        @m.Expression([1, 2])
        def e2(m, i):
            if i == 1:
                return m.x + 4
            else:
                return m.x**2

        m.o = pe.Objective(expr=m.e + 1 + m.e2[1] + m.e2[2])
        derivs = reverse_ad(m.o.expr)
        symbolic = reverse_sd(m.o.expr)
        self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol)
コード例 #9
0
ファイル: diff.py プロジェクト: wangcj05/pyomo
import pyomo.environ as pe
from pyomo.contrib.derivatives.differentiate import reverse_ad, reverse_sd

m = pe.ConcreteModel()
m.x = pe.Var(initialize=2)
m.y = pe.Var(initialize=3)
m.p = pe.Param(initialize=0.5, mutable=True)

e = pe.exp(m.x**m.p + 0.1*m.y)
derivs = reverse_ad(e)
print('dfdx: ', derivs[m.x])
print('dfdy: ', derivs[m.y])
print('dfdp: ', derivs[m.p])
derivs = reverse_sd(e)
print('dfdx: ', derivs[m.x])
print('dfdy: ', derivs[m.y])
print('dfdp: ', derivs[m.p])
コード例 #10
0
def add_outer_approximation_cuts(nlp_result, solve_data, config):
    """Add outer approximation cuts to the linear GDP model."""
    with time_code(solve_data.timing, 'OA cut generation'):
        m = solve_data.linear_GDP
        GDPopt = m.GDPopt_utils
        sign_adjust = -1 if solve_data.objective_sense == minimize else 1

        # copy values over
        for var, val in zip(GDPopt.variable_list, nlp_result.var_values):
            if val is not None and not var.fixed:
                var.value = val

        # TODO some kind of special handling if the dual is phenomenally small?
        config.logger.debug('Adding OA cuts.')

        counter = 0
        if not hasattr(GDPopt, 'jacobians'):
            GDPopt.jacobians = ComponentMap()
        for constr, dual_value in zip(GDPopt.constraint_list,
                                      nlp_result.dual_values):
            if dual_value is None or constr.body.polynomial_degree() in (1, 0):
                continue

            # Determine if the user pre-specified that OA cuts should not be
            # generated for the given constraint.
            parent_block = constr.parent_block()
            ignore_set = getattr(parent_block, 'GDPopt_ignore_OA', None)
            config.logger.debug('Ignore_set %s' % ignore_set)
            if (ignore_set and (constr in ignore_set
                                or constr.parent_component() in ignore_set)):
                config.logger.debug(
                    'OA cut addition for %s skipped because it is in '
                    'the ignore set.' % constr.name)
                continue

            config.logger.debug("Adding OA cut for %s with dual value %s" %
                                (constr.name, dual_value))

            # Cache jacobians
            jacobians = GDPopt.jacobians.get(constr, None)
            if jacobians is None:
                constr_vars = list(
                    identify_variables(constr.body, include_fixed=False))
                if len(constr_vars) >= 1000:
                    jac_map = reverse_ad(constr.body)
                    jacobians = ComponentMap(
                        (v, jac_map[v]) for v in constr_vars)
                    GDPopt.jacobians[constr] = jacobians
                else:
                    jac_list = differentiate(constr.body, wrt_list=constr_vars)
                    jacobians = ComponentMap(zip(constr_vars, jac_list))
                    GDPopt.jacobians[constr] = jacobians

            # Create a block on which to put outer approximation cuts.
            oa_utils = parent_block.component('GDPopt_OA')
            if oa_utils is None:
                oa_utils = parent_block.GDPopt_OA = Block(
                    doc="Block holding outer approximation cuts "
                    "and associated data.")
                oa_utils.GDPopt_OA_cuts = ConstraintList()
                oa_utils.GDPopt_OA_slacks = VarList(bounds=(0,
                                                            config.max_slack),
                                                    domain=NonNegativeReals,
                                                    initialize=0)

            oa_cuts = oa_utils.GDPopt_OA_cuts
            slack_var = oa_utils.GDPopt_OA_slacks.add()
            rhs = value(constr.lower) if constr.has_lb() else value(
                constr.upper)
            try:
                new_oa_cut = (copysign(1, sign_adjust * dual_value) *
                              (value(constr.body) - rhs + sum(
                                  value(jacobians[var]) * (var - value(var))
                                  for var in jacobians)) - slack_var <= 0)
                if new_oa_cut.polynomial_degree() not in (1, 0):
                    for var in jacobians:
                        print(var.name, value(jacobians[var]))
                oa_cuts.add(expr=new_oa_cut)
                counter += 1
            except ZeroDivisionError:
                config.logger.warning(
                    "Zero division occured attempting to generate OA cut for constraint %s.\n"
                    "Skipping OA cut generation for this constraint." %
                    (constr.name, ))
                # Simply continue on to the next constraint.

        config.logger.info('Added %s OA cuts' % counter)