Source code for gemseo.post.pareto_front

# -*- coding: utf-8 -*-
# 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.

# Contributors:
#    INITIAL AUTHORS - API and implementation and/or documentation
#        :author: Francois Gallard
#        :author: Damien Guenot
#    OTHER AUTHORS   - MACROSCOPIC CHANGES
"""
Display a Pareto Front
**********************
"""
from __future__ import absolute_import, division, print_function, unicode_literals

from future import standard_library

from gemseo.algos.pareto_front import generate_pareto_plots
from gemseo.post.opt_post_processor import OptPostProcessor

standard_library.install_aliases()


from gemseo import LOGGER


[docs]class ParetoFront(OptPostProcessor): """ Compute the Pareto front Search for all non dominated points, ie there exists j such that there is no lower value for obj_values[:,j] that does not degrade at least one other objective obj_values[:,i]. Generates a plot or a matrix of plots if there are more than 2 objectives. Plots in red the locally non dominated points for the currrent two objectives. Plot in green the globally (all objectives) Pareto optimal points. """ def _plot( self, objectives=None, objectives_labels=None, figsize_x=10, figsize_y=10, show=False, save=False, file_path=None, extension="pdf", ): """ Plots the Pareto front :param objectives: the functions names or design variables to plot if None, use the objective function (may be a vector) :type objectives: list(str) :param figsize_x: size of figure in horizontal direction (inches) :type figsize_x: int :param figsize_y: size of figure in vertical direction (inches) :type figsize_y: int :param show: if True, displays the plot windows :type show: bool :param save: if True, exports plot to pdf :type save: bool :param file_path: the base paths of the files to export :type file_path: str :param extension: file extension :type extension: str """ if objectives is None: objectives = [self.opt_problem.objective.name] add_dv = False all_funcs = self.opt_problem.get_all_functions_names() all_dv_names = self.opt_problem.design_space.variables_names design_variables = None if not objectives: # function list only contains design variables vals = self.database.get_x_history() vname = self.database.set_dv_names(vals[0].shape[0]) else: design_variables = [] for func in list(objectives): if func not in all_funcs and func not in all_dv_names: min_f = "-" + func == self.opt_problem.objective.name if min_f and not self.opt_problem.minimize_objective: objectives[objectives.index(func)] = "-" + func else: msg = "Cannot build Pareto front," msg += " Function " + func + " is neither among" msg += " optimization problem functions :" msg += str(all_funcs) + "nor design variables :" msg += str(all_dv_names) raise ValueError(msg) if func in self.opt_problem.design_space.variables_names: # if given function is a design variable, then remove it add_dv = True objectives.remove(func) design_variables.append(func) if design_variables == []: design_variables = None vals, vname, _ = self.database.get_history_array( objectives, design_variables, add_dv=add_dv ) if objectives_labels is not None: assert len(vname) == len(objectives_labels) vname = objectives_labels fig = generate_pareto_plots(vals, vname, figsize=(figsize_x, figsize_y)) self._save_and_show( fig, save=save, show=show, file_path=file_path, extension=extension )