From 9da03132594fe3ddbef0e160adbb7a121a7e3259 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Mon, 28 Jul 2025 10:08:57 +0200 Subject: [PATCH 1/8] added: hock and schittkowski problem 71. --- .../optimization/hock_schittkowski_71.py | 186 ++++++++++++++++++ .../optimization/test_hock_schittkowski_71.py | 69 +++++++ 2 files changed, 255 insertions(+) create mode 100644 src/gemseo/problems/optimization/hock_schittkowski_71.py create mode 100644 tests/problems/optimization/test_hock_schittkowski_71.py diff --git a/src/gemseo/problems/optimization/hock_schittkowski_71.py b/src/gemseo/problems/optimization/hock_schittkowski_71.py new file mode 100644 index 0000000000..a229f71150 --- /dev/null +++ b/src/gemseo/problems/optimization/hock_schittkowski_71.py @@ -0,0 +1,186 @@ +# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 3 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +r"""Hock & Schittkowski problem 71. + +This module implements the Hock & Schittkowski non-linear programming problem 71. + +See: Willi Hock and Klaus Schittkowski. (1981) Test Examples for +Nonlinear Programming Codes. Lecture Notes in Economics and Mathematical +Systems Vol. 187, Springer-Verlag. +Based on MATLAB code by Peter Carbonetto. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import numpy as np +from numpy import array + +from gemseo.algos.design_space import DesignSpace +from gemseo.algos.optimization_problem import OptimizationProblem +from gemseo.core.mdo_functions.mdo_function import MDOFunction + +if TYPE_CHECKING: + from gemseo.typing import NumberArray + + +class HockSchittkowski71(OptimizationProblem): + """Hock and Schittkowski problem 71.""" + + def __init__( + self, + initial_guess: NumberArray = (1.0, 5.0, 5.0, 1.0), + ): + """Initialize the Hock Schittkowski 71 problem. + + Args: + initial_guess: The initial guess for the optimal solution. + """ + design_space = DesignSpace() + design_space.add_variable( + "x", + size=4, + lower_bound=[1.0, 1.0, 1.0, 1.0], + upper_bound=[5.0, 5.0, 5.0, 5.0], + ) + + design_space.set_current_value(array(initial_guess)) + + super().__init__(design_space) + + self.objective = MDOFunction( + self.compute_objective, + name="hock_schittkoski_71", + f_type=MDOFunction.FunctionType.OBJ, + jac=self.compute_objective_jacobian, + expr="x_1 * x_4 * (x_1 + x_2 +x_3 + x_4) + x_3", + input_names=["x"], + dim=1, + ) + + constraint = MDOFunction( + self.compute_constraint, + name="constraint", + f_type=MDOFunction.ConstraintType.INEQ, + jac=self.compute_constraint_jacobian, + expr="[25 - (x_1 * x_2 * x_3 * x_4)," + "(x_1 * x_2 * x_3 * x_4) - 2e19," + "40 - (x_1**2 + x_2**2 + x_3**2 + x_4**2)," + "(x_1**2 + x_2**2 + x_3**2 + x_4**2) - 40]", + input_names=["x"], + dim=4, + ) + self.add_constraint(constraint, constraint_type=MDOFunction.ConstraintType.INEQ) + + @staticmethod + def compute_objective(design_variables: NumberArray) -> NumberArray: + """Compute the objectives of the Hock and Schittkowski 71 function. + + Args: + design_variables: The design variables vector. + + Returns: + The objective function value. + """ + return ( + design_variables[0] * design_variables[3] * np.sum(design_variables[0:3]) + + design_variables[2] + ) + + @staticmethod + def compute_objective_jacobian(design_variables: NumberArray) -> NumberArray: + """Compute the jacobian of objective function. + + Args: + design_variables: The design variables vector. + + Returns: + The gradient of the objective functions wrt the design variables. + """ + x_1, x_2, x_3, x_4 = design_variables + + return np.array([ + x_1 * x_4 + x_4 * (x_1 + x_2 + x_3 + x_4), + x_1 * x_4, + x_1 * x_4 + 1.0, + x_1 * (x_1 + x_2 + x_3 + x_4), + ]) + + @staticmethod + def compute_constraint(design_variables: NumberArray) -> NumberArray: + """Compute the constraint function. + + Args: + design_variables: The design variables vector. + + Returns: + The constraint's value. + """ + # The problem bounds the constraint on both sides, therefore the 2-dimension + # constraint turns into a 4-dimension so that it can be an inequality. + + x_1, x_2, x_3, x_4 = design_variables + + constraint = [ + x_1 * x_2 * x_3 * x_4, + x_1**2 + x_2**2 + x_3**2 + x_4**2, + ] + return np.array([ + 25.0 - constraint[0], + constraint[0] - 2.0e19, + 40.0 - constraint[1], + constraint[1] - 40.0, + ]) + + @staticmethod + def compute_constraint_jacobian(design_variables: NumberArray) -> NumberArray: + """Compute the constraint's jacobian. + + Args: + design_variables: The design variables vector. + + Returns: + The gradient of the first constraint function wrt the design variables. + """ + x_1, x_2, x_3, x_4 = design_variables + + return np.array([ + [ + -x_2 * x_3 * x_4, + -x_1 * x_3 * x_4, + -x_1 * x_2 * x_4, + -x_1 * x_2 * x_3, + ], + [ + x_2 * x_3 * x_4, + x_1 * x_3 * x_4, + x_1 * x_2 * x_4, + x_1 * x_2 * x_3, + ], + [ + -2 * x_1, + -2 * x_2, + -2 * x_3, + -2 * x_4, + ], + [ + 2 * x_1, + 2 * x_2, + 2 * x_3, + 2 * x_4, + ], + ]) diff --git a/tests/problems/optimization/test_hock_schittkowski_71.py b/tests/problems/optimization/test_hock_schittkowski_71.py new file mode 100644 index 0000000000..89b0421df7 --- /dev/null +++ b/tests/problems/optimization/test_hock_schittkowski_71.py @@ -0,0 +1,69 @@ +# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 3 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +"""Tests for the Hock and Schittkowski problem 71.""" + +from __future__ import annotations + +import pytest +from numpy import array +from numpy.testing import assert_allclose + +from gemseo.problems.optimization.hock_schittkowski_71 import HockSchittkowski71 + + +@pytest.fixture +def hock_schittkowski_71() -> HockSchittkowski71: + """Create a :class:`.HockSchittkowski71` optimization problem. + + Returns: + A HockSchittkowski71 instance. + """ + return HockSchittkowski71(initial_guess=array([1.0, 1.0, 1.0, 1.0])) + + +def test_obj_jacobian(hock_schittkowski_71): + """Test the jacobian of the Hock and Schittkowski 71 objective function. + + Args: + hock_schittkowski_71: Fixture returning a HockSchittkowski71 + `OptimizationProblem`. + """ + x_dv = array([1.0, 1.0, 1.0, 1.0]) + + jac = hock_schittkowski_71.objective.jac(x_dv) + + assert_allclose([5.0, 1.0, 2.0, 4.0], jac) + + +def test_constraints_jacobian(hock_schittkowski_71): + """Test the jacobian the Hock and Schittkowski 71 constraint functions. + + Args: + hock_schittkowski_71: Fixture returning a HockSchittkowski71 + `OptimizationProblem`. + """ + x_dv = array([1.0, 1.0, 1.0, 1.0]) + + jac = hock_schittkowski_71.constraints[0].jac(x_dv) + assert_allclose( + [ + [-1.0, -1.0, -1.0, -1.0], + [1.0, 1.0, 1.0, 1.0], + [-2.0, -2.0, -2.0, -2.0], + [2.0, 2.0, 2.0, 2.0], + ], + jac, + ) -- GitLab From f4f2a011ec44170af0fa19536d108430fb23cbe5 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Mon, 28 Jul 2025 15:06:19 +0200 Subject: [PATCH 2/8] fix: correction on the hs71 problem. The cyipopt version is different from the original due to how it handles the constraints. test: Increased coverage. --- .../optimization/hock_schittkowski_71.py | 117 ++++++++++-------- .../optimization/test_hock_schittkowski_71.py | 67 ++++++++-- 2 files changed, 123 insertions(+), 61 deletions(-) diff --git a/src/gemseo/problems/optimization/hock_schittkowski_71.py b/src/gemseo/problems/optimization/hock_schittkowski_71.py index a229f71150..e52e10ccb4 100644 --- a/src/gemseo/problems/optimization/hock_schittkowski_71.py +++ b/src/gemseo/problems/optimization/hock_schittkowski_71.py @@ -72,19 +72,31 @@ class HockSchittkowski71(OptimizationProblem): dim=1, ) - constraint = MDOFunction( - self.compute_constraint, - name="constraint", + equality_constraint = MDOFunction( + self.compute_equality_constraint, + name="equality_constraint", f_type=MDOFunction.ConstraintType.INEQ, - jac=self.compute_constraint_jacobian, - expr="[25 - (x_1 * x_2 * x_3 * x_4)," - "(x_1 * x_2 * x_3 * x_4) - 2e19," - "40 - (x_1**2 + x_2**2 + x_3**2 + x_4**2)," - "(x_1**2 + x_2**2 + x_3**2 + x_4**2) - 40]", + jac=self.compute_equality_constraint_jacobian, + expr="(x_1**2 + x_2**2 + x_3**2 + x_4**2) - 40", input_names=["x"], - dim=4, + dim=1, + ) + self.add_constraint( + equality_constraint, constraint_type=MDOFunction.ConstraintType.EQ + ) + + inequality_constraint = MDOFunction( + self.compute_inequality_constraint, + name="inequality_constraint", + f_type=MDOFunction.ConstraintType.INEQ, + jac=self.compute_inequality_constraint_jacobian, + expr="[25 - (x_1 * x_2 * x_3 * x_4)", + input_names=["x"], + dim=1, + ) + self.add_constraint( + inequality_constraint, constraint_type=MDOFunction.ConstraintType.INEQ ) - self.add_constraint(constraint, constraint_type=MDOFunction.ConstraintType.INEQ) @staticmethod def compute_objective(design_variables: NumberArray) -> NumberArray: @@ -97,7 +109,7 @@ class HockSchittkowski71(OptimizationProblem): The objective function value. """ return ( - design_variables[0] * design_variables[3] * np.sum(design_variables[0:3]) + design_variables[0] * design_variables[3] * (design_variables.sum()) + design_variables[2] ) @@ -121,66 +133,69 @@ class HockSchittkowski71(OptimizationProblem): ]) @staticmethod - def compute_constraint(design_variables: NumberArray) -> NumberArray: - """Compute the constraint function. + def compute_equality_constraint(design_variables: NumberArray) -> NumberArray: + """Compute the equality constraint function. Args: design_variables: The design variables vector. Returns: - The constraint's value. + The equality constraint's value. """ - # The problem bounds the constraint on both sides, therefore the 2-dimension - # constraint turns into a 4-dimension so that it can be an inequality. + x_1, x_2, x_3, x_4 = design_variables + return np.array([x_1**2 + x_2**2 + x_3**2 + x_4**2 - 40]) + + @staticmethod + def compute_inequality_constraint(design_variables: NumberArray) -> NumberArray: + """Compute the inequality constraint function. + Args: + design_variables: The design variables vector. + + Returns: + The equality constraint's value. + """ + x_1, x_2, x_3, x_4 = design_variables + return np.array([25 - x_1 * x_2 * x_3 * x_4]) + + @staticmethod + def compute_equality_constraint_jacobian( + design_variables: NumberArray, + ) -> NumberArray: + """Compute the equality constraint's jacobian. + + Args: + design_variables: The design variables vector. + + Returns: + The jacobian of the equality constraint function wrt the design variables. + """ x_1, x_2, x_3, x_4 = design_variables - constraint = [ - x_1 * x_2 * x_3 * x_4, - x_1**2 + x_2**2 + x_3**2 + x_4**2, - ] return np.array([ - 25.0 - constraint[0], - constraint[0] - 2.0e19, - 40.0 - constraint[1], - constraint[1] - 40.0, + 2 * x_1, + 2 * x_2, + 2 * x_3, + 2 * x_4, ]) @staticmethod - def compute_constraint_jacobian(design_variables: NumberArray) -> NumberArray: - """Compute the constraint's jacobian. + def compute_inequality_constraint_jacobian( + design_variables: NumberArray, + ) -> NumberArray: + """Compute the inequality constraint's jacobian. Args: design_variables: The design variables vector. Returns: - The gradient of the first constraint function wrt the design variables. + The jacobian of the inequality constraint function wrt the design variables. """ x_1, x_2, x_3, x_4 = design_variables return np.array([ - [ - -x_2 * x_3 * x_4, - -x_1 * x_3 * x_4, - -x_1 * x_2 * x_4, - -x_1 * x_2 * x_3, - ], - [ - x_2 * x_3 * x_4, - x_1 * x_3 * x_4, - x_1 * x_2 * x_4, - x_1 * x_2 * x_3, - ], - [ - -2 * x_1, - -2 * x_2, - -2 * x_3, - -2 * x_4, - ], - [ - 2 * x_1, - 2 * x_2, - 2 * x_3, - 2 * x_4, - ], + -x_2 * x_3 * x_4, + -x_1 * x_3 * x_4, + -x_1 * x_2 * x_4, + -x_1 * x_2 * x_3, ]) diff --git a/tests/problems/optimization/test_hock_schittkowski_71.py b/tests/problems/optimization/test_hock_schittkowski_71.py index 89b0421df7..19bc5b360a 100644 --- a/tests/problems/optimization/test_hock_schittkowski_71.py +++ b/tests/problems/optimization/test_hock_schittkowski_71.py @@ -48,8 +48,8 @@ def test_obj_jacobian(hock_schittkowski_71): assert_allclose([5.0, 1.0, 2.0, 4.0], jac) -def test_constraints_jacobian(hock_schittkowski_71): - """Test the jacobian the Hock and Schittkowski 71 constraint functions. +def test_equality_constraint_jacobian(hock_schittkowski_71): + """Test the equality constraint function's jacobian of Hock and Schittkowski 71. Args: hock_schittkowski_71: Fixture returning a HockSchittkowski71 @@ -58,12 +58,59 @@ def test_constraints_jacobian(hock_schittkowski_71): x_dv = array([1.0, 1.0, 1.0, 1.0]) jac = hock_schittkowski_71.constraints[0].jac(x_dv) - assert_allclose( - [ - [-1.0, -1.0, -1.0, -1.0], - [1.0, 1.0, 1.0, 1.0], - [-2.0, -2.0, -2.0, -2.0], - [2.0, 2.0, 2.0, 2.0], - ], - jac, + assert_allclose([2, 2, 2, 2], jac) + + +def test_inequality_constraint_jacobian(hock_schittkowski_71): + """Test the inequality constraint function's jacobian of Hock and Schittkowski 71. + + Args: + hock_schittkowski_71: Fixture returning a HockSchittkowski71 + `OptimizationProblem`. + """ + x_dv = array([1.0, 1.0, 1.0, 1.0]) + + jac = hock_schittkowski_71.constraints[1].jac(x_dv) + assert_allclose([-1, -1, -1, -1], jac) + + +def test_compute_objective(hock_schittkowski_71): + """Test the objective function of the Hock and Schittkowski 71 problem. + + Args: + hock_schittkowski_71: Fixture returning a HockSchittkowski71 + `OptimizationProblem`. + """ + objective = hock_schittkowski_71.compute_objective( + hock_schittkowski_71.design_space.get_current_value() + ) + + assert objective == 5.0 + + +def test_compute_equality_constraint(hock_schittkowski_71): + """Test the equality constraint function of the Hock and Schittkowski 71 problem. + + Args: + hock_schittkowski_71: Fixture returning a HockSchittkowski71 + `OptimizationProblem`. + """ + + equality_constraint = hock_schittkowski_71.compute_equality_constraint( + hock_schittkowski_71.design_space.get_current_value() + ) + assert equality_constraint == -36.0 + + +def test_compute_inequality_constraint(hock_schittkowski_71): + """Test the inequality constraint function of the Hock and Schittkowski 71 problem. + + Args: + hock_schittkowski_71: Fixture returning a HockSchittkowski71 + `OptimizationProblem`. + """ + + inequality_constraint = hock_schittkowski_71.compute_inequality_constraint( + hock_schittkowski_71.design_space.get_current_value() ) + assert inequality_constraint == 24.0 -- GitLab From f8421a793069f507f93867b90a8ae438d7f43810 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Mon, 28 Jul 2025 14:00:37 +0000 Subject: [PATCH 3/8] suggestions. --- .../optimization/hock_schittkowski_71.py | 16 ++++++++-------- .../optimization/test_hock_schittkowski_71.py | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/gemseo/problems/optimization/hock_schittkowski_71.py b/src/gemseo/problems/optimization/hock_schittkowski_71.py index e52e10ccb4..5bea84e7f8 100644 --- a/src/gemseo/problems/optimization/hock_schittkowski_71.py +++ b/src/gemseo/problems/optimization/hock_schittkowski_71.py @@ -75,7 +75,7 @@ class HockSchittkowski71(OptimizationProblem): equality_constraint = MDOFunction( self.compute_equality_constraint, name="equality_constraint", - f_type=MDOFunction.ConstraintType.INEQ, + f_type=MDOFunction.ConstraintType.EQ, jac=self.compute_equality_constraint_jacobian, expr="(x_1**2 + x_2**2 + x_3**2 + x_4**2) - 40", input_names=["x"], @@ -90,7 +90,7 @@ class HockSchittkowski71(OptimizationProblem): name="inequality_constraint", f_type=MDOFunction.ConstraintType.INEQ, jac=self.compute_inequality_constraint_jacobian, - expr="[25 - (x_1 * x_2 * x_3 * x_4)", + expr="25 - (x_1 * x_2 * x_3 * x_4)", input_names=["x"], dim=1, ) @@ -115,7 +115,7 @@ class HockSchittkowski71(OptimizationProblem): @staticmethod def compute_objective_jacobian(design_variables: NumberArray) -> NumberArray: - """Compute the jacobian of objective function. + """Compute the Jacobian of objective function. Args: design_variables: The design variables vector. @@ -153,7 +153,7 @@ class HockSchittkowski71(OptimizationProblem): design_variables: The design variables vector. Returns: - The equality constraint's value. + The inequality constraint's value. """ x_1, x_2, x_3, x_4 = design_variables return np.array([25 - x_1 * x_2 * x_3 * x_4]) @@ -162,13 +162,13 @@ class HockSchittkowski71(OptimizationProblem): def compute_equality_constraint_jacobian( design_variables: NumberArray, ) -> NumberArray: - """Compute the equality constraint's jacobian. + """Compute the equality constraint's Jacobian. Args: design_variables: The design variables vector. Returns: - The jacobian of the equality constraint function wrt the design variables. + The Jacobian of the equality constraint function wrt the design variables. """ x_1, x_2, x_3, x_4 = design_variables @@ -183,13 +183,13 @@ class HockSchittkowski71(OptimizationProblem): def compute_inequality_constraint_jacobian( design_variables: NumberArray, ) -> NumberArray: - """Compute the inequality constraint's jacobian. + """Compute the inequality constraint's Jacobian. Args: design_variables: The design variables vector. Returns: - The jacobian of the inequality constraint function wrt the design variables. + The Jacobian of the inequality constraint function wrt the design variables. """ x_1, x_2, x_3, x_4 = design_variables diff --git a/tests/problems/optimization/test_hock_schittkowski_71.py b/tests/problems/optimization/test_hock_schittkowski_71.py index 19bc5b360a..615248ec81 100644 --- a/tests/problems/optimization/test_hock_schittkowski_71.py +++ b/tests/problems/optimization/test_hock_schittkowski_71.py @@ -35,7 +35,7 @@ def hock_schittkowski_71() -> HockSchittkowski71: def test_obj_jacobian(hock_schittkowski_71): - """Test the jacobian of the Hock and Schittkowski 71 objective function. + """Test the Jacobian of the Hock and Schittkowski 71 objective function. Args: hock_schittkowski_71: Fixture returning a HockSchittkowski71 @@ -49,7 +49,7 @@ def test_obj_jacobian(hock_schittkowski_71): def test_equality_constraint_jacobian(hock_schittkowski_71): - """Test the equality constraint function's jacobian of Hock and Schittkowski 71. + """Test the equality constraint function's Jacobian of Hock and Schittkowski 71. Args: hock_schittkowski_71: Fixture returning a HockSchittkowski71 @@ -62,7 +62,7 @@ def test_equality_constraint_jacobian(hock_schittkowski_71): def test_inequality_constraint_jacobian(hock_schittkowski_71): - """Test the inequality constraint function's jacobian of Hock and Schittkowski 71. + """Test the inequality constraint function's Jacobian of Hock and Schittkowski 71. Args: hock_schittkowski_71: Fixture returning a HockSchittkowski71 @@ -78,7 +78,7 @@ def test_compute_objective(hock_schittkowski_71): """Test the objective function of the Hock and Schittkowski 71 problem. Args: - hock_schittkowski_71: Fixture returning a HockSchittkowski71 + hock_schittkowski_71: Fixture returning a HockSchittkowski71 `OptimizationProblem`. """ objective = hock_schittkowski_71.compute_objective( @@ -92,7 +92,7 @@ def test_compute_equality_constraint(hock_schittkowski_71): """Test the equality constraint function of the Hock and Schittkowski 71 problem. Args: - hock_schittkowski_71: Fixture returning a HockSchittkowski71 + hock_schittkowski_71: Fixture returning a HockSchittkowski71 `OptimizationProblem`. """ @@ -106,7 +106,7 @@ def test_compute_inequality_constraint(hock_schittkowski_71): """Test the inequality constraint function of the Hock and Schittkowski 71 problem. Args: - hock_schittkowski_71: Fixture returning a HockSchittkowski71 + hock_schittkowski_71: Fixture returning a HockSchittkowski71 `OptimizationProblem`. """ -- GitLab From 7f62846487468ce8c9436281eb7f1e9eef76c5e0 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 29 Jul 2025 10:35:58 +0200 Subject: [PATCH 4/8] fix: correction on the hs71 problem's jacobian. Added analytical solution and test. --- .../problems/optimization/hock_schittkowski_71.py | 13 ++++++++++++- .../optimization/test_hock_schittkowski_71.py | 11 +++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gemseo/problems/optimization/hock_schittkowski_71.py b/src/gemseo/problems/optimization/hock_schittkowski_71.py index 5bea84e7f8..728eb6ce96 100644 --- a/src/gemseo/problems/optimization/hock_schittkowski_71.py +++ b/src/gemseo/problems/optimization/hock_schittkowski_71.py @@ -129,7 +129,7 @@ class HockSchittkowski71(OptimizationProblem): x_1 * x_4 + x_4 * (x_1 + x_2 + x_3 + x_4), x_1 * x_4, x_1 * x_4 + 1.0, - x_1 * (x_1 + x_2 + x_3 + x_4), + x_1 * x_4 + x_1 * (x_1 + x_2 + x_3 + x_4), ]) @staticmethod @@ -199,3 +199,14 @@ class HockSchittkowski71(OptimizationProblem): -x_1 * x_2 * x_4, -x_1 * x_2 * x_3, ]) + + @staticmethod + def get_solution() -> tuple[NumberArray, NumberArray]: + """Return the analytical solution of the problem. + + Returns: + The theoretical optimum of the problem. + """ + x_opt = array([0.99999999, 4.74299964, 3.82114998, 1.37940829]) + f_opt = x_opt[0] * x_opt[3] * np.sum(x_opt) + x_opt[2] + return x_opt, f_opt diff --git a/tests/problems/optimization/test_hock_schittkowski_71.py b/tests/problems/optimization/test_hock_schittkowski_71.py index 615248ec81..1f7051e449 100644 --- a/tests/problems/optimization/test_hock_schittkowski_71.py +++ b/tests/problems/optimization/test_hock_schittkowski_71.py @@ -114,3 +114,14 @@ def test_compute_inequality_constraint(hock_schittkowski_71): hock_schittkowski_71.design_space.get_current_value() ) assert inequality_constraint == 24.0 + + +def test_solution(hock_schittkowski_71) -> None: + """Check the objective value at the solution. + + Args: + hock_schittkowski_71: Fixture returning a HockSchittkowski71 + `OptimizationProblem`. + """ + x_opt, f_opt = hock_schittkowski_71.get_solution() + assert hock_schittkowski_71.objective.evaluate(x_opt) == pytest.approx(f_opt) -- GitLab From cd656b726d29174e6a1856f82986756da86e74a1 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 29 Jul 2025 09:08:23 +0000 Subject: [PATCH 5/8] suggestions --- .../optimization/hock_schittkowski_71.py | 15 +++++++-------- .../optimization/test_hock_schittkowski_71.py | 17 ++++++----------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/gemseo/problems/optimization/hock_schittkowski_71.py b/src/gemseo/problems/optimization/hock_schittkowski_71.py index 728eb6ce96..b58a2b8e95 100644 --- a/src/gemseo/problems/optimization/hock_schittkowski_71.py +++ b/src/gemseo/problems/optimization/hock_schittkowski_71.py @@ -27,7 +27,6 @@ from __future__ import annotations from typing import TYPE_CHECKING -import numpy as np from numpy import array from gemseo.algos.design_space import DesignSpace @@ -109,7 +108,7 @@ class HockSchittkowski71(OptimizationProblem): The objective function value. """ return ( - design_variables[0] * design_variables[3] * (design_variables.sum()) + design_variables[0] * design_variables[3] * (sum(design_variables[0:3])) + design_variables[2] ) @@ -125,8 +124,8 @@ class HockSchittkowski71(OptimizationProblem): """ x_1, x_2, x_3, x_4 = design_variables - return np.array([ - x_1 * x_4 + x_4 * (x_1 + x_2 + x_3 + x_4), + return array([ + x_1 * x_4 + x_4 * (x_1 + x_2 + x_3), x_1 * x_4, x_1 * x_4 + 1.0, x_1 * x_4 + x_1 * (x_1 + x_2 + x_3 + x_4), @@ -143,7 +142,7 @@ class HockSchittkowski71(OptimizationProblem): The equality constraint's value. """ x_1, x_2, x_3, x_4 = design_variables - return np.array([x_1**2 + x_2**2 + x_3**2 + x_4**2 - 40]) + return array([x_1**2 + x_2**2 + x_3**2 + x_4**2 - 40]) @staticmethod def compute_inequality_constraint(design_variables: NumberArray) -> NumberArray: @@ -156,7 +155,7 @@ class HockSchittkowski71(OptimizationProblem): The inequality constraint's value. """ x_1, x_2, x_3, x_4 = design_variables - return np.array([25 - x_1 * x_2 * x_3 * x_4]) + return array([25 - x_1 * x_2 * x_3 * x_4]) @staticmethod def compute_equality_constraint_jacobian( @@ -172,7 +171,7 @@ class HockSchittkowski71(OptimizationProblem): """ x_1, x_2, x_3, x_4 = design_variables - return np.array([ + return array([ 2 * x_1, 2 * x_2, 2 * x_3, @@ -193,7 +192,7 @@ class HockSchittkowski71(OptimizationProblem): """ x_1, x_2, x_3, x_4 = design_variables - return np.array([ + return array([ -x_2 * x_3 * x_4, -x_1 * x_3 * x_4, -x_1 * x_2 * x_4, diff --git a/tests/problems/optimization/test_hock_schittkowski_71.py b/tests/problems/optimization/test_hock_schittkowski_71.py index 1f7051e449..cbac9d971d 100644 --- a/tests/problems/optimization/test_hock_schittkowski_71.py +++ b/tests/problems/optimization/test_hock_schittkowski_71.py @@ -21,7 +21,9 @@ import pytest from numpy import array from numpy.testing import assert_allclose +from gemseo import execute_algo from gemseo.problems.optimization.hock_schittkowski_71 import HockSchittkowski71 +from gemseo.settings.opt import SLSQP_Settings @pytest.fixture @@ -31,7 +33,7 @@ def hock_schittkowski_71() -> HockSchittkowski71: Returns: A HockSchittkowski71 instance. """ - return HockSchittkowski71(initial_guess=array([1.0, 1.0, 1.0, 1.0])) + return HockSchittkowski71(initial_guess=array([1.0, 5.0, 5.0, 1.0])) def test_obj_jacobian(hock_schittkowski_71): @@ -42,10 +44,7 @@ def test_obj_jacobian(hock_schittkowski_71): `OptimizationProblem`. """ x_dv = array([1.0, 1.0, 1.0, 1.0]) - - jac = hock_schittkowski_71.objective.jac(x_dv) - - assert_allclose([5.0, 1.0, 2.0, 4.0], jac) + hock_schittkowski_71.objective.check_grad(x_dv, error_max=1e-6) def test_equality_constraint_jacobian(hock_schittkowski_71): @@ -56,9 +55,7 @@ def test_equality_constraint_jacobian(hock_schittkowski_71): `OptimizationProblem`. """ x_dv = array([1.0, 1.0, 1.0, 1.0]) - - jac = hock_schittkowski_71.constraints[0].jac(x_dv) - assert_allclose([2, 2, 2, 2], jac) + hock_schittkowski_71.constraints[0].check_grad(x_dv, error_max=1e-6) def test_inequality_constraint_jacobian(hock_schittkowski_71): @@ -69,9 +66,7 @@ def test_inequality_constraint_jacobian(hock_schittkowski_71): `OptimizationProblem`. """ x_dv = array([1.0, 1.0, 1.0, 1.0]) - - jac = hock_schittkowski_71.constraints[1].jac(x_dv) - assert_allclose([-1, -1, -1, -1], jac) + hock_schittkowski_71.constraints[1].check_grad(x_dv, error_max=1e-6) def test_compute_objective(hock_schittkowski_71): -- GitLab From 20fb8658ef55c73c024f4715d81e1c976bb34866 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 29 Jul 2025 11:12:09 +0200 Subject: [PATCH 6/8] corrections. --- src/gemseo/problems/optimization/hock_schittkowski_71.py | 4 ++-- tests/problems/optimization/test_hock_schittkowski_71.py | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gemseo/problems/optimization/hock_schittkowski_71.py b/src/gemseo/problems/optimization/hock_schittkowski_71.py index b58a2b8e95..8b6029addd 100644 --- a/src/gemseo/problems/optimization/hock_schittkowski_71.py +++ b/src/gemseo/problems/optimization/hock_schittkowski_71.py @@ -66,7 +66,7 @@ class HockSchittkowski71(OptimizationProblem): name="hock_schittkoski_71", f_type=MDOFunction.FunctionType.OBJ, jac=self.compute_objective_jacobian, - expr="x_1 * x_4 * (x_1 + x_2 +x_3 + x_4) + x_3", + expr="x_1 * x_4 * (x_1 + x_2 + x_3) + x_3", input_names=["x"], dim=1, ) @@ -207,5 +207,5 @@ class HockSchittkowski71(OptimizationProblem): The theoretical optimum of the problem. """ x_opt = array([0.99999999, 4.74299964, 3.82114998, 1.37940829]) - f_opt = x_opt[0] * x_opt[3] * np.sum(x_opt) + x_opt[2] + f_opt = x_opt[0] * x_opt[3] * sum(x_opt[0:3]) + x_opt[2] return x_opt, f_opt diff --git a/tests/problems/optimization/test_hock_schittkowski_71.py b/tests/problems/optimization/test_hock_schittkowski_71.py index cbac9d971d..d5993294d7 100644 --- a/tests/problems/optimization/test_hock_schittkowski_71.py +++ b/tests/problems/optimization/test_hock_schittkowski_71.py @@ -19,11 +19,8 @@ from __future__ import annotations import pytest from numpy import array -from numpy.testing import assert_allclose -from gemseo import execute_algo from gemseo.problems.optimization.hock_schittkowski_71 import HockSchittkowski71 -from gemseo.settings.opt import SLSQP_Settings @pytest.fixture -- GitLab From 5e14ed3deb8d222bc23fb892fa0c929f1395cbfd Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 29 Jul 2025 11:25:57 +0200 Subject: [PATCH 7/8] corrections. --- src/gemseo/problems/optimization/hock_schittkowski_71.py | 2 +- tests/problems/optimization/test_analytical.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gemseo/problems/optimization/hock_schittkowski_71.py b/src/gemseo/problems/optimization/hock_schittkowski_71.py index 8b6029addd..9d9c8c0d25 100644 --- a/src/gemseo/problems/optimization/hock_schittkowski_71.py +++ b/src/gemseo/problems/optimization/hock_schittkowski_71.py @@ -128,7 +128,7 @@ class HockSchittkowski71(OptimizationProblem): x_1 * x_4 + x_4 * (x_1 + x_2 + x_3), x_1 * x_4, x_1 * x_4 + 1.0, - x_1 * x_4 + x_1 * (x_1 + x_2 + x_3 + x_4), + x_1 * (x_1 + x_2 + x_3), ]) @staticmethod diff --git a/tests/problems/optimization/test_analytical.py b/tests/problems/optimization/test_analytical.py index 834c9f18fa..d0cd52bdc6 100644 --- a/tests/problems/optimization/test_analytical.py +++ b/tests/problems/optimization/test_analytical.py @@ -27,6 +27,7 @@ from numpy import zeros from gemseo.algos.base_driver_library import MaxIterReachedException from gemseo.algos.opt.factory import OptimizationLibraryFactory +from gemseo.problems.optimization.hock_schittkowski_71 import HockSchittkowski71 from gemseo.problems.optimization.power_2 import Power2 from gemseo.problems.optimization.rastrigin import Rastrigin from gemseo.problems.optimization.rosen_mf import RosenMF @@ -83,3 +84,9 @@ def test_rosen_mf() -> None: step=1e-8, threshold=1e-4, ) + + +def test_hs071() -> None: + """""" + problem = HockSchittkowski71() + run_and_test_problem(problem) -- GitLab From 548ba82e34480d43fb5e1faa6696dd956c6dbaea Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 29 Jul 2025 11:58:08 +0200 Subject: [PATCH 8/8] fixed tests. --- .../optimization/test_hock_schittkowski_71.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/tests/problems/optimization/test_hock_schittkowski_71.py b/tests/problems/optimization/test_hock_schittkowski_71.py index d5993294d7..ad49658b51 100644 --- a/tests/problems/optimization/test_hock_schittkowski_71.py +++ b/tests/problems/optimization/test_hock_schittkowski_71.py @@ -73,11 +73,10 @@ def test_compute_objective(hock_schittkowski_71): hock_schittkowski_71: Fixture returning a HockSchittkowski71 `OptimizationProblem`. """ - objective = hock_schittkowski_71.compute_objective( - hock_schittkowski_71.design_space.get_current_value() - ) + x_dv = array([1.0, 1.0, 1.0, 1.0]) + objective = hock_schittkowski_71.compute_objective(x_dv) - assert objective == 5.0 + assert objective == 4.0 def test_compute_equality_constraint(hock_schittkowski_71): @@ -87,10 +86,8 @@ def test_compute_equality_constraint(hock_schittkowski_71): hock_schittkowski_71: Fixture returning a HockSchittkowski71 `OptimizationProblem`. """ - - equality_constraint = hock_schittkowski_71.compute_equality_constraint( - hock_schittkowski_71.design_space.get_current_value() - ) + x_dv = array([1.0, 1.0, 1.0, 1.0]) + equality_constraint = hock_schittkowski_71.compute_equality_constraint(x_dv) assert equality_constraint == -36.0 @@ -101,10 +98,8 @@ def test_compute_inequality_constraint(hock_schittkowski_71): hock_schittkowski_71: Fixture returning a HockSchittkowski71 `OptimizationProblem`. """ - - inequality_constraint = hock_schittkowski_71.compute_inequality_constraint( - hock_schittkowski_71.design_space.get_current_value() - ) + x_dv = array([1.0, 1.0, 1.0, 1.0]) + inequality_constraint = hock_schittkowski_71.compute_inequality_constraint(x_dv) assert inequality_constraint == 24.0 -- GitLab