def test_evaluate_hessian_lagrangian_SimpleModel2x2_1(self): model = SimpleModel2by2_1() m = model.make_model() m.x[0].set_value(1.0) m.x[1].set_value(2.0) m.y[0].set_value(3.0) m.y[1].set_value(4.0) x0_init_list = [-5.0, -3.0, 0.5, 1.0, 2.5] x1_init_list = [-4.5, -2.3, 0.0, 1.0, 4.1] x_init_list = list(itertools.product(x0_init_list, x1_init_list)) external_model = ExternalPyomoModel( list(m.x.values()), list(m.y.values()), list(m.residual_eqn.values()), list(m.external_eqn.values()), ) for x in x_init_list: external_model.set_input_values(x) external_model.set_equality_constraint_multipliers([1.0, 1.0]) hess_lag = external_model.evaluate_hessian_equality_constraints() hess_lag = hess_lag.toarray() expected_hess = model.evaluate_hessian(x) expected_hess_lag = np.tril(expected_hess[0] + expected_hess[1]) np.testing.assert_allclose(hess_lag, expected_hess_lag, rtol=1e-8)
def test_external_multipliers_from_residual_multipliers(self): model = Model2by2() m = model.make_model() m.x[0].set_value(1.0) m.x[1].set_value(2.0) m.y[0].set_value(3.0) m.y[1].set_value(4.0) x0_init_list = [-5.0, -3.0, 0.5, 1.0, 2.5] x1_init_list = [0.5, 1.0, 1.5, 2.5, 4.1] lam_init_list = [-2.5, -0.5, 0.0, 1.0, 2.0] init_list = list( itertools.product(x0_init_list, x1_init_list, lam_init_list)) external_model = ExternalPyomoModel( list(m.x.values()), list(m.y.values()), list(m.residual_eqn.values()), list(m.external_eqn.values()), ) for x0, x1, lam in init_list: x = [x0, x1] lam = [lam] external_model.set_input_values(x) lam_g = external_model.calculate_external_constraint_multipliers( lam) pred_lam_g = model.calculate_external_multipliers(lam, x) np.testing.assert_allclose(lam_g, pred_lam_g, rtol=1e-8)
def test_hessian_SimpleModel2(self): model = SimpleModel2() m = model.make_model() x_init_list = [ [-5.0], [-4.0], [-3.0], [-1.5], [0.5], [1.0], [2.0], [3.5] ] external_model = ExternalPyomoModel( [m.x], [m.y], [m.residual_eqn], [m.external_eqn], ) for x in x_init_list: external_model.set_input_values(x) hess = external_model.evaluate_hessians_of_residuals() self.assertAlmostEqual( hess[0][0, 0], model.evaluate_hessian(x[0]), delta=1e-7, )
def test_evaluate_SimpleModel2(self): model = SimpleModel2() m = model.make_model() x_init_list = [ [-5.0], [-4.0], [-3.0], [-1.5], [0.5], [1.0], [2.0], [3.5] ] external_model = ExternalPyomoModel( [m.x], [m.y], [m.residual_eqn], [m.external_eqn], ) for x in x_init_list: external_model.set_input_values(x) resid = external_model.evaluate_equality_constraints() self.assertAlmostEqual( resid[0], model.evaluate_residual(x[0]), delta=1e-8, )
def test_jacobian_SimpleModel1(self): model = SimpleModel1() m = model.make_model() x_init_list = [ [-5.0], [-4.0], [-3.0], [-1.5], [0.5], [1.0], [2.0], [3.5] ] external_model = ExternalPyomoModel( [m.x], [m.y], [m.residual_eqn], [m.external_eqn], ) for x in x_init_list: external_model.set_input_values(x) jac = external_model.evaluate_jacobian_equality_constraints() self.assertAlmostEqual( jac.toarray()[0][0], model.evaluate_jacobian(x[0]), delta=1e-8, )
def test_external_jacobian_SimpleModel2(self): model = SimpleModel2() m = model.make_model() x_init_list = [ [-5.0], [-4.0], [-3.0], [-1.5], [0.5], [1.0], [2.0], [3.5] ] external_model = ExternalPyomoModel( [m.x], [m.y], [m.residual_eqn], [m.external_eqn], ) for x in x_init_list: external_model.set_input_values(x) jac = external_model.evaluate_jacobian_external_variables() expected_jac = model.evaluate_external_jacobian(x[0]) self.assertAlmostEqual( jac[0,0], expected_jac, delta=1e-8, )
def test_evaluate_hessian_equality_constraints_order(self): model = Model2by2() m = model.make_model() m.x[0].set_value(1.0) m.x[1].set_value(2.0) m.y[0].set_value(3.0) m.y[1].set_value(4.0) x0_init_list = [-5.0, -3.0, 0.5, 1.0, 2.5] x1_init_list = [0.5, 1.0, 1.5, 2.5, 4.1] lam_init_list = [-2.5, -0.5, 0.0, 1.0, 2.0] init_list = list( itertools.product(x0_init_list, x1_init_list, lam_init_list)) external_model = ExternalPyomoModel( list(m.x.values()), list(m.y.values()), list(m.residual_eqn.values()), list(m.external_eqn.values()), ) for x0, x1, lam in init_list: x = [x0, x1] lam = [lam] external_model.set_equality_constraint_multipliers(lam) external_model.set_input_values(x) # Using evaluate_hessian_equality_constraints, which calculates # external multiplier values, we can calculate the correct Hessian # regardless of the order in which primal and dual variables are # set. hess = external_model.evaluate_hessian_equality_constraints() pred_hess = model.calculate_reduced_lagrangian_hessian(lam, x) # This test asserts that we are doing the block reduction properly. np.testing.assert_allclose(hess.toarray(), np.tril(pred_hess), rtol=1e-8) from_individual = external_model.evaluate_hessians_of_residuals() hl_from_individual = sum(l * h for l, h in zip(lam, from_individual)) # This test asserts that the block reduction is correct. np.testing.assert_allclose(hess.toarray(), np.tril(hl_from_individual), rtol=1e-8)
def test_reduced_hessian_lagrangian(self): model = Model2by2() m = model.make_model() m.x[0].set_value(1.0) m.x[1].set_value(2.0) m.y[0].set_value(3.0) m.y[1].set_value(4.0) x0_init_list = [-5.0, -3.0, 0.5, 1.0, 2.5] x1_init_list = [0.5, 1.0, 1.5, 2.5, 4.1] lam_init_list = [-2.5, -0.5, 0.0, 1.0, 2.0] init_list = list( itertools.product(x0_init_list, x1_init_list, lam_init_list)) external_model = ExternalPyomoModel( list(m.x.values()), list(m.y.values()), list(m.residual_eqn.values()), list(m.external_eqn.values()), ) for x0, x1, lam in init_list: x = [x0, x1] lam = [lam] external_model.set_input_values(x) # Same comment as previous test regarding calculation order external_model.set_external_constraint_multipliers(lam) hlxx, hlxy, hlyy = \ external_model.get_full_space_lagrangian_hessians() hess = external_model.calculate_reduced_hessian_lagrangian( hlxx, hlxy, hlyy) pred_hess = model.calculate_reduced_lagrangian_hessian(lam, x) # This test asserts that we are doing the block reduction properly. np.testing.assert_allclose(np.array(hess), pred_hess, rtol=1e-8) from_individual = external_model.evaluate_hessians_of_residuals() hl_from_individual = sum(l * h for l, h in zip(lam, from_individual)) # This test asserts that the block reduction is correct. np.testing.assert_allclose(np.array(hess), hl_from_individual, rtol=1e-8)
def test_hessian_SimpleModel2x2_1(self): model = SimpleModel2by2_1() m = model.make_model() m.x[0].set_value(1.0) m.x[1].set_value(2.0) m.y[0].set_value(3.0) m.y[1].set_value(4.0) x0_init_list = [-5.0, -3.0, 0.5, 1.0, 2.5] x1_init_list = [-4.5, -2.3, 0.0, 1.0, 4.1] x_init_list = list(itertools.product(x0_init_list, x1_init_list)) external_model = ExternalPyomoModel( list(m.x.values()), list(m.y.values()), list(m.residual_eqn.values()), list(m.external_eqn.values()), ) for x in x_init_list: external_model.set_input_values(x) hess = external_model.evaluate_hessians_of_residuals() expected_hess = model.evaluate_hessian(x) np.testing.assert_allclose(hess, expected_hess, rtol=1e-8)
def test_jacobian_SimpleModel2x2_1(self): model = SimpleModel2by2_1() m = model.make_model() m.x[0].set_value(1.0) m.x[1].set_value(2.0) m.y[0].set_value(3.0) m.y[1].set_value(4.0) x0_init_list = [-5.0, -3.0, 0.5, 1.0, 2.5] x1_init_list = [-4.5, -2.3, 0.0, 1.0, 4.1] x_init_list = list(itertools.product(x0_init_list, x1_init_list)) external_model = ExternalPyomoModel( list(m.x.values()), list(m.y.values()), list(m.residual_eqn.values()), list(m.external_eqn.values()), ) for x in x_init_list: external_model.set_input_values(x) jac = external_model.evaluate_jacobian_equality_constraints() expected_jac = model.evaluate_jacobian(x) np.testing.assert_allclose(jac.toarray(), expected_jac, rtol=1e-8)
def test_external_jacobian_Model2by2(self): model = Model2by2() m = model.make_model() m.x[0].set_value(1.0) m.x[1].set_value(2.0) m.y[0].set_value(3.0) m.y[1].set_value(4.0) x0_init_list = [-5.0, -3.0, 0.5, 1.0, 2.5] x1_init_list = [0.5, 1.0, 1.5, 2.5, 4.1] x_init_list = list(itertools.product(x0_init_list, x1_init_list)) external_model = ExternalPyomoModel( list(m.x.values()), list(m.y.values()), list(m.residual_eqn.values()), list(m.external_eqn.values()), ) for x in x_init_list: external_model.set_input_values(x) jac = external_model.evaluate_jacobian_external_variables() expected_jac = model.evaluate_external_jacobian(x) np.testing.assert_allclose(jac, expected_jac, rtol=1e-8)
def test_jacobian_SimpleModel2(self): model = SimpleModel2() m = model.make_model() x_init_list = [ [-5.0], [-4.0], [-3.0], [-1.5], [0.5], [1.0], [2.0], [3.5] ] external_model = ExternalPyomoModel( [m.x], [m.y], [m.residual_eqn], [m.external_eqn], ) for x in x_init_list: external_model.set_input_values(x) jac = external_model.evaluate_jacobian_equality_constraints() # evaluate_jacobian_equality_constraints involves an LU # factorization and repeated back-solve. SciPy returns a # dense matrix from this operation. I am not sure if I should # cast it to a sparse matrix. For now it is dense... self.assertAlmostEqual( jac.toarray()[0][0], model.evaluate_jacobian(x[0]), delta=1e-7, )
def test_full_space_lagrangian_hessians(self): model = Model2by2() m = model.make_model() m.x[0].set_value(1.0) m.x[1].set_value(2.0) m.y[0].set_value(3.0) m.y[1].set_value(4.0) x0_init_list = [-5.0, -3.0, 0.5, 1.0, 2.5] x1_init_list = [0.5, 1.0, 1.5, 2.5, 4.1] lam_init_list = [-2.5, -0.5, 0.0, 1.0, 2.0] init_list = list( itertools.product(x0_init_list, x1_init_list, lam_init_list)) external_model = ExternalPyomoModel( list(m.x.values()), list(m.y.values()), list(m.residual_eqn.values()), list(m.external_eqn.values()), ) for x0, x1, lam in init_list: x = [x0, x1] lam = [lam] external_model.set_input_values(x) # Note that these multiplier calculations are dependent on x, # so if we switch their order, we will get "wrong" answers. # (This is wrong in the sense that the residual and external # multipliers won't necessarily correspond). external_model.set_external_constraint_multipliers(lam) hlxx, hlxy, hlyy = \ external_model.get_full_space_lagrangian_hessians() pred_hlxx, pred_hlxy, pred_hlyy = \ model.calculate_full_space_lagrangian_hessians(lam, x) # TODO: Is comparing the array representation sufficient here? # Should I make sure I get the sparse representation I expect? np.testing.assert_allclose(hlxx.toarray(), pred_hlxx, rtol=1e-8) np.testing.assert_allclose(hlxy.toarray(), pred_hlxy, rtol=1e-8) np.testing.assert_allclose(hlyy.toarray(), pred_hlyy, rtol=1e-8)