def test_cyipopt_callback(self):
        # Use a callback to check that the reported infeasibility is
        # due to the scaled equality constraints.
        # Note that the scaled infeasibility is not what we see if we
        # call solve with tee=True, as by default the displayed infeasibility
        # is unscaled. Luckily, we can still access the scaled infeasibility
        # with a callback.
        m = self.make_model()
        scaling_factors = [1e-4, 1e4]
        m.epm.set_equality_constraint_scaling_factors(scaling_factors)
        nlp = PyomoNLPWithGreyBoxBlocks(m)

        def callback(
            local_nlp,
            alg_mod,
            iter_count,
            obj_value,
            inf_pr,
            inf_du,
            mu,
            d_norm,
            regularization_size,
            alpha_du,
            alpha_pr,
            ls_trials,
        ):
            primals = tuple(local_nlp.get_primals())
            # I happen to know the order of the primals here
            u, v, x, y = primals

            # Calculate the scaled residuals I expect
            con_3_resid = scaling_factors[0] * abs(
                self.con_3_body(x, y, u, v) - self.con_3_rhs())
            con_4_resid = scaling_factors[1] * abs(
                self.con_4_body(x, y, u, v) - self.con_4_rhs())
            pred_inf_pr = max(con_3_resid, con_4_resid)

            # Make sure Ipopt is using the scaled constraints internally
            self.assertAlmostEqual(inf_pr, pred_inf_pr)

        cyipopt_nlp = CyIpoptNLP(
            nlp,
            intermediate_callback=callback,
        )
        x0 = nlp.get_primals()
        cyipopt = CyIpoptSolver(
            cyipopt_nlp,
            options={
                "max_iter": 0,
                "nlp_scaling_method": "user-scaling",
            },
        )
        cyipopt.solve(x0=x0)
Ejemplo n.º 2
0
    def test_composite_nlp(self):

        G = np.array([[6, 2, 1], [2, 5, 2], [1, 2, 4]])
        A = np.array([[1, 0, 1], [0, 1, 1]])
        b = np.array([3, 0])
        c = np.array([-8, -3, -3])

        scenarios = dict()
        coupling_vars = dict()
        n_scenarios = 2
        np.random.seed(seed=985739465)
        bs = [b, b + 0.001]

        for i in range(n_scenarios):
            instance = create_model3(G, A, bs[i], c)
            nlp = PyomoNLP(instance)
            scenario_name = "s{}".format(i)
            scenarios[scenario_name] = nlp
            coupling_vars[scenario_name] = [nlp.variable_idx(instance.x[0])]

        nlp = TwoStageStochasticNLP(scenarios, coupling_vars)

        solver = CyIpoptSolver(nlp)
        x, info = solver.solve(tee=False)
        x_sol = np.array([
            2.00003846, -0.99996154, 0.99996154, 2.00003846, -0.99996154,
            1.00096154, 2.00003846
        ])

        self.assertTrue(np.allclose(x, x_sol, rtol=1e-4))
        self.assertAlmostEqual(nlp.objective(x), -6.99899, 3)
Ejemplo n.º 3
0
    def test_pyomo_external_model(self):
        m = pyo.ConcreteModel()
        m.Pin = pyo.Var(initialize=100, bounds=(0,None))
        m.c1 = pyo.Var(initialize=1.0, bounds=(0,None))
        m.c2 = pyo.Var(initialize=1.0, bounds=(0,None))
        m.F = pyo.Var(initialize=10, bounds=(0,None))

        m.P1 = pyo.Var()
        m.P2 = pyo.Var()

        m.F_con = pyo.Constraint(expr = m.F == 10)
        m.Pin_con = pyo.Constraint(expr = m.Pin == 100)

        # simple parameter estimation test
        m.obj = pyo.Objective(expr= (m.P1 - 90)**2 + (m.P2 - 40)**2)

        cyipopt_problem = \
            PyomoExternalCyIpoptProblem(m,
                                        PressureDropModel(),
                                        [m.Pin, m.c1, m.c2, m.F],
                                        [m.P1, m.P2]
                                        )

        # check that the dummy variable is initialized
        expected_dummy_var_value = pyo.value(m.Pin) + pyo.value(m.c1) + pyo.value(m.c2) + pyo.value(m.F) \
            + 0 + 0
            # + pyo.value(m.P1) + pyo.value(m.P2) # not initialized - therefore should use zero
        self.assertAlmostEqual(pyo.value(m._dummy_variable_CyIpoptPyomoExNLP), expected_dummy_var_value)

        # solve the problem
        solver = CyIpoptSolver(cyipopt_problem, {'hessian_approximation':'limited-memory'})
        x, info = solver.solve(tee=False)
        cyipopt_problem.load_x_into_pyomo(x)
        self.assertAlmostEqual(pyo.value(m.c1), 0.1, places=5)
        self.assertAlmostEqual(pyo.value(m.c2), 0.5, places=5)
Ejemplo n.º 4
0
 def test_options(self):
     model = create_model1()
     nlp = PyomoNLP(model)
     solver = CyIpoptSolver(CyIpoptNLP(nlp), options={'max_iter': 1})
     x, info = solver.solve(tee=False)
     nlp.set_primals(x)
     self.assertAlmostEqual(nlp.evaluate_objective(), -5.0879028e+02, places=5)
Ejemplo n.º 5
0
    def test_model1_with_scaling(self):
        m = create_model1()
        m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
        m.scaling_factor[m.o] = 1e-6 # scale the objective
        m.scaling_factor[m.c] = 2.0  # scale the equality constraint
        m.scaling_factor[m.d] = 3.0  # scale the inequality constraint
        m.scaling_factor[m.x[1]] = 4.0  # scale one of the x variables

        cynlp = CyIpoptNLP(PyomoNLP(m))
        options={'nlp_scaling_method': 'user-scaling',
                 'output_file': '_cyipopt-scaling.log',
                 'file_print_level':10,
                 'max_iter': 0}
        solver = CyIpoptSolver(cynlp, options=options)
        x, info = solver.solve()

        with open('_cyipopt-scaling.log', 'r') as fd:
            solver_trace = fd.read()
        os.remove('_cyipopt-scaling.log')

        # check for the following strings in the log and then delete the log
        self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
        self.assertIn('output_file = _cyipopt-scaling.log', solver_trace)
        self.assertIn('objective scaling factor = 1e-06', solver_trace)
        self.assertIn('x scaling provided', solver_trace)
        self.assertIn('c scaling provided', solver_trace)
        self.assertIn('d scaling provided', solver_trace)
        self.assertIn('DenseVector "x scaling vector" with 3 elements:', solver_trace)
        self.assertIn('x scaling vector[    1]= 1.0000000000000000e+00', solver_trace)
        self.assertIn('x scaling vector[    2]= 1.0000000000000000e+00', solver_trace)
        self.assertIn('x scaling vector[    3]= 4.0000000000000000e+00', solver_trace)
        self.assertIn('DenseVector "c scaling vector" with 1 elements:', solver_trace)
        self.assertIn('c scaling vector[    1]= 2.0000000000000000e+00', solver_trace)
        self.assertIn('DenseVector "d scaling vector" with 1 elements:', solver_trace)
        self.assertIn('d scaling vector[    1]= 3.0000000000000000e+00', solver_trace)
Ejemplo n.º 6
0
 def test_model2(self):
     model = create_model2()
     nlp = PyomoNLP(model)
     solver = CyIpoptSolver(nlp)
     x, info = solver.solve(tee=False)
     x_sol = np.array([3.0, 1.99997807])
     y_sol = np.array([0.00017543])
     self.assertTrue(np.allclose(x, x_sol, rtol=1e-4))
     self.assertAlmostEqual(nlp.objective(x), -31.000000057167462, 3)
     self.assertTrue(np.allclose(info['mult_g'], y_sol, rtol=1e-4))
Ejemplo n.º 7
0
 def test_model1(self):
     model = create_model1()
     nlp = PyomoNLP(model)
     solver = CyIpoptSolver(nlp)
     x, info = solver.solve(tee=False)
     x_sol = np.array([3.85958688, 4.67936007, 3.10358931])
     y_sol = np.array([-1.0, 53.90357665])
     self.assertTrue(np.allclose(x, x_sol, rtol=1e-4))
     self.assertAlmostEqual(nlp.objective(x), -428.6362455416348)
     self.assertTrue(np.allclose(info['mult_g'], y_sol, rtol=1e-4))
Ejemplo n.º 8
0
 def test_model2(self):
     model = create_model2()
     nlp = PyomoNLP(model)
     solver = CyIpoptSolver(CyIpoptNLP(nlp))
     x, info = solver.solve(tee=False)
     x_sol = np.array([3.0, 1.99997807])
     y_sol = np.array([0.00017543])
     self.assertTrue(np.allclose(x, x_sol, rtol=1e-4))
     nlp.set_primals(x)
     nlp.set_duals(y_sol)
     self.assertAlmostEqual(nlp.evaluate_objective(), -31.000000057167462, places=5)
     self.assertTrue(np.allclose(info['mult_g'], y_sol, rtol=1e-4))
Ejemplo n.º 9
0
    def test_model3(self):
        G = np.array([[6, 2, 1], [2, 5, 2], [1, 2, 4]])
        A = np.array([[1, 0, 1], [0, 1, 1]])
        b = np.array([3, 0])
        c = np.array([-8, -3, -3])

        model = create_model3(G, A, b, c)
        nlp = PyomoNLP(model)
        solver = CyIpoptSolver(nlp)
        x, info = solver.solve(tee=False)
        x_sol = np.array([2.0, -1.0, 1.0])
        y_sol = np.array([-3., 2.])
        self.assertTrue(np.allclose(x, x_sol, rtol=1e-4))
        self.assertAlmostEqual(nlp.objective(x), -3.5, 3)
        self.assertTrue(np.allclose(info['mult_g'], y_sol, rtol=1e-4))
Ejemplo n.º 10
0
    def test_pyomo_external_model_ndarray_scaling(self):
        m = pyo.ConcreteModel()
        m.Pin = pyo.Var(initialize=100, bounds=(0, None))
        m.c1 = pyo.Var(initialize=1.0, bounds=(0, None))
        m.c2 = pyo.Var(initialize=1.0, bounds=(0, None))
        m.F = pyo.Var(initialize=10, bounds=(0, None))

        m.P1 = pyo.Var()
        m.P2 = pyo.Var()

        m.F_con = pyo.Constraint(expr=m.F == 10)
        m.Pin_con = pyo.Constraint(expr=m.Pin == 100)

        # simple parameter estimation test
        m.obj = pyo.Objective(expr=(m.P1 - 90)**2 + (m.P2 - 40)**2)

        # set scaling parameters for the pyomo variables and constraints
        m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
        m.scaling_factor[m.obj] = 0.1  # scale the objective
        m.scaling_factor[m.Pin] = 2.0  # scale the variable
        m.scaling_factor[m.c1] = 3.0  # scale the variable
        m.scaling_factor[m.c2] = 4.0  # scale the variable
        m.scaling_factor[m.F] = 5.0  # scale the variable
        m.scaling_factor[m.P1] = 6.0  # scale the variable
        m.scaling_factor[m.P2] = 7.0  # scale the variable
        m.scaling_factor[m.F_con] = 8.0  # scale the pyomo constraint
        m.scaling_factor[m.Pin_con] = 9.0  # scale the pyomo constraint

        # test that this all works with ndarray input as well
        cyipopt_problem = \
            PyomoExternalCyIpoptProblem(pyomo_model=m,
                                        ex_input_output_model=PressureDropModel(),
                                        inputs=[m.Pin, m.c1, m.c2, m.F],
                                        outputs=[m.P1, m.P2],
                                        outputs_eqn_scaling=np.asarray([10.0, 11.0], dtype=np.float64)
                                        )

        # solve the problem
        options = {
            'hessian_approximation': 'limited-memory',
            'nlp_scaling_method': 'user-scaling',
            'output_file': '_cyipopt-pyomo-ext-scaling-ndarray.log',
            'file_print_level': 10,
            'max_iter': 0
        }
        solver = CyIpoptSolver(cyipopt_problem, options=options)
        x, info = solver.solve(tee=False)

        with open('_cyipopt-pyomo-ext-scaling-ndarray.log', 'r') as fd:
            solver_trace = fd.read()
        os.remove('_cyipopt-pyomo-ext-scaling-ndarray.log')

        self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
        self.assertIn('output_file = _cyipopt-pyomo-ext-scaling-ndarray.log',
                      solver_trace)
        self.assertIn('objective scaling factor = 0.1', solver_trace)
        self.assertIn('x scaling provided', solver_trace)
        self.assertIn('c scaling provided', solver_trace)
        self.assertIn('d scaling provided', solver_trace)
        self.assertIn('DenseVector "x scaling vector" with 7 elements:',
                      solver_trace)
        self.assertIn('x scaling vector[    1]= 6.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    2]= 7.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    3]= 2.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    4]= 3.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    5]= 4.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    6]= 5.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    7]= 1.0000000000000000e+00',
                      solver_trace)
        self.assertIn('DenseVector "c scaling vector" with 5 elements:',
                      solver_trace)
        self.assertIn('c scaling vector[    1]= 8.0000000000000000e+00',
                      solver_trace)
        self.assertIn('c scaling vector[    2]= 9.0000000000000000e+00',
                      solver_trace)
        self.assertIn('c scaling vector[    3]= 1.0000000000000000e+00',
                      solver_trace)
        self.assertIn('c scaling vector[    4]= 1.0000000000000000e+01',
                      solver_trace)
        self.assertIn('c scaling vector[    5]= 1.1000000000000000e+01',
                      solver_trace)