From d6a13b6170c825b0b5828ce6d26130e9e638248f Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Thu, 6 Mar 2025 11:01:06 +0100 Subject: [PATCH 1/7] fix: fixed bug where the method OptimizationResult.from_optimization_problem failed when giving as an input an OptimizationProblem object. --- changelog/fragments/1450.fixed.rst | 1 + src/gemseo/algos/optimization_result.py | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 changelog/fragments/1450.fixed.rst diff --git a/changelog/fragments/1450.fixed.rst b/changelog/fragments/1450.fixed.rst new file mode 100644 index 0000000000..65536b8624 --- /dev/null +++ b/changelog/fragments/1450.fixed.rst @@ -0,0 +1 @@ +The method OptimizationResult.from_optimization_problem() properly returns an OptimizationResult object when giving an OptimizationProblem as an argument. diff --git a/src/gemseo/algos/optimization_result.py b/src/gemseo/algos/optimization_result.py index 90480f709d..c9d3c781d5 100644 --- a/src/gemseo/algos/optimization_result.py +++ b/src/gemseo/algos/optimization_result.py @@ -237,6 +237,8 @@ class OptimizationResult(metaclass=ABCGoogleDocstringInheritanceMeta): Returns: The optimization result associated with the optimization problem. """ + if problem.solution: + return problem.solution if not problem.database: return cls(n_obj_call=0, **fields_) -- GitLab From 2230d114da5fcb0c77852fa690d1a89617c8b5f1 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Mon, 10 Mar 2025 09:34:53 +0100 Subject: [PATCH 2/7] test added. --- tests/algos/test_opt_result_multiobj.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/algos/test_opt_result_multiobj.py b/tests/algos/test_opt_result_multiobj.py index 6e5c6b4eb0..ae4be30e99 100644 --- a/tests/algos/test_opt_result_multiobj.py +++ b/tests/algos/test_opt_result_multiobj.py @@ -30,6 +30,7 @@ from gemseo.algos.multiobjective_optimization_result import ( ) from gemseo.algos.opt.factory import OptimizationLibraryFactory from gemseo.algos.optimization_problem import OptimizationProblem +from gemseo.algos.optimization_result import OptimizationResult from gemseo.problems.multiobjective_optimization.binh_korn import BinhKorn @@ -55,6 +56,16 @@ def test_export_hdf(problem: OptimizationProblem, tmpdir): assert len(read_solution.pareto_front.f_optima) > 7 +def test_opt_result_from_opt_problem(problem: OptimizationProblem, tmpdir): + """Test the creation of an OptimizationResult from an OptimizationProblem.""" + out_file = tmpdir / "output.hdf" + problem.to_hdf(out_file) + read_problem = OptimizationProblem.from_hdf(out_file) + opt_result = OptimizationResult.from_optimization_problem(read_problem) + assert isinstance(opt_result, MultiObjectiveOptimizationResult) + assert read_problem.solution == opt_result + + @pytest.mark.parametrize("solved", [True, False]) def test_str(problem, solved): """Test the string representation of the multi objective result.""" -- GitLab From 9063414bdd277a91e61d856e881b0d6f2cb13ad9 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 11 Mar 2025 09:09:18 +0100 Subject: [PATCH 3/7] test added. --- src/gemseo/algos/optimization_result.py | 4 ++-- tests/algos/test_opt_result_multiobj.py | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gemseo/algos/optimization_result.py b/src/gemseo/algos/optimization_result.py index c9d3c781d5..1baf6126e4 100644 --- a/src/gemseo/algos/optimization_result.py +++ b/src/gemseo/algos/optimization_result.py @@ -237,8 +237,8 @@ class OptimizationResult(metaclass=ABCGoogleDocstringInheritanceMeta): Returns: The optimization result associated with the optimization problem. """ - if problem.solution: - return problem.solution + if problem.solution and not hasattr(problem.objective, "n_calls"): + problem.objective.n_calls = problem.solution.n_obj_call if not problem.database: return cls(n_obj_call=0, **fields_) diff --git a/tests/algos/test_opt_result_multiobj.py b/tests/algos/test_opt_result_multiobj.py index ae4be30e99..edb8e3af75 100644 --- a/tests/algos/test_opt_result_multiobj.py +++ b/tests/algos/test_opt_result_multiobj.py @@ -62,8 +62,7 @@ def test_opt_result_from_opt_problem(problem: OptimizationProblem, tmpdir): problem.to_hdf(out_file) read_problem = OptimizationProblem.from_hdf(out_file) opt_result = OptimizationResult.from_optimization_problem(read_problem) - assert isinstance(opt_result, MultiObjectiveOptimizationResult) - assert read_problem.solution == opt_result + assert isinstance(opt_result, OptimizationResult) @pytest.mark.parametrize("solved", [True, False]) -- GitLab From 378e4bd15acec3e3c0c791a7a2d1cb9220d80e62 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 11 Mar 2025 13:33:28 +0000 Subject: [PATCH 4/7] Corrections. --- changelog/fragments/1450.fixed.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/fragments/1450.fixed.rst b/changelog/fragments/1450.fixed.rst index 65536b8624..145a57ec05 100644 --- a/changelog/fragments/1450.fixed.rst +++ b/changelog/fragments/1450.fixed.rst @@ -1 +1 @@ -The method OptimizationResult.from_optimization_problem() properly returns an OptimizationResult object when giving an OptimizationProblem as an argument. +The method ``OptimizationResult.from_optimization_problem()`` properly returns an ``OptimizationResult`` object when giving an ``OptimizationProblem`` as an argument. -- GitLab From ba7c51fa6e5a656bcd8789d599490ead7ce85267 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 11 Mar 2025 14:38:40 +0100 Subject: [PATCH 5/7] refact: moved test to tests.algos.opt.test_opt_result.py --- tests/algos/opt/test_opt_result.py | 15 +++++++++++++++ tests/algos/test_opt_result_multiobj.py | 10 ---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/algos/opt/test_opt_result.py b/tests/algos/opt/test_opt_result.py index 430c8291d5..7990931f81 100644 --- a/tests/algos/opt/test_opt_result.py +++ b/tests/algos/opt/test_opt_result.py @@ -24,10 +24,12 @@ from numpy import array from gemseo import execute_algo from gemseo.algos.design_space import DesignSpace +from gemseo.algos.opt.factory import OptimizationLibraryFactory from gemseo.algos.optimization_problem import OptimizationProblem from gemseo.algos.optimization_result import OptimizationResult from gemseo.core.mdo_functions.mdo_function import MDOFunction from gemseo.disciplines.analytic import AnalyticDiscipline +from gemseo.problems.multiobjective_optimization.binh_korn import BinhKorn from gemseo.scenarios.doe_scenario import DOEScenario from gemseo.utils.repr_html import REPR_HTML_WRAPPER @@ -229,3 +231,16 @@ def test_from_optimization_problem( constraint_values={f"[g{sign}1.0]": array([constraint])}, constraints_grad={f"[g{sign}1.0]": None}, ) + + +def test_opt_result_from_opt_problem(tmpdir): + """Test the creation of an OptimizationResult from an OptimizationProblem.""" + problem = BinhKorn() + OptimizationLibraryFactory().execute( + problem, algo_name="MNBI", max_iter=100, n_sub_optim=5, sub_optim_algo="SLSQP" + ) + out_file = tmpdir / "output.hdf" + problem.to_hdf(out_file) + read_problem = OptimizationProblem.from_hdf(out_file) + opt_result = OptimizationResult.from_optimization_problem(read_problem) + assert isinstance(opt_result, OptimizationResult) diff --git a/tests/algos/test_opt_result_multiobj.py b/tests/algos/test_opt_result_multiobj.py index edb8e3af75..6e5c6b4eb0 100644 --- a/tests/algos/test_opt_result_multiobj.py +++ b/tests/algos/test_opt_result_multiobj.py @@ -30,7 +30,6 @@ from gemseo.algos.multiobjective_optimization_result import ( ) from gemseo.algos.opt.factory import OptimizationLibraryFactory from gemseo.algos.optimization_problem import OptimizationProblem -from gemseo.algos.optimization_result import OptimizationResult from gemseo.problems.multiobjective_optimization.binh_korn import BinhKorn @@ -56,15 +55,6 @@ def test_export_hdf(problem: OptimizationProblem, tmpdir): assert len(read_solution.pareto_front.f_optima) > 7 -def test_opt_result_from_opt_problem(problem: OptimizationProblem, tmpdir): - """Test the creation of an OptimizationResult from an OptimizationProblem.""" - out_file = tmpdir / "output.hdf" - problem.to_hdf(out_file) - read_problem = OptimizationProblem.from_hdf(out_file) - opt_result = OptimizationResult.from_optimization_problem(read_problem) - assert isinstance(opt_result, OptimizationResult) - - @pytest.mark.parametrize("solved", [True, False]) def test_str(problem, solved): """Test the string representation of the multi objective result.""" -- GitLab From 27deb3bb9fe608e3518f7b4e8a3a320ed66b9762 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 11 Mar 2025 15:01:30 +0100 Subject: [PATCH 6/7] test: changed test problem from Binhkorn to Power2. --- tests/algos/opt/test_opt_result.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/algos/opt/test_opt_result.py b/tests/algos/opt/test_opt_result.py index 7990931f81..332761cd12 100644 --- a/tests/algos/opt/test_opt_result.py +++ b/tests/algos/opt/test_opt_result.py @@ -29,7 +29,7 @@ from gemseo.algos.optimization_problem import OptimizationProblem from gemseo.algos.optimization_result import OptimizationResult from gemseo.core.mdo_functions.mdo_function import MDOFunction from gemseo.disciplines.analytic import AnalyticDiscipline -from gemseo.problems.multiobjective_optimization.binh_korn import BinhKorn +from gemseo.problems.optimization.power_2 import Power2 from gemseo.scenarios.doe_scenario import DOEScenario from gemseo.utils.repr_html import REPR_HTML_WRAPPER @@ -235,10 +235,8 @@ def test_from_optimization_problem( def test_opt_result_from_opt_problem(tmpdir): """Test the creation of an OptimizationResult from an OptimizationProblem.""" - problem = BinhKorn() - OptimizationLibraryFactory().execute( - problem, algo_name="MNBI", max_iter=100, n_sub_optim=5, sub_optim_algo="SLSQP" - ) + problem = Power2() + OptimizationLibraryFactory().execute(problem, algo_name="SLSQP", max_iter=50) out_file = tmpdir / "output.hdf" problem.to_hdf(out_file) read_problem = OptimizationProblem.from_hdf(out_file) -- GitLab From 4d33acf82e1109b228ea570742465a9a88a9a6a6 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 11 Mar 2025 16:34:37 +0100 Subject: [PATCH 7/7] test: changed tmpdir to tmp_path. --- tests/algos/opt/test_opt_result.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/algos/opt/test_opt_result.py b/tests/algos/opt/test_opt_result.py index 332761cd12..84bcf3aede 100644 --- a/tests/algos/opt/test_opt_result.py +++ b/tests/algos/opt/test_opt_result.py @@ -233,11 +233,11 @@ def test_from_optimization_problem( ) -def test_opt_result_from_opt_problem(tmpdir): +def test_opt_result_from_opt_problem(tmp_path): """Test the creation of an OptimizationResult from an OptimizationProblem.""" problem = Power2() OptimizationLibraryFactory().execute(problem, algo_name="SLSQP", max_iter=50) - out_file = tmpdir / "output.hdf" + out_file = tmp_path / "output.hdf" problem.to_hdf(out_file) read_problem = OptimizationProblem.from_hdf(out_file) opt_result = OptimizationResult.from_optimization_problem(read_problem) -- GitLab