.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/mdo/plot_opt_as_mdo.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_mdo_plot_opt_as_mdo.py: Make a monodisciplinary optimization problem multidisciplinary ============================================================== Introduction ------------ The :class:`.OptAsMDOScenario` is a class to make a monodisciplinary optimization problem multidisciplinary :cite:`AzizAlaoui2025`. The only requirement is that the discipline has at least three scalar inputs and at least one output. This scenario can be used to enrich a catalog of benchmark MDO problems, based on the observation that MDO benchmark problems are far less numerous than optimization problems. This example illustrates it in the case of the minimization of the 3-dimensional Rosenbrock function .. math:: f(z) = 100(z_2-z_1^2)^2 + (1-z_1)^2 + 100(z_1-z_0^2)^2 + (1-z_0)^2 over the hypercube :math:`[-1,1]^3`. The unique solution of this minimization problem is the design point :math:`z^*=(1,1,1)` at which :math:`f` is zero. .. GENERATED FROM PYTHON SOURCE LINES 43-54 .. code-block:: Python from __future__ import annotations from numpy import array from gemseo import create_design_space from gemseo import create_discipline from gemseo import create_scenario from gemseo import generate_coupling_graph from gemseo.problems.mdo.opt_as_mdo_scenario import OptAsMDOScenario .. GENERATED FROM PYTHON SOURCE LINES 55-59 Material -------- First, we create the discipline implementing the Rosenbrock function: .. GENERATED FROM PYTHON SOURCE LINES 59-64 .. code-block:: Python discipline = create_discipline( "AnalyticDiscipline", expressions={"f": "100*(z_2-z_1**2)**2+(1-z_1)**2+100*(z_1-z_0**2)**2+(1-z_0)**2"}, name="Rosenbrock", ) .. GENERATED FROM PYTHON SOURCE LINES 65-66 as well as the design space: .. GENERATED FROM PYTHON SOURCE LINES 66-70 .. code-block:: Python design_space = create_design_space() design_space.add_variable("z_0", lower_bound=-1, upper_bound=1) design_space.add_variable("z_1", lower_bound=-1, upper_bound=1) design_space.add_variable("z_2", lower_bound=-1, upper_bound=1) .. GENERATED FROM PYTHON SOURCE LINES 71-73 and choose :math:`x^{(0)}=(-0.25, 0.75, -0.9)` as the starting point of the optimization: .. GENERATED FROM PYTHON SOURCE LINES 73-76 .. code-block:: Python initial_point = array([-0.25, 0.75, -0.9]) design_space.set_current_value(initial_point) .. GENERATED FROM PYTHON SOURCE LINES 77-81 Optimization problem -------------------- Then, we define the optimization problem: .. GENERATED FROM PYTHON SOURCE LINES 81-84 .. code-block:: Python opt_scenario = create_scenario( [discipline], "f", design_space, formulation_name="DisciplinaryOpt" ) .. GENERATED FROM PYTHON SOURCE LINES 85-86 and solve it using the SLSQP algorithm: .. GENERATED FROM PYTHON SOURCE LINES 86-87 .. code-block:: Python opt_scenario.execute(algo_name="NLOPT_SLSQP", max_iter=100) .. rst-class:: sphx-glr-script-out .. code-block:: none INFO - 16:25:07: *** Start MDOScenario execution *** INFO - 16:25:07: MDOScenario INFO - 16:25:07: Disciplines: Rosenbrock INFO - 16:25:07: MDO formulation: DisciplinaryOpt INFO - 16:25:07: Optimization problem: INFO - 16:25:07: minimize f(z_0, z_1, z_2) INFO - 16:25:07: with respect to z_0, z_1, z_2 INFO - 16:25:07: over the design space: INFO - 16:25:07: +------+-------------+-------+-------------+-------+ INFO - 16:25:07: | Name | Lower bound | Value | Upper bound | Type | INFO - 16:25:07: +------+-------------+-------+-------------+-------+ INFO - 16:25:07: | z_0 | -1 | -0.25 | 1 | float | INFO - 16:25:07: | z_1 | -1 | 0.75 | 1 | float | INFO - 16:25:07: | z_2 | -1 | -0.9 | 1 | float | INFO - 16:25:07: +------+-------------+-------+-------------+-------+ INFO - 16:25:07: Solving optimization problem with algorithm NLOPT_SLSQP: INFO - 16:25:07: 1%| | 1/100 [00:00<00:00, 372.66 it/sec, feas=True, obj=263] INFO - 16:25:07: 2%|▏ | 2/100 [00:00<00:00, 629.21 it/sec, feas=True, obj=408] INFO - 16:25:07: 3%|▎ | 3/100 [00:00<00:00, 817.98 it/sec, feas=True, obj=20.2] INFO - 16:25:07: 4%|▍ | 4/100 [00:00<00:00, 917.09 it/sec, feas=True, obj=168] INFO - 16:25:07: 5%|▌ | 5/100 [00:00<00:00, 991.09 it/sec, feas=True, obj=8.91] INFO - 16:25:07: 6%|▌ | 6/100 [00:00<00:00, 1053.23 it/sec, feas=True, obj=395] INFO - 16:25:07: 7%|▋ | 7/100 [00:00<00:00, 1102.44 it/sec, feas=True, obj=4.06] INFO - 16:25:07: 8%|▊ | 8/100 [00:00<00:00, 1144.38 it/sec, feas=True, obj=151] INFO - 16:25:07: 9%|▉ | 9/100 [00:00<00:00, 1177.15 it/sec, feas=True, obj=3.31] INFO - 16:25:07: 10%|█ | 10/100 [00:00<00:00, 1209.78 it/sec, feas=True, obj=2.09] INFO - 16:25:07: 11%|█ | 11/100 [00:00<00:00, 1235.27 it/sec, feas=True, obj=2.02] INFO - 16:25:07: 12%|█▏ | 12/100 [00:00<00:00, 1260.28 it/sec, feas=True, obj=1.97] INFO - 16:25:07: 13%|█▎ | 13/100 [00:00<00:00, 1279.98 it/sec, feas=True, obj=1.92] INFO - 16:25:07: 14%|█▍ | 14/100 [00:00<00:00, 1299.12 it/sec, feas=True, obj=1.85] INFO - 16:25:07: 15%|█▌ | 15/100 [00:00<00:00, 1318.24 it/sec, feas=True, obj=1.73] INFO - 16:25:07: 16%|█▌ | 16/100 [00:00<00:00, 1332.61 it/sec, feas=True, obj=1.3] INFO - 16:25:07: 17%|█▋ | 17/100 [00:00<00:00, 1345.44 it/sec, feas=True, obj=0.995] INFO - 16:25:07: 18%|█▊ | 18/100 [00:00<00:00, 1358.53 it/sec, feas=True, obj=0.721] INFO - 16:25:07: 19%|█▉ | 19/100 [00:00<00:00, 1369.44 it/sec, feas=True, obj=0.625] INFO - 16:25:07: 20%|██ | 20/100 [00:00<00:00, 1381.39 it/sec, feas=True, obj=6.19] INFO - 16:25:07: 21%|██ | 21/100 [00:00<00:00, 1388.60 it/sec, feas=True, obj=0.491] INFO - 16:25:07: 22%|██▏ | 22/100 [00:00<00:00, 1396.60 it/sec, feas=True, obj=5.86] INFO - 16:25:07: 23%|██▎ | 23/100 [00:00<00:00, 1402.49 it/sec, feas=True, obj=0.403] INFO - 16:25:07: 24%|██▍ | 24/100 [00:00<00:00, 1409.59 it/sec, feas=True, obj=0.87] INFO - 16:25:07: 25%|██▌ | 25/100 [00:00<00:00, 1413.86 it/sec, feas=True, obj=0.279] INFO - 16:25:07: 26%|██▌ | 26/100 [00:00<00:00, 1421.11 it/sec, feas=True, obj=0.243] INFO - 16:25:07: 27%|██▋ | 27/100 [00:00<00:00, 1426.90 it/sec, feas=True, obj=0.244] INFO - 16:25:07: 28%|██▊ | 28/100 [00:00<00:00, 1431.61 it/sec, feas=True, obj=0.224] INFO - 16:25:07: 29%|██▉ | 29/100 [00:00<00:00, 1435.68 it/sec, feas=True, obj=0.171] INFO - 16:25:07: 30%|███ | 30/100 [00:00<00:00, 1440.12 it/sec, feas=True, obj=0.276] INFO - 16:25:07: 31%|███ | 31/100 [00:00<00:00, 1443.74 it/sec, feas=True, obj=0.117] INFO - 16:25:07: 32%|███▏ | 32/100 [00:00<00:00, 1447.51 it/sec, feas=True, obj=0.0792] INFO - 16:25:07: 33%|███▎ | 33/100 [00:00<00:00, 1451.12 it/sec, feas=True, obj=0.0624] INFO - 16:25:07: 34%|███▍ | 34/100 [00:00<00:00, 1455.86 it/sec, feas=True, obj=0.0366] INFO - 16:25:07: 35%|███▌ | 35/100 [00:00<00:00, 1459.89 it/sec, feas=True, obj=0.0298] INFO - 16:25:07: 36%|███▌ | 36/100 [00:00<00:00, 1463.74 it/sec, feas=True, obj=0.0164] INFO - 16:25:07: 37%|███▋ | 37/100 [00:00<00:00, 1468.45 it/sec, feas=True, obj=0.0103] INFO - 16:25:07: 38%|███▊ | 38/100 [00:00<00:00, 1471.89 it/sec, feas=True, obj=0.00429] INFO - 16:25:07: 39%|███▉ | 39/100 [00:00<00:00, 1475.62 it/sec, feas=True, obj=0.00128] INFO - 16:25:07: 40%|████ | 40/100 [00:00<00:00, 1478.49 it/sec, feas=True, obj=0.000368] INFO - 16:25:07: 41%|████ | 41/100 [00:00<00:00, 1480.59 it/sec, feas=True, obj=2.77e-5] INFO - 16:25:07: 42%|████▏ | 42/100 [00:00<00:00, 1483.83 it/sec, feas=True, obj=6.38e-7] INFO - 16:25:07: 43%|████▎ | 43/100 [00:00<00:00, 1485.90 it/sec, feas=True, obj=1.32e-9] INFO - 16:25:07: 44%|████▍ | 44/100 [00:00<00:00, 1489.06 it/sec, feas=True, obj=9.1e-12] INFO - 16:25:07: 45%|████▌ | 45/100 [00:00<00:00, 1491.14 it/sec, feas=True, obj=6.58e-14] INFO - 16:25:07: 46%|████▌ | 46/100 [00:00<00:00, 1493.41 it/sec, feas=True, obj=1.58e-21] INFO - 16:25:07: 47%|████▋ | 47/100 [00:00<00:00, 1496.12 it/sec, feas=True, obj=3.2e-26] INFO - 16:25:07: Optimization result: INFO - 16:25:07: Optimizer info: INFO - 16:25:07: Status: None INFO - 16:25:07: Message: Successive iterates of the design variables are closer than xtol_rel or xtol_abs. GEMSEO stopped the driver. INFO - 16:25:07: Solution: INFO - 16:25:07: Objective: 3.1977265654038935e-26 INFO - 16:25:07: Design space: INFO - 16:25:07: +------+-------------+--------------------+-------------+-------+ INFO - 16:25:07: | Name | Lower bound | Value | Upper bound | Type | INFO - 16:25:07: +------+-------------+--------------------+-------------+-------+ INFO - 16:25:07: | z_0 | -1 | 0.9999999999999947 | 1 | float | INFO - 16:25:07: | z_1 | -1 | 0.9999999999999911 | 1 | float | INFO - 16:25:07: | z_2 | -1 | 1 | 1 | float | INFO - 16:25:07: +------+-------------+--------------------+-------------+-------+ INFO - 16:25:07: *** End MDOScenario execution *** .. GENERATED FROM PYTHON SOURCE LINES 88-98 We can see that the numerical solution corresponds to the analytical one. MDO problem ----------- Now, we use the :class:`.OptAsMDOScenario` to rewrite this optimization problem as an MDO problem with two strongly coupled disciplines. First, we reset the design space to the initial point: .. GENERATED FROM PYTHON SOURCE LINES 98-99 .. code-block:: Python design_space.set_current_value(initial_point) .. GENERATED FROM PYTHON SOURCE LINES 100-102 and create the :class:`.OptAsMDOScenario`, orchestrated by an MDF formulation: .. GENERATED FROM PYTHON SOURCE LINES 102-103 .. code-block:: Python mdo_scenario = OptAsMDOScenario(discipline, "f", design_space, formulation_name="MDF") .. GENERATED FROM PYTHON SOURCE LINES 104-106 Then, we can see that the design variables have been renamed: .. GENERATED FROM PYTHON SOURCE LINES 106-107 .. code-block:: Python design_space .. raw:: html
Design space:
Name Lower bound Value Upper bound Type
x_0 -1 -0.25 1 float
x_1 -1 0.75 1 float
x_2 -1 -0.9 1 float


.. GENERATED FROM PYTHON SOURCE LINES 108-116 This renaming is based on the convention: - the first design variable is the global design variable and is named :math:`x_0`, - the :math:`(1+i)`-th design variable is the local design variable specific to the :math:`i`-th strongly coupled discipline and is named :math:`x_{1+i}`. We can also have a look to the coupling graph: .. GENERATED FROM PYTHON SOURCE LINES 116-117 .. code-block:: Python generate_coupling_graph(mdo_scenario.disciplines, file_path="") .. raw:: html
%3 L L Rosenbrock Rosenbrock L->Rosenbrock z_0, z_1, z_2 Rosenbrock->_Rosenbrock f D1 D1 D1->L y_1 D2 D2 D1->D2 y_1 D2->L y_2 D2->D1 y_2


.. GENERATED FROM PYTHON SOURCE LINES 118-128 and see that there are two strongly coupled disciplines :math:`D_1` and :math:`D_2`, connected by the coupling variables :math:`y_1` and :math:`y_2`. These disciplines are weakly coupled to a downstream link discipline :math:`L`, which is weakly coupled to the downstream original discipline. Let us note that the link discipline computes the values of the design variables in the original optimization problem from the values of the design and coupling variables in the MDO problem. Lastly, we solve this scenario using the SLSQP algorithm: .. GENERATED FROM PYTHON SOURCE LINES 128-130 .. code-block:: Python mdo_scenario.set_differentiation_method(method="finite_differences") mdo_scenario.execute(algo_name="NLOPT_SLSQP", max_iter=100) .. rst-class:: sphx-glr-script-out .. code-block:: none INFO - 16:25:08: *** Start OptAsMDOScenario execution *** INFO - 16:25:08: OptAsMDOScenario INFO - 16:25:08: Disciplines: D1 D2 L Rosenbrock INFO - 16:25:08: MDO formulation: MDF INFO - 16:25:08: Optimization problem: INFO - 16:25:08: minimize f(x_0, x_1, x_2) INFO - 16:25:08: with respect to x_0, x_1, x_2 INFO - 16:25:08: over the design space: INFO - 16:25:08: +------+-------------+-------+-------------+-------+ INFO - 16:25:08: | Name | Lower bound | Value | Upper bound | Type | INFO - 16:25:08: +------+-------------+-------+-------------+-------+ INFO - 16:25:08: | x_0 | -1 | -0.25 | 1 | float | INFO - 16:25:08: | x_1 | -1 | 0.75 | 1 | float | INFO - 16:25:08: | x_2 | -1 | -0.9 | 1 | float | INFO - 16:25:08: +------+-------------+-------+-------------+-------+ INFO - 16:25:08: Solving optimization problem with algorithm NLOPT_SLSQP: INFO - 16:25:08: 1%| | 1/100 [00:00<00:01, 62.50 it/sec, feas=True, obj=263] INFO - 16:25:08: 2%|▏ | 2/100 [00:00<00:01, 73.05 it/sec, feas=True, obj=408] INFO - 16:25:08: 3%|▎ | 3/100 [00:00<00:01, 81.14 it/sec, feas=True, obj=20.2] WARNING - 16:25:08: All components of the normalized vector should be between 0 and 1; upper bounds violated: [1.000001]. WARNING - 16:25:08: All components of the normalized vector should be between 0 and 1; upper bounds violated: [1.000001]. INFO - 16:25:08: 4%|▍ | 4/100 [00:00<00:01, 81.47 it/sec, feas=True, obj=168] INFO - 16:25:08: 5%|▌ | 5/100 [00:00<00:01, 85.61 it/sec, feas=True, obj=8.91] INFO - 16:25:08: 6%|▌ | 6/100 [00:00<00:01, 85.33 it/sec, feas=True, obj=395] INFO - 16:25:08: 7%|▋ | 7/100 [00:00<00:01, 88.19 it/sec, feas=True, obj=4.06] WARNING - 16:25:08: All components of the normalized vector should be between 0 and 1; upper bounds violated: [1.000001]. INFO - 16:25:08: 8%|▊ | 8/100 [00:00<00:01, 87.76 it/sec, feas=True, obj=151] INFO - 16:25:08: 9%|▉ | 9/100 [00:00<00:01, 89.65 it/sec, feas=True, obj=3.31] INFO - 16:25:08: 10%|█ | 10/100 [00:00<00:01, 89.21 it/sec, feas=True, obj=2.09] INFO - 16:25:08: 11%|█ | 11/100 [00:00<00:00, 89.07 it/sec, feas=True, obj=2.02] INFO - 16:25:08: 12%|█▏ | 12/100 [00:00<00:00, 88.99 it/sec, feas=True, obj=1.97] INFO - 16:25:08: 13%|█▎ | 13/100 [00:00<00:00, 88.94 it/sec, feas=True, obj=1.92] INFO - 16:25:08: 14%|█▍ | 14/100 [00:00<00:00, 88.86 it/sec, feas=True, obj=1.85] INFO - 16:25:08: 15%|█▌ | 15/100 [00:00<00:00, 88.99 it/sec, feas=True, obj=1.73] INFO - 16:25:08: 16%|█▌ | 16/100 [00:00<00:00, 89.21 it/sec, feas=True, obj=1.3] INFO - 16:25:08: 17%|█▋ | 17/100 [00:00<00:00, 88.99 it/sec, feas=True, obj=0.996] INFO - 16:25:08: 18%|█▊ | 18/100 [00:00<00:00, 89.04 it/sec, feas=True, obj=0.721] INFO - 16:25:08: 19%|█▉ | 19/100 [00:00<00:00, 88.80 it/sec, feas=True, obj=0.6] WARNING - 16:25:08: All components of the normalized vector should be between 0 and 1; upper bounds violated: [1.000001]. INFO - 16:25:08: 20%|██ | 20/100 [00:00<00:00, 88.51 it/sec, feas=True, obj=6.26] INFO - 16:25:08: 21%|██ | 21/100 [00:00<00:00, 89.42 it/sec, feas=True, obj=0.473] INFO - 16:25:08: 22%|██▏ | 22/100 [00:00<00:00, 89.36 it/sec, feas=True, obj=6.1] INFO - 16:25:08: 23%|██▎ | 23/100 [00:00<00:00, 90.09 it/sec, feas=True, obj=0.394] INFO - 16:25:08: 24%|██▍ | 24/100 [00:00<00:00, 90.13 it/sec, feas=True, obj=0.665] INFO - 16:25:08: 25%|██▌ | 25/100 [00:00<00:00, 90.84 it/sec, feas=True, obj=0.28] INFO - 16:25:08: 26%|██▌ | 26/100 [00:00<00:00, 90.68 it/sec, feas=True, obj=0.242] INFO - 16:25:08: 27%|██▋ | 27/100 [00:00<00:00, 90.66 it/sec, feas=True, obj=0.207] INFO - 16:25:08: 28%|██▊ | 28/100 [00:00<00:00, 90.61 it/sec, feas=True, obj=0.142] INFO - 16:25:08: 29%|██▉ | 29/100 [00:00<00:00, 90.54 it/sec, feas=True, obj=0.091] INFO - 16:25:08: 30%|███ | 30/100 [00:00<00:00, 90.42 it/sec, feas=True, obj=0.0673] INFO - 16:25:08: 31%|███ | 31/100 [00:00<00:00, 90.33 it/sec, feas=True, obj=0.0512] INFO - 16:25:08: 32%|███▏ | 32/100 [00:00<00:00, 90.23 it/sec, feas=True, obj=0.029] INFO - 16:25:08: 33%|███▎ | 33/100 [00:00<00:00, 90.18 it/sec, feas=True, obj=0.0164] INFO - 16:25:08: 34%|███▍ | 34/100 [00:00<00:00, 90.06 it/sec, feas=True, obj=0.00786] INFO - 16:25:08: 35%|███▌ | 35/100 [00:00<00:00, 89.98 it/sec, feas=True, obj=0.00314] INFO - 16:25:08: 36%|███▌ | 36/100 [00:00<00:00, 89.97 it/sec, feas=True, obj=0.00103] INFO - 16:25:08: 37%|███▋ | 37/100 [00:00<00:00, 90.04 it/sec, feas=True, obj=0.000147] INFO - 16:25:08: 38%|███▊ | 38/100 [00:00<00:00, 89.55 it/sec, feas=True, obj=1.19e-5] INFO - 16:25:08: 39%|███▉ | 39/100 [00:00<00:00, 89.54 it/sec, feas=True, obj=9.5e-7] INFO - 16:25:08: 40%|████ | 40/100 [00:00<00:00, 89.55 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: 41%|████ | 41/100 [00:00<00:00, 89.49 it/sec, feas=True, obj=6.45e-7] INFO - 16:25:08: 42%|████▏ | 42/100 [00:00<00:00, 91.12 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: 43%|████▎ | 43/100 [00:00<00:00, 92.74 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: 44%|████▍ | 44/100 [00:00<00:00, 94.37 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: 45%|████▌ | 45/100 [00:00<00:00, 95.94 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: 46%|████▌ | 46/100 [00:00<00:00, 97.52 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: 47%|████▋ | 47/100 [00:00<00:00, 99.09 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: 48%|████▊ | 48/100 [00:00<00:00, 100.64 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: 49%|████▉ | 49/100 [00:00<00:00, 102.15 it/sec, feas=True, obj=6.41e-7] INFO - 16:25:08: Optimization result: INFO - 16:25:08: Optimizer info: INFO - 16:25:08: Status: None INFO - 16:25:08: Message: Successive iterates of the design variables are closer than xtol_rel or xtol_abs. GEMSEO stopped the driver. INFO - 16:25:08: Solution: INFO - 16:25:08: Objective: 6.40943911289712e-07 INFO - 16:25:08: Design space: INFO - 16:25:08: +------+-------------+--------------------+-------------+-------+ INFO - 16:25:08: | Name | Lower bound | Value | Upper bound | Type | INFO - 16:25:08: +------+-------------+--------------------+-------------+-------+ INFO - 16:25:08: | x_0 | -1 | 0.9996445136827841 | 1 | float | INFO - 16:25:08: | x_1 | -1 | 0.999284303839403 | 1 | float | INFO - 16:25:08: | x_2 | -1 | 0.9985690703536887 | 1 | float | INFO - 16:25:08: +------+-------------+--------------------+-------------+-------+ INFO - 16:25:08: *** End OptAsMDOScenario execution *** .. GENERATED FROM PYTHON SOURCE LINES 131-132 We can see that the numerical solution corresponds to the analytical one. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.836 seconds) .. _sphx_glr_download_examples_mdo_plot_opt_as_mdo.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_opt_as_mdo.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_opt_as_mdo.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_opt_as_mdo.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_