Source code for gemseo.algos.doe.openturns.openturns

# 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 - initial API and implementation and/or initial
#                           documentation
#        :author: Damien Guenot
#    OTHER AUTHORS   - MACROSCOPIC CHANGES
"""OpenTURNS DOE algorithms."""

from __future__ import annotations

from collections.abc import Mapping
from collections.abc import Sequence
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing import ClassVar
from typing import Final
from typing import Optional
from typing import Union

import openturns

from gemseo.algos.doe.base_doe_library import BaseDOELibrary
from gemseo.algos.doe.base_doe_library import DOEAlgorithmDescription
from gemseo.algos.doe.openturns._algos.ot_axial_doe import OTAxialDOE
from gemseo.algos.doe.openturns._algos.ot_centered_lhs import OTCenteredLHS
from gemseo.algos.doe.openturns._algos.ot_composite_doe import OTCompositeDOE
from gemseo.algos.doe.openturns._algos.ot_factorial_doe import OTFactorialDOE
from gemseo.algos.doe.openturns._algos.ot_faure_sequence import OTFaureSequence
from gemseo.algos.doe.openturns._algos.ot_full_factorial_doe import OTFullFactorialDOE
from gemseo.algos.doe.openturns._algos.ot_halton_sequence import OTHaltonSequence
from gemseo.algos.doe.openturns._algos.ot_haselgrove_sequence import (
    OTHaselgroveSequence,
)
from gemseo.algos.doe.openturns._algos.ot_monte_carlo import OTMonteCarlo
from gemseo.algos.doe.openturns._algos.ot_optimal_lhs import OTOptimalLHS
from gemseo.algos.doe.openturns._algos.ot_reverse_halton_sequence import (
    OTReverseHaltonSequence,
)
from gemseo.algos.doe.openturns._algos.ot_sobol_doe import OTSobolDOE
from gemseo.algos.doe.openturns._algos.ot_sobol_sequence import OTSobolSequence
from gemseo.algos.doe.openturns._algos.ot_standard_lhs import OTStandardLHS
from gemseo.algos.doe.openturns.settings.ot_axial import OT_AXIAL_Settings
from gemseo.algos.doe.openturns.settings.ot_composite import OT_COMPOSITE_Settings
from gemseo.algos.doe.openturns.settings.ot_factorial import OT_FACTORIAL_Settings
from gemseo.algos.doe.openturns.settings.ot_faure import OT_FAURE_Settings
from gemseo.algos.doe.openturns.settings.ot_fullfact import OT_FULLFACT_Settings
from gemseo.algos.doe.openturns.settings.ot_halton import OT_HALTON_Settings
from gemseo.algos.doe.openturns.settings.ot_haselgrove import OT_HASELGROVE_Settings
from gemseo.algos.doe.openturns.settings.ot_lhs import OT_LHS_Settings
from gemseo.algos.doe.openturns.settings.ot_lhsc import OT_LHSC_Settings
from gemseo.algos.doe.openturns.settings.ot_monte_carlo import OT_MONTE_CARLO_Settings
from gemseo.algos.doe.openturns.settings.ot_opt_lhs import OT_OPT_LHS_Settings
from gemseo.algos.doe.openturns.settings.ot_random import OT_RANDOM_Settings
from gemseo.algos.doe.openturns.settings.ot_reverse_halton import (
    OT_REVERSE_HALTON_Settings,
)
from gemseo.algos.doe.openturns.settings.ot_sobol import OT_SOBOL_Settings
from gemseo.algos.doe.openturns.settings.ot_sobol_indices import (
    OT_SOBOL_INDICES_Settings,
)
from gemseo.typing import RealArray

if TYPE_CHECKING:
    from gemseo.algos.design_space import DesignSpace
    from gemseo.algos.doe.base_doe import BaseDOE
    from gemseo.typing import NumberArray

OptionType = Optional[Union[str, int, float, bool, Sequence[int], RealArray]]


[docs] @dataclass class OpenTURNSAlgorithmDescription(DOEAlgorithmDescription): """The description of a DOE algorithm from the OpenTURNS library.""" library_name: str = "OpenTURNS" """The library name."""
[docs] class OpenTURNS(BaseDOELibrary): """The OpenTURNS DOE algorithms library.""" # Algorithm names within GEMSEO __AXIAL: Final[str] = "OT_AXIAL" __COMPOSITE: Final[str] = "OT_COMPOSITE" __FACTORIAL: Final[str] = "OT_FACTORIAL" __FAURE: Final[str] = "OT_FAURE" __FULLFACT: Final[str] = "OT_FULLFACT" __HALTON: Final[str] = "OT_HALTON" __HASELGROVE: Final[str] = "OT_HASELGROVE" __LHS: Final[str] = "OT_LHS" __LHSC: Final[str] = "OT_LHSC" __MONTE_CARLO: Final[str] = "OT_MONTE_CARLO" __OPT_LHS: Final[str] = "OT_OPT_LHS" __RANDOM: Final[str] = "OT_RANDOM" __REVERSE_HALTON: Final[str] = "OT_REVERSE_HALTON" __SOBOL: Final[str] = "OT_SOBOL" __SOBOL_INDICES: Final[str] = "OT_SOBOL_INDICES" __NAMES_TO_CLASSES: Final[Mapping[str, type[BaseDOE]]] = { __AXIAL: OTAxialDOE, __COMPOSITE: OTCompositeDOE, __FAURE: OTFaureSequence, __FACTORIAL: OTFactorialDOE, __FULLFACT: OTFullFactorialDOE, __HALTON: OTHaltonSequence, __HASELGROVE: OTHaselgroveSequence, __LHS: OTStandardLHS, __LHSC: OTCenteredLHS, __MONTE_CARLO: OTMonteCarlo, __OPT_LHS: OTOptimalLHS, __RANDOM: OTMonteCarlo, __REVERSE_HALTON: OTReverseHaltonSequence, __SOBOL: OTSobolSequence, __SOBOL_INDICES: OTSobolDOE, } """The algorithm names bound to the OpenTURNS classes.""" __DOC: Final[str] = "http://openturns.github.io/openturns/latest/user_manual/" ALGORITHM_INFOS: ClassVar[dict[str, OpenTURNSAlgorithmDescription]] = { __SOBOL: OpenTURNSAlgorithmDescription( algorithm_name=__SOBOL, description="Sobol sequence", internal_algorithm_name=__SOBOL, website=f"{__DOC}_generated/openturns.SobolSequence.html", Settings=OT_SOBOL_Settings, ), __RANDOM: OpenTURNSAlgorithmDescription( algorithm_name=__RANDOM, description="Random sampling", internal_algorithm_name=__RANDOM, website=f"{__DOC}_generated/openturns.Uniform.html", Settings=OT_RANDOM_Settings, ), __HASELGROVE: OpenTURNSAlgorithmDescription( algorithm_name=__HASELGROVE, description="Haselgrove sequence", internal_algorithm_name=__HASELGROVE, website=f"{__DOC}_generated/openturns.HaselgroveSequence.html", Settings=OT_HASELGROVE_Settings, ), __REVERSE_HALTON: OpenTURNSAlgorithmDescription( algorithm_name=__REVERSE_HALTON, description="Reverse Halton", internal_algorithm_name=__REVERSE_HALTON, website=f"{__DOC}_generated/openturns.ReverseHaltonSequence.html", Settings=OT_REVERSE_HALTON_Settings, ), __HALTON: OpenTURNSAlgorithmDescription( algorithm_name=__HALTON, description="Halton sequence", internal_algorithm_name=__HALTON, website=f"{__DOC}_generated/openturns.HaltonSequence.html", Settings=OT_HALTON_Settings, ), __FAURE: OpenTURNSAlgorithmDescription( algorithm_name=__FAURE, description="Faure sequence", internal_algorithm_name=__FAURE, website=f"{__DOC}_generated/openturns.FaureSequence.html", Settings=OT_FAURE_Settings, ), __MONTE_CARLO: OpenTURNSAlgorithmDescription( algorithm_name=__MONTE_CARLO, description="Monte Carlo sequence", internal_algorithm_name=__MONTE_CARLO, website=f"{__DOC}_generated/openturns.Uniform.html", Settings=OT_MONTE_CARLO_Settings, ), __FACTORIAL: OpenTURNSAlgorithmDescription( algorithm_name=__FACTORIAL, description="Factorial design", internal_algorithm_name=__FACTORIAL, website=f"{__DOC}_generated/openturns.Factorial.html", Settings=OT_FACTORIAL_Settings, ), __COMPOSITE: OpenTURNSAlgorithmDescription( algorithm_name=__COMPOSITE, description="Composite design", internal_algorithm_name=__COMPOSITE, website=f"{__DOC}_generated/openturns.Composite.html", Settings=OT_COMPOSITE_Settings, ), __AXIAL: OpenTURNSAlgorithmDescription( algorithm_name=__AXIAL, description="Axial design", internal_algorithm_name=__AXIAL, website=f"{__DOC}_generated/openturns.Axial.html", Settings=OT_AXIAL_Settings, ), __OPT_LHS: OpenTURNSAlgorithmDescription( algorithm_name=__OPT_LHS, description="Optimal Latin Hypercube Sampling", internal_algorithm_name=__OPT_LHS, website=f"{__DOC}_generated/openturns.SimulatedAnnealingLHS.html", Settings=OT_OPT_LHS_Settings, ), __LHS: OpenTURNSAlgorithmDescription( algorithm_name=__LHS, description="Latin Hypercube Sampling", internal_algorithm_name=__LHS, website=f"{__DOC}_generated/openturns.LHS.html", Settings=OT_LHS_Settings, ), __LHSC: OpenTURNSAlgorithmDescription( algorithm_name=__LHSC, description="Centered Latin Hypercube Sampling", internal_algorithm_name=__LHSC, website=f"{__DOC}_generated/openturns.LHS.html", Settings=OT_LHSC_Settings, ), __FULLFACT: OpenTURNSAlgorithmDescription( algorithm_name=__FULLFACT, description="Full factorial design", internal_algorithm_name=__FULLFACT, website=f"{__DOC}_generated/openturns.Box.html", Settings=OT_FULLFACT_Settings, ), __SOBOL_INDICES: OpenTURNSAlgorithmDescription( algorithm_name=__SOBOL_INDICES, description="DOE for Sobol indices", internal_algorithm_name=__SOBOL_INDICES, website=f"{__DOC}_generated/openturns.SobolIndicesAlgorithm.html", Settings=OT_SOBOL_INDICES_Settings, ), } def _generate_unit_samples( self, design_space: DesignSpace, n_samples: int = 0, seed: int | None = None, **settings: OptionType, ) -> NumberArray: """ Args: n_samples: The number of samples. If 0, set from the options. seed: The seed used for reproducibility reasons. If ``None``, use :attr:`.seed`. """ # noqa: D205, D212, D415 openturns.RandomGenerator.SetSeed(self._seeder.get_seed(seed)) doe_algo = self.__NAMES_TO_CLASSES[self._algo_name]() return doe_algo.generate_samples(n_samples, design_space.dimension, **settings)