.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/optimization_problem/plot_simple_optimization_example.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_optimization_problem_plot_simple_optimization_example.py: How to solve an optimization problem ==================================== .. GENERATED FROM PYTHON SOURCE LINES 26-29 Although the |g| library is dedicated to the :term:`MDO`, it can also be used for mono-disciplinary optimization problems. This example presents some analytical test cases. .. GENERATED FROM PYTHON SOURCE LINES 31-33 Imports ******* .. GENERATED FROM PYTHON SOURCE LINES 33-44 .. code-block:: Python from __future__ import annotations import numpy as np from scipy import optimize from gemseo import create_design_space from gemseo import create_discipline from gemseo import create_scenario from gemseo import execute_post from gemseo import get_available_opt_algorithms .. GENERATED FROM PYTHON SOURCE LINES 45-69 Optimization based on a design of experiments ********************************************* Let :math:`(P)` be a simple optimization problem: .. math:: (P) = \left\{ \begin{aligned} & \underset{x\in\mathbb{N}^2}{\text{minimize}} & & f(x) = x_1 + x_2 \\ & \text{subject to} & & -5 \leq x \leq 5 \end{aligned} \right. In this section, we will see how to use |g| to solve this problem :math:`(P)` by means of a Design Of Experiments (:term:`DOE`) Define the objective function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Firstly, by means of the :func:`.create_discipline` high-level function, we create a :class:`.Discipline` of :class:`.AutoPyDiscipline` type from a Python function. .. GENERATED FROM PYTHON SOURCE LINES 69-78 .. code-block:: Python def f(x1=0.0, x2=0.0): y = x1 + x2 return y discipline = create_discipline("AutoPyDiscipline", py_func=f) .. GENERATED FROM PYTHON SOURCE LINES 79-80 Now, we want to minimize this :class:`.Discipline` over a design of experiments (DOE). .. GENERATED FROM PYTHON SOURCE LINES 82-87 Define the design space ~~~~~~~~~~~~~~~~~~~~~~~ For that, by means of the :func:`.create_design_space` API function, we define the :class:`.DesignSpace` :math:`[-5, 5]\times[-5, 5]` by using its :meth:`~.DesignSpace.add_variable` method. .. GENERATED FROM PYTHON SOURCE LINES 87-92 .. code-block:: Python design_space = create_design_space() design_space.add_variable("x1", 1, lower_bound=-5, upper_bound=5, type_="integer") design_space.add_variable("x2", 1, lower_bound=-5, upper_bound=5, type_="integer") .. GENERATED FROM PYTHON SOURCE LINES 93-98 Define the DOE scenario ~~~~~~~~~~~~~~~~~~~~~~~ Then, by means of the :func:`.create_scenario` high-level function, we define a :class:`.DOEScenario` from the :class:`.Discipline` and the :class:`.DesignSpace` defined above: .. GENERATED FROM PYTHON SOURCE LINES 98-107 .. code-block:: Python scenario = create_scenario( discipline, "y", design_space, formulation_name="DisciplinaryOpt", scenario_type="DOE", ) .. GENERATED FROM PYTHON SOURCE LINES 108-116 Execute the DOE scenario ~~~~~~~~~~~~~~~~~~~~~~~~ Lastly, we solve the :class:`.OptimizationProblem` included in the :class:`.DOEScenario` defined above by minimizing the objective function over a design of experiments included in the :class:`.DesignSpace`. Precisely, we choose a `full factorial design `_ of size :math:`11^2`: .. GENERATED FROM PYTHON SOURCE LINES 116-119 .. code-block:: Python scenario.execute(algo_name="PYDOE_FULLFACT", n_samples=11**2) .. rst-class:: sphx-glr-script-out .. code-block:: none INFO - 16:18:38: *** Start DOEScenario execution *** INFO - 16:18:38: DOEScenario INFO - 16:18:38: Disciplines: f INFO - 16:18:38: MDO formulation: DisciplinaryOpt INFO - 16:18:38: Optimization problem: INFO - 16:18:38: minimize y(x1, x2) INFO - 16:18:38: with respect to x1, x2 INFO - 16:18:38: over the design space: INFO - 16:18:38: +------+-------------+-------+-------------+---------+ INFO - 16:18:38: | Name | Lower bound | Value | Upper bound | Type | INFO - 16:18:38: +------+-------------+-------+-------------+---------+ INFO - 16:18:38: | x1 | -5 | None | 5 | integer | INFO - 16:18:38: | x2 | -5 | None | 5 | integer | INFO - 16:18:38: +------+-------------+-------+-------------+---------+ INFO - 16:18:38: Solving optimization problem with algorithm PYDOE_FULLFACT: INFO - 16:18:38: 1%| | 1/121 [00:00<00:00, 455.85 it/sec, feas=True, obj=-10] INFO - 16:18:38: 2%|▏ | 2/121 [00:00<00:00, 732.37 it/sec, feas=True, obj=-9] INFO - 16:18:38: 2%|▏ | 3/121 [00:00<00:00, 933.59 it/sec, feas=True, obj=-8] INFO - 16:18:38: 3%|▎ | 4/121 [00:00<00:00, 1088.79 it/sec, feas=True, obj=-7] INFO - 16:18:38: 4%|▍ | 5/121 [00:00<00:00, 1209.22 it/sec, feas=True, obj=-6] INFO - 16:18:38: 5%|▍ | 6/121 [00:00<00:00, 1308.88 it/sec, feas=True, obj=-5] INFO - 16:18:38: 6%|▌ | 7/121 [00:00<00:00, 1393.59 it/sec, feas=True, obj=-4] INFO - 16:18:38: 7%|▋ | 8/121 [00:00<00:00, 1460.86 it/sec, feas=True, obj=-3] INFO - 16:18:38: 7%|▋ | 9/121 [00:00<00:00, 1522.99 it/sec, feas=True, obj=-2] INFO - 16:18:38: 8%|▊ | 10/121 [00:00<00:00, 1584.01 it/sec, feas=True, obj=-1] INFO - 16:18:38: 9%|▉ | 11/121 [00:00<00:00, 1625.36 it/sec, feas=True, obj=0] INFO - 16:18:38: 10%|▉ | 12/121 [00:00<00:00, 1672.26 it/sec, feas=True, obj=-9] INFO - 16:18:38: 11%|█ | 13/121 [00:00<00:00, 1707.46 it/sec, feas=True, obj=-8] INFO - 16:18:38: 12%|█▏ | 14/121 [00:00<00:00, 1746.28 it/sec, feas=True, obj=-7] INFO - 16:18:38: 12%|█▏ | 15/121 [00:00<00:00, 1769.75 it/sec, feas=True, obj=-6] INFO - 16:18:38: 13%|█▎ | 16/121 [00:00<00:00, 1801.68 it/sec, feas=True, obj=-5] INFO - 16:18:38: 14%|█▍ | 17/121 [00:00<00:00, 1824.50 it/sec, feas=True, obj=-4] INFO - 16:18:38: 15%|█▍ | 18/121 [00:00<00:00, 1844.46 it/sec, feas=True, obj=-3] INFO - 16:18:38: 16%|█▌ | 19/121 [00:00<00:00, 1864.22 it/sec, feas=True, obj=-2] INFO - 16:18:38: 17%|█▋ | 20/121 [00:00<00:00, 1882.50 it/sec, feas=True, obj=-1] INFO - 16:18:38: 17%|█▋ | 21/121 [00:00<00:00, 1900.25 it/sec, feas=True, obj=0] INFO - 16:18:38: 18%|█▊ | 22/121 [00:00<00:00, 1915.37 it/sec, feas=True, obj=1] INFO - 16:18:38: 19%|█▉ | 23/121 [00:00<00:00, 1929.50 it/sec, feas=True, obj=-8] INFO - 16:18:38: 20%|█▉ | 24/121 [00:00<00:00, 1941.88 it/sec, feas=True, obj=-7] INFO - 16:18:38: 21%|██ | 25/121 [00:00<00:00, 1948.08 it/sec, feas=True, obj=-6] INFO - 16:18:38: 21%|██▏ | 26/121 [00:00<00:00, 1963.70 it/sec, feas=True, obj=-5] INFO - 16:18:38: 22%|██▏ | 27/121 [00:00<00:00, 1968.78 it/sec, feas=True, obj=-4] INFO - 16:18:38: 23%|██▎ | 28/121 [00:00<00:00, 1982.79 it/sec, feas=True, obj=-3] INFO - 16:18:38: 24%|██▍ | 29/121 [00:00<00:00, 1990.72 it/sec, feas=True, obj=-2] INFO - 16:18:38: 25%|██▍ | 30/121 [00:00<00:00, 2001.93 it/sec, feas=True, obj=-1] INFO - 16:18:38: 26%|██▌ | 31/121 [00:00<00:00, 2013.99 it/sec, feas=True, obj=0] INFO - 16:18:38: 26%|██▋ | 32/121 [00:00<00:00, 2018.22 it/sec, feas=True, obj=1] INFO - 16:18:38: 27%|██▋ | 33/121 [00:00<00:00, 2029.26 it/sec, feas=True, obj=2] INFO - 16:18:38: 28%|██▊ | 34/121 [00:00<00:00, 2034.04 it/sec, feas=True, obj=-7] INFO - 16:18:38: 29%|██▉ | 35/121 [00:00<00:00, 2044.18 it/sec, feas=True, obj=-6] INFO - 16:18:38: 30%|██▉ | 36/121 [00:00<00:00, 2048.89 it/sec, feas=True, obj=-5] INFO - 16:18:38: 31%|███ | 37/121 [00:00<00:00, 2055.65 it/sec, feas=True, obj=-4] INFO - 16:18:38: 31%|███▏ | 38/121 [00:00<00:00, 2057.97 it/sec, feas=True, obj=-3] INFO - 16:18:38: 32%|███▏ | 39/121 [00:00<00:00, 2066.32 it/sec, feas=True, obj=-2] INFO - 16:18:38: 33%|███▎ | 40/121 [00:00<00:00, 2071.70 it/sec, feas=True, obj=-1] INFO - 16:18:38: 34%|███▍ | 41/121 [00:00<00:00, 2077.77 it/sec, feas=True, obj=0] INFO - 16:18:38: 35%|███▍ | 42/121 [00:00<00:00, 2082.75 it/sec, feas=True, obj=1] INFO - 16:18:38: 36%|███▌ | 43/121 [00:00<00:00, 2088.29 it/sec, feas=True, obj=2] INFO - 16:18:38: 36%|███▋ | 44/121 [00:00<00:00, 2093.32 it/sec, feas=True, obj=3] INFO - 16:18:38: 37%|███▋ | 45/121 [00:00<00:00, 2096.50 it/sec, feas=True, obj=-6] INFO - 16:18:38: 38%|███▊ | 46/121 [00:00<00:00, 2100.17 it/sec, feas=True, obj=-5] INFO - 16:18:38: 39%|███▉ | 47/121 [00:00<00:00, 2106.63 it/sec, feas=True, obj=-4] INFO - 16:18:38: 40%|███▉ | 48/121 [00:00<00:00, 2095.56 it/sec, feas=True, obj=-3] INFO - 16:18:38: 40%|████ | 49/121 [00:00<00:00, 2098.89 it/sec, feas=True, obj=-2] INFO - 16:18:38: 41%|████▏ | 50/121 [00:00<00:00, 2102.20 it/sec, feas=True, obj=-1] INFO - 16:18:38: 42%|████▏ | 51/121 [00:00<00:00, 2105.93 it/sec, feas=True, obj=0] INFO - 16:18:38: 43%|████▎ | 52/121 [00:00<00:00, 2109.38 it/sec, feas=True, obj=1] INFO - 16:18:38: 44%|████▍ | 53/121 [00:00<00:00, 2112.76 it/sec, feas=True, obj=2] INFO - 16:18:38: 45%|████▍ | 54/121 [00:00<00:00, 2114.95 it/sec, feas=True, obj=3] INFO - 16:18:38: 45%|████▌ | 55/121 [00:00<00:00, 2118.04 it/sec, feas=True, obj=4] INFO - 16:18:38: 46%|████▋ | 56/121 [00:00<00:00, 2122.91 it/sec, feas=True, obj=-5] INFO - 16:18:38: 47%|████▋ | 57/121 [00:00<00:00, 2124.06 it/sec, feas=True, obj=-4] INFO - 16:18:38: 48%|████▊ | 58/121 [00:00<00:00, 2129.20 it/sec, feas=True, obj=-3] INFO - 16:18:38: 49%|████▉ | 59/121 [00:00<00:00, 2130.83 it/sec, feas=True, obj=-2] INFO - 16:18:38: 50%|████▉ | 60/121 [00:00<00:00, 2133.85 it/sec, feas=True, obj=-1] INFO - 16:18:38: 50%|█████ | 61/121 [00:00<00:00, 2136.75 it/sec, feas=True, obj=0] INFO - 16:18:38: 51%|█████ | 62/121 [00:00<00:00, 2139.93 it/sec, feas=True, obj=1] INFO - 16:18:38: 52%|█████▏ | 63/121 [00:00<00:00, 2144.74 it/sec, feas=True, obj=2] INFO - 16:18:38: 53%|█████▎ | 64/121 [00:00<00:00, 2145.03 it/sec, feas=True, obj=3] INFO - 16:18:38: 54%|█████▎ | 65/121 [00:00<00:00, 2149.57 it/sec, feas=True, obj=4] INFO - 16:18:38: 55%|█████▍ | 66/121 [00:00<00:00, 2150.04 it/sec, feas=True, obj=5] INFO - 16:18:38: 55%|█████▌ | 67/121 [00:00<00:00, 2150.20 it/sec, feas=True, obj=-4] INFO - 16:18:38: 56%|█████▌ | 68/121 [00:00<00:00, 2151.44 it/sec, feas=True, obj=-3] INFO - 16:18:38: 57%|█████▋ | 69/121 [00:00<00:00, 2154.61 it/sec, feas=True, obj=-2] INFO - 16:18:38: 58%|█████▊ | 70/121 [00:00<00:00, 2154.11 it/sec, feas=True, obj=-1] INFO - 16:18:38: 59%|█████▊ | 71/121 [00:00<00:00, 2157.92 it/sec, feas=True, obj=0] INFO - 16:18:38: 60%|█████▉ | 72/121 [00:00<00:00, 2159.82 it/sec, feas=True, obj=1] INFO - 16:18:38: 60%|██████ | 73/121 [00:00<00:00, 2161.39 it/sec, feas=True, obj=2] INFO - 16:18:38: 61%|██████ | 74/121 [00:00<00:00, 2163.43 it/sec, feas=True, obj=3] INFO - 16:18:38: 62%|██████▏ | 75/121 [00:00<00:00, 2164.35 it/sec, feas=True, obj=4] INFO - 16:18:38: 63%|██████▎ | 76/121 [00:00<00:00, 2166.23 it/sec, feas=True, obj=5] INFO - 16:18:38: 64%|██████▎ | 77/121 [00:00<00:00, 2168.14 it/sec, feas=True, obj=6] INFO - 16:18:38: 64%|██████▍ | 78/121 [00:00<00:00, 2169.91 it/sec, feas=True, obj=-3] INFO - 16:18:38: 65%|██████▌ | 79/121 [00:00<00:00, 2173.44 it/sec, feas=True, obj=-2] INFO - 16:18:38: 66%|██████▌ | 80/121 [00:00<00:00, 2173.38 it/sec, feas=True, obj=-1] INFO - 16:18:38: 67%|██████▋ | 81/121 [00:00<00:00, 2176.54 it/sec, feas=True, obj=0] INFO - 16:18:38: 68%|██████▊ | 82/121 [00:00<00:00, 2177.15 it/sec, feas=True, obj=1] INFO - 16:18:38: 69%|██████▊ | 83/121 [00:00<00:00, 2180.10 it/sec, feas=True, obj=2] INFO - 16:18:38: 69%|██████▉ | 84/121 [00:00<00:00, 2181.15 it/sec, feas=True, obj=3] INFO - 16:18:38: 70%|███████ | 85/121 [00:00<00:00, 2183.98 it/sec, feas=True, obj=4] INFO - 16:18:38: 71%|███████ | 86/121 [00:00<00:00, 2185.41 it/sec, feas=True, obj=5] INFO - 16:18:38: 72%|███████▏ | 87/121 [00:00<00:00, 2186.72 it/sec, feas=True, obj=6] INFO - 16:18:38: 73%|███████▎ | 88/121 [00:00<00:00, 2188.42 it/sec, feas=True, obj=7] INFO - 16:18:38: 74%|███████▎ | 89/121 [00:00<00:00, 2189.57 it/sec, feas=True, obj=-2] INFO - 16:18:38: 74%|███████▍ | 90/121 [00:00<00:00, 2190.76 it/sec, feas=True, obj=-1] INFO - 16:18:38: 75%|███████▌ | 91/121 [00:00<00:00, 2191.10 it/sec, feas=True, obj=0] INFO - 16:18:38: 76%|███████▌ | 92/121 [00:00<00:00, 2192.24 it/sec, feas=True, obj=1] INFO - 16:18:38: 77%|███████▋ | 93/121 [00:00<00:00, 2194.90 it/sec, feas=True, obj=2] INFO - 16:18:38: 78%|███████▊ | 94/121 [00:00<00:00, 2194.38 it/sec, feas=True, obj=3] INFO - 16:18:38: 79%|███████▊ | 95/121 [00:00<00:00, 2196.84 it/sec, feas=True, obj=4] INFO - 16:18:38: 79%|███████▉ | 96/121 [00:00<00:00, 2197.22 it/sec, feas=True, obj=5] INFO - 16:18:38: 80%|████████ | 97/121 [00:00<00:00, 2199.50 it/sec, feas=True, obj=6] INFO - 16:18:38: 81%|████████ | 98/121 [00:00<00:00, 2200.31 it/sec, feas=True, obj=7] INFO - 16:18:38: 82%|████████▏ | 99/121 [00:00<00:00, 2202.40 it/sec, feas=True, obj=8] INFO - 16:18:38: 83%|████████▎ | 100/121 [00:00<00:00, 2203.32 it/sec, feas=True, obj=-1] INFO - 16:18:38: 83%|████████▎ | 101/121 [00:00<00:00, 2203.39 it/sec, feas=True, obj=0] INFO - 16:18:38: 84%|████████▍ | 102/121 [00:00<00:00, 2204.35 it/sec, feas=True, obj=1] INFO - 16:18:38: 85%|████████▌ | 103/121 [00:00<00:00, 2205.67 it/sec, feas=True, obj=2] INFO - 16:18:38: 86%|████████▌ | 104/121 [00:00<00:00, 2207.10 it/sec, feas=True, obj=3] INFO - 16:18:38: 87%|████████▋ | 105/121 [00:00<00:00, 2208.16 it/sec, feas=True, obj=4] INFO - 16:18:38: 88%|████████▊ | 106/121 [00:00<00:00, 2209.29 it/sec, feas=True, obj=5] INFO - 16:18:38: 88%|████████▊ | 107/121 [00:00<00:00, 2210.94 it/sec, feas=True, obj=6] INFO - 16:18:38: 89%|████████▉ | 108/121 [00:00<00:00, 2210.39 it/sec, feas=True, obj=7] INFO - 16:18:38: 90%|█████████ | 109/121 [00:00<00:00, 2211.93 it/sec, feas=True, obj=8] INFO - 16:18:38: 91%|█████████ | 110/121 [00:00<00:00, 2211.26 it/sec, feas=True, obj=9] INFO - 16:18:38: 92%|█████████▏| 111/121 [00:00<00:00, 2212.01 it/sec, feas=True, obj=0] INFO - 16:18:38: 93%|█████████▎| 112/121 [00:00<00:00, 2213.10 it/sec, feas=True, obj=1] INFO - 16:18:38: 93%|█████████▎| 113/121 [00:00<00:00, 2215.12 it/sec, feas=True, obj=2] INFO - 16:18:38: 94%|█████████▍| 114/121 [00:00<00:00, 2215.08 it/sec, feas=True, obj=3] INFO - 16:18:38: 95%|█████████▌| 115/121 [00:00<00:00, 2216.82 it/sec, feas=True, obj=4] INFO - 16:18:38: 96%|█████████▌| 116/121 [00:00<00:00, 2217.70 it/sec, feas=True, obj=5] INFO - 16:18:38: 97%|█████████▋| 117/121 [00:00<00:00, 2218.67 it/sec, feas=True, obj=6] INFO - 16:18:38: 98%|█████████▊| 118/121 [00:00<00:00, 2219.57 it/sec, feas=True, obj=7] INFO - 16:18:38: 98%|█████████▊| 119/121 [00:00<00:00, 2220.52 it/sec, feas=True, obj=8] INFO - 16:18:38: 99%|█████████▉| 120/121 [00:00<00:00, 2221.39 it/sec, feas=True, obj=9] INFO - 16:18:38: 100%|██████████| 121/121 [00:00<00:00, 2207.84 it/sec, feas=True, obj=10] INFO - 16:18:38: Optimization result: INFO - 16:18:38: Optimizer info: INFO - 16:18:38: Status: None INFO - 16:18:38: Message: None INFO - 16:18:38: Solution: INFO - 16:18:38: Objective: -10.0 INFO - 16:18:38: Design space: INFO - 16:18:38: +------+-------------+-------+-------------+---------+ INFO - 16:18:38: | Name | Lower bound | Value | Upper bound | Type | INFO - 16:18:38: +------+-------------+-------+-------------+---------+ INFO - 16:18:38: | x1 | -5 | -5 | 5 | integer | INFO - 16:18:38: | x2 | -5 | -5 | 5 | integer | INFO - 16:18:38: +------+-------------+-------+-------------+---------+ INFO - 16:18:38: *** End DOEScenario execution *** .. GENERATED FROM PYTHON SOURCE LINES 120-122 The optimum results can be found in the execution log. It is also possible to extract them from the :attr:`.BaseScenario.optimization_result`. .. GENERATED FROM PYTHON SOURCE LINES 122-128 .. code-block:: Python optimization_result = scenario.optimization_result print( f"The solution of P is (x*,f(x*)) = ({optimization_result.x_opt}, {optimization_result.f_opt})" ) .. rst-class:: sphx-glr-script-out .. code-block:: none The solution of P is (x*,f(x*)) = ([-5. -5.], -10.0) .. GENERATED FROM PYTHON SOURCE LINES 129-151 Optimization based on a quasi-Newton method by means of the `SciPy `_ library ************************************************************************************************* Let :math:`(P)` be a simple optimization problem: .. math:: (P) = \left\{ \begin{aligned} & \underset{x}{\text{minimize}} & & f(x) = \sin(x) - \exp(x) \\ & \text{subject to} & & -2 \leq x \leq 2 \end{aligned} \right. In this section, we will see how to use |g| to solve this problem :math:`(P)` by means of an optimizer directly used from the `SciPy `_ library. Define the objective function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Firstly, we create the objective function and its gradient as standard Python functions: .. GENERATED FROM PYTHON SOURCE LINES 151-163 .. code-block:: Python def g(x=0): y = np.sin(x) - np.exp(x) return y def dgdx(x=0): y = np.cos(x) - np.exp(x) return y .. GENERATED FROM PYTHON SOURCE LINES 164-169 Minimize the objective function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now, we can minimize this Python function over its design space by means of the `L-BFGS-B algorithm `_ implemented in the function ``scipy.optimize.fmin_l_bfgs_b``. .. GENERATED FROM PYTHON SOURCE LINES 169-174 .. code-block:: Python x_0 = -0.5 * np.ones(1) opt = optimize.fmin_l_bfgs_b(g, x_0, fprime=dgdx, bounds=[(-0.2, 2.0)]) x_opt, f_opt, _ = opt .. GENERATED FROM PYTHON SOURCE LINES 175-176 Then, we can display the solution of our optimization problem with the following code: .. GENERATED FROM PYTHON SOURCE LINES 176-179 .. code-block:: Python print(f"The solution of P is (x*,f(x*)) = ({x_opt[0]}, {f_opt}).") .. rst-class:: sphx-glr-script-out .. code-block:: none The solution of P is (x*,f(x*)) = (-0.2, -1.017400083873043). .. GENERATED FROM PYTHON SOURCE LINES 180-185 .. seealso:: You can find the SciPy implementation of the L-BFGS-B algorithm `by clicking here `_. .. GENERATED FROM PYTHON SOURCE LINES 187-211 Optimization based on a quasi-Newton method by means of the |g| optimization interface ************************************************************************************** Let :math:`(P)` be a simple optimization problem: .. math:: (P) = \left\{ \begin{aligned} & \underset{x}{\text{minimize}} & & f(x) = \sin(x) - \exp(x) \\ & \text{subject to} & & -2 \leq x \leq 2 \end{aligned} \right. In this section, we will see how to use |g| to solve this problem :math:`(P)` by means of an optimizer from `SciPy `_ called through the optimization interface of |g|. Define the objective function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Firstly, by means of the :func:`.create_discipline` high-level function, we create an :class:`.Discipline` of :class:`.AutoPyDiscipline` type from a Python function: .. GENERATED FROM PYTHON SOURCE LINES 211-225 .. code-block:: Python def g(x=0): y = np.sin(x) - np.exp(x) return y def dgdx(x=0): y = np.cos(x) - np.exp(x) return y discipline = create_discipline("AutoPyDiscipline", py_func=g, py_jac=dgdx) .. GENERATED FROM PYTHON SOURCE LINES 226-235 Now, we can to minimize this :class:`.Discipline` over a design space, by means of a quasi-Newton method from the initial point :math:`0.5`. Define the design space ~~~~~~~~~~~~~~~~~~~~~~~ For that, by means of the :func:`.create_design_space` high-level function, we define the :class:`.DesignSpace` :math:`[-2., 2.]` with initial value :math:`0.5` by using its :meth:`~.DesignSpace.add_variable` method. .. GENERATED FROM PYTHON SOURCE LINES 235-241 .. code-block:: Python design_space = create_design_space() design_space.add_variable( "x", 1, lower_bound=-2.0, upper_bound=2.0, value=-0.5 * np.ones(1) ) .. GENERATED FROM PYTHON SOURCE LINES 242-247 Define the optimization problem ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Then, by means of the :func:`.create_scenario` high-level function, we define an :class:`.MDOScenario` from the :class:`.Discipline` and the :class:`.DesignSpace` defined above: .. GENERATED FROM PYTHON SOURCE LINES 247-256 .. code-block:: Python scenario = create_scenario( discipline, "y", design_space, formulation_name="DisciplinaryOpt", scenario_type="MDO", ) .. GENERATED FROM PYTHON SOURCE LINES 257-266 Execute the optimization problem ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Lastly, we solve the :class:`.OptimizationProblem` included in the :class:`.MDOScenario` defined above by minimizing the objective function over the :class:`.DesignSpace`. Precisely, we choose the `L-BFGS-B algorithm `_ implemented in the function ``scipy.optimize.fmin_l_bfgs_b`` and indirectly called by means of the class :class:`.OptimizationLibraryFactory` and of its function :meth:`~.BaseAlgoFactory.execute`: .. GENERATED FROM PYTHON SOURCE LINES 266-269 .. code-block:: Python scenario.execute(algo_name="L-BFGS-B", max_iter=100) .. rst-class:: sphx-glr-script-out .. code-block:: none INFO - 16:18:38: *** Start MDOScenario execution *** INFO - 16:18:38: MDOScenario INFO - 16:18:38: Disciplines: g INFO - 16:18:38: MDO formulation: DisciplinaryOpt INFO - 16:18:38: Optimization problem: INFO - 16:18:38: minimize y(x) INFO - 16:18:38: with respect to x INFO - 16:18:38: over the design space: INFO - 16:18:38: +------+-------------+-------+-------------+-------+ INFO - 16:18:38: | Name | Lower bound | Value | Upper bound | Type | INFO - 16:18:38: +------+-------------+-------+-------------+-------+ INFO - 16:18:38: | x | -2 | -0.5 | 2 | float | INFO - 16:18:38: +------+-------------+-------+-------------+-------+ INFO - 16:18:38: Solving optimization problem with algorithm L-BFGS-B: INFO - 16:18:38: 1%| | 1/100 [00:00<00:00, 366.12 it/sec, feas=True, obj=-1.09] INFO - 16:18:38: 2%|▏ | 2/100 [00:00<00:00, 572.56 it/sec, feas=True, obj=-1.04] INFO - 16:18:38: 3%|▎ | 3/100 [00:00<00:00, 701.66 it/sec, feas=True, obj=-1.24] INFO - 16:18:38: 4%|▍ | 4/100 [00:00<00:00, 745.62 it/sec, feas=True, obj=-1.23] INFO - 16:18:38: 5%|▌ | 5/100 [00:00<00:00, 764.99 it/sec, feas=True, obj=-1.24] INFO - 16:18:38: 6%|▌ | 6/100 [00:00<00:00, 781.40 it/sec, feas=True, obj=-1.24] INFO - 16:18:38: 7%|▋ | 7/100 [00:00<00:00, 777.81 it/sec, feas=True, obj=-1.24] INFO - 16:18:38: Optimization result: INFO - 16:18:38: Optimizer info: INFO - 16:18:38: Status: 0 INFO - 16:18:38: Message: CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL INFO - 16:18:38: Solution: INFO - 16:18:38: Objective: -1.2361083418592416 INFO - 16:18:38: Design space: INFO - 16:18:38: +------+-------------+--------------------+-------------+-------+ INFO - 16:18:38: | Name | Lower bound | Value | Upper bound | Type | INFO - 16:18:38: +------+-------------+--------------------+-------------+-------+ INFO - 16:18:38: | x | -2 | -1.292695718944152 | 2 | float | INFO - 16:18:38: +------+-------------+--------------------+-------------+-------+ INFO - 16:18:38: *** End MDOScenario execution *** .. GENERATED FROM PYTHON SOURCE LINES 270-272 The optimization results are displayed in the log file. They can also be obtained using the following code: .. GENERATED FROM PYTHON SOURCE LINES 272-278 .. code-block:: Python optimization_result = scenario.optimization_result print( f"The solution of P is (x*,f(x*)) = ({optimization_result.x_opt}, {optimization_result.f_opt})." ) .. rst-class:: sphx-glr-script-out .. code-block:: none The solution of P is (x*,f(x*)) = ([-1.29269572], -1.2361083418592416). .. GENERATED FROM PYTHON SOURCE LINES 279-287 .. seealso:: You can find the `SciPy `_ implementation of the `L-BFGS-B algorithm `_ algorithm `by clicking here `_. In order to get the list of available optimization algorithms, use: .. GENERATED FROM PYTHON SOURCE LINES 288-292 .. code-block:: Python algo_list = get_available_opt_algorithms() print(f"Available algorithms: {algo_list}") .. rst-class:: sphx-glr-script-out .. code-block:: none Available algorithms: ['Augmented_Lagrangian_order_0', 'Augmented_Lagrangian_order_1', 'Scipy_MILP', 'HEXALY', 'MMA', 'MNBI', 'MultiStart', 'NLOPT_MMA', 'NLOPT_COBYLA', 'NLOPT_SLSQP', 'NLOPT_BOBYQA', 'NLOPT_BFGS', 'NLOPT_NEWUOA', 'PDFO_COBYLA', 'PDFO_BOBYQA', 'PDFO_NEWUOA', 'PYOPTSPARSE_SLSQP', 'PYOPTSPARSE_SNOPT', 'PYMOO_GA', 'PYMOO_NSGA2', 'PYMOO_NSGA3', 'PYMOO_UNSGA3', 'PYMOO_RNSGA3', 'DUAL_ANNEALING', 'SHGO', 'DIFFERENTIAL_EVOLUTION', 'INTERIOR_POINT', 'DUAL_SIMPLEX', 'SLSQP', 'L-BFGS-B', 'TNC', 'NELDER-MEAD', 'COBYQA', 'SBO'] .. GENERATED FROM PYTHON SOURCE LINES 293-298 Saving and post-processing ************************** After the resolution of the :class:`~gemseo.algos.optimization_problem.OptimizationProblem`, we can export the results into an :term:`HDF` file: .. GENERATED FROM PYTHON SOURCE LINES 298-302 .. code-block:: Python problem = scenario.formulation.optimization_problem problem.to_hdf("my_optim.hdf5") .. rst-class:: sphx-glr-script-out .. code-block:: none INFO - 16:18:38: Exporting the optimization problem to the file my_optim.hdf5 .. GENERATED FROM PYTHON SOURCE LINES 303-306 We can also post-process the optimization history by means of the function :func:`.execute_post`, either from the :class:`~gemseo.algos.optimization_problem.OptimizationProblem`: .. GENERATED FROM PYTHON SOURCE LINES 306-309 .. code-block:: Python execute_post(problem, post_name="OptHistoryView", save=False, show=True) .. rst-class:: sphx-glr-horizontal * .. image-sg:: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_001.png :alt: Evolution of the optimization variables :srcset: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_001.png :class: sphx-glr-multi-img * .. image-sg:: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_002.png :alt: Evolution of the objective value :srcset: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_002.png :class: sphx-glr-multi-img * .. image-sg:: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_003.png :alt: Evolution of the distance to the optimum :srcset: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_003.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 310-311 or from the :term:`HDF` file created above: .. GENERATED FROM PYTHON SOURCE LINES 311-313 .. code-block:: Python execute_post("my_optim.hdf5", post_name="OptHistoryView", save=False, show=True) .. rst-class:: sphx-glr-horizontal * .. image-sg:: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_004.png :alt: Evolution of the optimization variables :srcset: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_004.png :class: sphx-glr-multi-img * .. image-sg:: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_005.png :alt: Evolution of the objective value :srcset: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_005.png :class: sphx-glr-multi-img * .. image-sg:: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_006.png :alt: Evolution of the distance to the optimum :srcset: /examples/optimization_problem/images/sphx_glr_plot_simple_optimization_example_006.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none INFO - 16:18:39: Importing the optimization problem from the file my_optim.hdf5 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.859 seconds) .. _sphx_glr_download_examples_optimization_problem_plot_simple_optimization_example.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_simple_optimization_example.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_simple_optimization_example.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_simple_optimization_example.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_