# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.2
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

"""Designs of experiments."""

from sys import version_info as _swig_python_version_info
if _swig_python_version_info < (2, 7, 0):
    raise RuntimeError("Python 2.7 or later required")

# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _experiment
else:
    import _experiment

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "thisown":
            self.this.own(value)
        elif name == "this":
            set(self, name, value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


class SwigPyIterator(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _experiment.delete_SwigPyIterator

    def value(self):
        return _experiment.SwigPyIterator_value(self)

    def incr(self, n=1):
        return _experiment.SwigPyIterator_incr(self, n)

    def decr(self, n=1):
        return _experiment.SwigPyIterator_decr(self, n)

    def distance(self, x):
        return _experiment.SwigPyIterator_distance(self, x)

    def equal(self, x):
        return _experiment.SwigPyIterator_equal(self, x)

    def copy(self):
        return _experiment.SwigPyIterator_copy(self)

    def next(self):
        return _experiment.SwigPyIterator_next(self)

    def __next__(self):
        return _experiment.SwigPyIterator___next__(self)

    def previous(self):
        return _experiment.SwigPyIterator_previous(self)

    def advance(self, n):
        return _experiment.SwigPyIterator_advance(self, n)

    def __eq__(self, x):
        return _experiment.SwigPyIterator___eq__(self, x)

    def __ne__(self, x):
        return _experiment.SwigPyIterator___ne__(self, x)

    def __iadd__(self, n):
        return _experiment.SwigPyIterator___iadd__(self, n)

    def __isub__(self, n):
        return _experiment.SwigPyIterator___isub__(self, n)

    def __add__(self, n):
        return _experiment.SwigPyIterator___add__(self, n)

    def __sub__(self, *args):
        return _experiment.SwigPyIterator___sub__(self, *args)
    def __iter__(self):
        return self

# Register SwigPyIterator in _experiment:
_experiment.SwigPyIterator_swigregister(SwigPyIterator)


class TestFailed:
    """TestFailed is used to raise an uniform exception in tests."""

    __type = "TestFailed"

    def __init__(self, reason=""):
        self.reason = reason

    def type(self):
        return TestFailed.__type

    def what(self):
        return self.reason

    def __str__(self):
        return TestFailed.__type + ": " + self.reason

    def __lshift__(self, ch):
        self.reason += ch
        return self

import openturns.common
import openturns.typ
import openturns.statistics
import openturns.graph
import openturns.func
import openturns.geom
class ExperimentImplementation(openturns.common.PersistentObject):
    r"""
    Base class for design of experiments.

    Considering :math:`\vect{x}=x^1,\dots, x^n` a vector of input parameters, this
    class is used to determine a particular set of values of :math:`\vect{x}`
    according to a particular design of experiments.

    Different types of design of experiments can be determined:

    - some stratified patterns: axial, composite, factorial or box patterns,

    - some weighted patterns that we can split into different categories:
      the random patterns, the low discrepancy sequences and the deterministic
      patterns.

    Examples
    --------
    Define a custom design of experiment:
    >>> import openturns as ot
    >>> ot.RandomGenerator.SetSeed(0)
    >>> class RandomExp(object):
    ...     def generate(self):
    ...         return ot.Normal(1).getSample(10)
    >>> experiment = ot.Experiment(RandomExp())
    >>> sample = experiment.generate()

    See also
    --------
    StratifiedExperiment, WeightedExperiment
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.ExperimentImplementation_getClassName(self)

    def __repr__(self):
        return _experiment.ExperimentImplementation___repr__(self)

    def generate(self):
        r"""
        Generate points according to the type of the experiment.

        Returns
        -------
        sample : :class:`~openturns.Sample`
            The points which constitute the design of experiments. The sampling method
            is defined by the nature of the experiment.

        Examples
        --------
        >>> import openturns as ot
        >>> ot.RandomGenerator.SetSeed(0)
        >>> myExperiment = ot.Experiment(ot.MonteCarloExperiment(ot.Normal(2),5))
        >>> print(myExperiment.generate())
            [ X0        X1        ]
        0 : [  0.608202 -1.26617  ]
        1 : [ -0.438266  1.20548  ]
        2 : [ -2.18139   0.350042 ]
        3 : [ -0.355007  1.43725  ]
        4 : [  0.810668  0.793156 ]
        """
        return _experiment.ExperimentImplementation_generate(self)

    def __init__(self, *args):
        _experiment.ExperimentImplementation_swiginit(self, _experiment.new_ExperimentImplementation(*args))
    __swig_destroy__ = _experiment.delete_ExperimentImplementation

# Register ExperimentImplementation in _experiment:
_experiment.ExperimentImplementation_swigregister(ExperimentImplementation)

class StratifiedExperiment(ExperimentImplementation):
    r"""
    Base class for stratified experiments.

    Available constructor:
        StratifiedExperiment(*center, levels*)

    Parameters
    ----------
    center, levels : two sequences of float
        Sequences which have different meanings according to the nature of the
        stratified experiment: Axial, Composite, Factorial or Box (see
        corresponding documentation).

    Notes
    -----
    A StratifiedExperiment object can be used only through its derived classes:

    - :class:`~openturns.Axial`
    - :class:`~openturns.Box`
    - :class:`~openturns.Composite`
    - :class:`~openturns.Factorial`.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.StratifiedExperiment_getClassName(self)

    def __repr__(self):
        return _experiment.StratifiedExperiment___repr__(self)

    def setCenter(self, center):
        r"""
        Set the center of the stratified experiment.

        Parameters
        ----------
        center : sequence of float
            Sequence which has different meanings according to the nature of the
            stratified experiment: Axial, Composite, Factorial or Box (see
            corresponding documentation).
        """
        return _experiment.StratifiedExperiment_setCenter(self, center)

    def getCenter(self):
        r"""
        Get the center of the stratified experiment.

        Returns
        -------
        center : :class:`~openturns.Point`
            Sequence which has different meanings according to the nature of the
            stratified experiment: Axial, Composite, Factorial or Box (see
            corresponding documentation).
        """
        return _experiment.StratifiedExperiment_getCenter(self)

    def setLevels(self, levels):
        r"""
        Set the levels of the stratified experiment.

        Parameters
        ----------
        levels : sequence of float
            Sequence which has different meanings according to the nature of the
            stratified experiment: Axial, Composite, Factorial or Box (see
            corresponding documentation).
        """
        return _experiment.StratifiedExperiment_setLevels(self, levels)

    def getLevels(self):
        r"""
        Get the levels of the stratified experiment.

        Returns
        -------
        levels : :class:`~openturns.Point`
            Sequence which has different meanings according to the nature of the
            stratified experiment: Axial, Composite, Factorial or Box (see
            corresponding documentation).
        """
        return _experiment.StratifiedExperiment_getLevels(self)

    def __init__(self, *args):
        _experiment.StratifiedExperiment_swiginit(self, _experiment.new_StratifiedExperiment(*args))
    __swig_destroy__ = _experiment.delete_StratifiedExperiment

# Register StratifiedExperiment in _experiment:
_experiment.StratifiedExperiment_swigregister(StratifiedExperiment)

class ExperimentImplementationTypedInterfaceObject(openturns.common.InterfaceObject):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _experiment.ExperimentImplementationTypedInterfaceObject_swiginit(self, _experiment.new_ExperimentImplementationTypedInterfaceObject(*args))

    def getImplementation(self):
        r"""
        Accessor to the underlying implementation.

        Returns
        -------
        impl : Implementation
            The implementation class.
        """
        return _experiment.ExperimentImplementationTypedInterfaceObject_getImplementation(self)

    def setName(self, name):
        r"""
        Accessor to the object's name.

        Parameters
        ----------
        name : str
            The name of the object.
        """
        return _experiment.ExperimentImplementationTypedInterfaceObject_setName(self, name)

    def getName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        name : str
            The name of the object.
        """
        return _experiment.ExperimentImplementationTypedInterfaceObject_getName(self)

    def __eq__(self, other):
        return _experiment.ExperimentImplementationTypedInterfaceObject___eq__(self, other)

    def __ne__(self, other):
        return _experiment.ExperimentImplementationTypedInterfaceObject___ne__(self, other)
    __swig_destroy__ = _experiment.delete_ExperimentImplementationTypedInterfaceObject

# Register ExperimentImplementationTypedInterfaceObject in _experiment:
_experiment.ExperimentImplementationTypedInterfaceObject_swigregister(ExperimentImplementationTypedInterfaceObject)

class Experiment(ExperimentImplementationTypedInterfaceObject):
    r"""
    Base class for design of experiments.

    Considering :math:`\vect{x}=x^1,\dots, x^n` a vector of input parameters, this
    class is used to determine a particular set of values of :math:`\vect{x}`
    according to a particular design of experiments.

    Different types of design of experiments can be determined:

    - some stratified patterns: axial, composite, factorial or box patterns,

    - some weighted patterns that we can split into different categories:
      the random patterns, the low discrepancy sequences and the deterministic
      patterns.

    Examples
    --------
    Define a custom design of experiment:
    >>> import openturns as ot
    >>> ot.RandomGenerator.SetSeed(0)
    >>> class RandomExp(object):
    ...     def generate(self):
    ...         return ot.Normal(1).getSample(10)
    >>> experiment = ot.Experiment(RandomExp())
    >>> sample = experiment.generate()

    See also
    --------
    StratifiedExperiment, WeightedExperiment
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.Experiment_getClassName(self)

    def __repr__(self):
        return _experiment.Experiment___repr__(self)

    def generate(self):
        r"""
        Generate points according to the type of the experiment.

        Returns
        -------
        sample : :class:`~openturns.Sample`
            The points which constitute the design of experiments. The sampling method
            is defined by the nature of the experiment.

        Examples
        --------
        >>> import openturns as ot
        >>> ot.RandomGenerator.SetSeed(0)
        >>> myExperiment = ot.Experiment(ot.MonteCarloExperiment(ot.Normal(2),5))
        >>> print(myExperiment.generate())
            [ X0        X1        ]
        0 : [  0.608202 -1.26617  ]
        1 : [ -0.438266  1.20548  ]
        2 : [ -2.18139   0.350042 ]
        3 : [ -0.355007  1.43725  ]
        4 : [  0.810668  0.793156 ]
        """
        return _experiment.Experiment_generate(self)

    def __init__(self, *args):
        _experiment.Experiment_swiginit(self, _experiment.new_Experiment(*args))
    __swig_destroy__ = _experiment.delete_Experiment

# Register Experiment in _experiment:
_experiment.Experiment_swigregister(Experiment)

class Axial(StratifiedExperiment):
    r"""
    Axial design of experiments.

    Available constructor:
        Axial(*center, levels*)

        Axial(*dimension, levels*)

    Parameters
    ----------
    center : sequence of float
        Center of the design of experiments. If not specified, the design of
        experiments is centered on :math:`\vect{0} \in \Rset^n`.
    levels : sequence of float of dimension :math:`n_{level}`
        The discretisation of directions (the same for each one), without any
        consideration of unit.
    dimension : positive int
        Dimension :math:`n` of the space where the design of experiments is created.

    Notes
    -----
    Axial is a stratified design of experiments enabling to generate a pattern with
    points only along the axes. It is not convenient to model interactions between
    variables. The axial pattern is obtained by discretizing each direction
    according to specified levels, symmetrically with respect to the center of the
    design of experiments.

    The number of points generated is :math:`1 + 2 n_{level}n`.

    In order to scale each direction and translate the grid structure onto the
    proper center, use the operator :math:`*=` and :math:`+=` of
    :class:`~openturns.Sample`.

    See also
    --------
    StratifiedExperiment

    Examples
    --------
    >>> import openturns as ot
    >>> levels = [4.0, 2.0, 7.0]
    >>> myCenteredReductedGrid = ot.Axial(2, levels)
    >>> mySample = myCenteredReductedGrid.generate()
    >>> # Translate the grid
    >>> mySample+=4
    >>> # Scale each direction
    >>> mySample*=2
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.Axial_getClassName(self)

    def generate(self):
        r"""
        Generate points according to the type of the experiment.

        Returns
        -------
        sample : :class:`~openturns.Sample`
            The points which constitute the design of experiments. The sampling method
            is defined by the nature of the experiment.

        Examples
        --------
        >>> import openturns as ot
        >>> ot.RandomGenerator.SetSeed(0)
        >>> myExperiment = ot.Experiment(ot.MonteCarloExperiment(ot.Normal(2),5))
        >>> print(myExperiment.generate())
            [ X0        X1        ]
        0 : [  0.608202 -1.26617  ]
        1 : [ -0.438266  1.20548  ]
        2 : [ -2.18139   0.350042 ]
        3 : [ -0.355007  1.43725  ]
        4 : [  0.810668  0.793156 ]
        """
        return _experiment.Axial_generate(self)

    def __repr__(self):
        return _experiment.Axial___repr__(self)

    def __init__(self, *args):
        _experiment.Axial_swiginit(self, _experiment.new_Axial(*args))
    __swig_destroy__ = _experiment.delete_Axial

# Register Axial in _experiment:
_experiment.Axial_swigregister(Axial)

class Composite(StratifiedExperiment):
    r"""
    Composite design of experiments.

    Available constructor:
        Composite(*center, levels*)

        Composite(*dimension, levels*)

    Parameters
    ----------
    center : sequence of float
        Center of the design of experiments. If not specified, the design of
        experiments is centered on :math:`\vect{0} \in \Rset^n`.
    levels : sequence of float of dimension :math:`n_{level}`
        The discretisation of directions (the same for each one), without any
        consideration of unit.
    dimension : positive int
        Dimension :math:`n` of the space where the design of experiments is created.

    Notes
    -----
    Composite is a stratified design of experiments enabling to create a pattern
    as the union of an :class:`~openturns.Axial` pattern and a
    :class:`~openturns.Factorial` one. The number of points generated is
    :math:`1 + n_{level}(2n+2^n)`.

    In order to scale each direction and translate the grid structure onto the
    proper center, use the operator :math:`*=` and :math:`+=` of
    :class:`~openturns.Sample`.

    See also
    --------
    StratifiedExperiment

    Examples
    --------
    >>> import openturns as ot
    >>> levels = [4.0, 2.0, 7.0]
    >>> myCenteredReductedGrid = ot.Composite(2, levels)
    >>> mySample = myCenteredReductedGrid.generate()
    >>> # Translate the grid
    >>> mySample+=4
    >>> # Scale each direction
    >>> mySample*=2
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.Composite_getClassName(self)

    def generate(self):
        r"""
        Generate points according to the type of the experiment.

        Returns
        -------
        sample : :class:`~openturns.Sample`
            The points which constitute the design of experiments. The sampling method
            is defined by the nature of the experiment.

        Examples
        --------
        >>> import openturns as ot
        >>> ot.RandomGenerator.SetSeed(0)
        >>> myExperiment = ot.Experiment(ot.MonteCarloExperiment(ot.Normal(2),5))
        >>> print(myExperiment.generate())
            [ X0        X1        ]
        0 : [  0.608202 -1.26617  ]
        1 : [ -0.438266  1.20548  ]
        2 : [ -2.18139   0.350042 ]
        3 : [ -0.355007  1.43725  ]
        4 : [  0.810668  0.793156 ]
        """
        return _experiment.Composite_generate(self)

    def __repr__(self):
        return _experiment.Composite___repr__(self)

    def __init__(self, *args):
        _experiment.Composite_swiginit(self, _experiment.new_Composite(*args))
    __swig_destroy__ = _experiment.delete_Composite

# Register Composite in _experiment:
_experiment.Composite_swigregister(Composite)

class Factorial(StratifiedExperiment):
    r"""
    Factorial design of experiments.

    Available constructor:
        Factorial(*center, levels*)

        Factorial(*dimension, levels*)

    Parameters
    ----------
    center : sequence of float
        Center of the design of experiments. If not specified, the design of
        experiments is centered on :math:`\vect{0} \in \Rset^n`.
    levels : sequence of float of dimension :math:`n_{level}`
        The discretisation of directions (the same for each one), without any
        consideration of unit.
    dimension : positive int
        Dimension :math:`n` of the space where the design of experiments is created.

    Notes
    -----
    Factorial is a stratified design of experiments enabling to generate a pattern
    with points only on diagonals. It is not convenient to model influences of
    single input variables. The factoriel pattern is obtained by discretizing each
    principal diagonal according to the specified levels, symmetrically with
    respect to the center of the design of experiments.

    The number of points generated is :math:`1 + 2^n n_{level}`.

    In order to scale each direction and translate the grid structure onto the
    proper center, use the operator :math:`*=` and :math:`+=` of
    :class:`~openturns.Sample`.

    See also
    --------
    StratifiedExperiment

    Examples
    --------
    >>> import openturns as ot
    >>> levels = [4.0, 2.0, 7.0]
    >>> myCenteredReductedGrid = ot.Factorial(2, levels)
    >>> mySample = myCenteredReductedGrid.generate()
    >>> # Translate the grid
    >>> mySample+=4
    >>> # Scale each direction
    >>> mySample*=2
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.Factorial_getClassName(self)

    def generate(self):
        r"""
        Generate points according to the type of the experiment.

        Returns
        -------
        sample : :class:`~openturns.Sample`
            The points which constitute the design of experiments. The sampling method
            is defined by the nature of the experiment.

        Examples
        --------
        >>> import openturns as ot
        >>> ot.RandomGenerator.SetSeed(0)
        >>> myExperiment = ot.Experiment(ot.MonteCarloExperiment(ot.Normal(2),5))
        >>> print(myExperiment.generate())
            [ X0        X1        ]
        0 : [  0.608202 -1.26617  ]
        1 : [ -0.438266  1.20548  ]
        2 : [ -2.18139   0.350042 ]
        3 : [ -0.355007  1.43725  ]
        4 : [  0.810668  0.793156 ]
        """
        return _experiment.Factorial_generate(self)

    def __repr__(self):
        return _experiment.Factorial___repr__(self)

    def __init__(self, *args):
        _experiment.Factorial_swiginit(self, _experiment.new_Factorial(*args))
    __swig_destroy__ = _experiment.delete_Factorial

# Register Factorial in _experiment:
_experiment.Factorial_swigregister(Factorial)

class Box(StratifiedExperiment):
    r"""
    Box design of experiments.

    Available constructor:
        Box(*levels*)

        Box(*levels, bounds*)

    Parameters
    ----------
    levels : sequence of int or float
        Sequence specifying the number of intermediate points in each direction
        which regularly discretizes a pavement. In direction :math:`i`, the
        points number is :math:`levels[i]+2`.
    bounds : :class:`~openturns.Interval`
        The bounds of the pavement
        If not specified, the bounds are set to the unit pavement :math:`[0,1]^n`.

    Notes
    -----
    Box is a stratified design of experiments enabling to create
    a points grid by regularly discretizing a pavement with
    the number of intermediate points specified in each direction. The number of
    points generated is :math:`\prod_{i=1}^n (2+levels[i])`.

    See also
    --------
    StratifiedExperiment

    Examples
    --------
    >>> import openturns as ot
    >>> # direction 1 will be discretized in with 4 intermediate points
    >>> # and direction 2 with 2 intermediate points
    >>> levels = [4, 2]
    >>> # first component in [5,7], second in [6,9]
    >>> bounds = ot.Interval([5.0, 6.0], [7.0, 9.0])
    >>> myGrid = ot.Box(levels, bounds)
    >>> mySample = myGrid.generate()
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.Box_getClassName(self)

    def generate(self):
        r"""
        Generate points according to the type of the experiment.

        Returns
        -------
        sample : :class:`~openturns.Sample`
            The points which constitute the design of experiments. The sampling method
            is defined by the nature of the experiment.

        Examples
        --------
        >>> import openturns as ot
        >>> ot.RandomGenerator.SetSeed(0)
        >>> myExperiment = ot.Experiment(ot.MonteCarloExperiment(ot.Normal(2),5))
        >>> print(myExperiment.generate())
            [ X0        X1        ]
        0 : [  0.608202 -1.26617  ]
        1 : [ -0.438266  1.20548  ]
        2 : [ -2.18139   0.350042 ]
        3 : [ -0.355007  1.43725  ]
        4 : [  0.810668  0.793156 ]
        """
        return _experiment.Box_generate(self)

    def __repr__(self):
        return _experiment.Box___repr__(self)

    def setLevels(self, levels):
        r"""
        Set the levels of the stratified experiment.

        Parameters
        ----------
        levels : sequence of float
            Sequence which has different meanings according to the nature of the
            stratified experiment: Axial, Composite, Factorial or Box (see
            corresponding documentation).
        """
        return _experiment.Box_setLevels(self, levels)

    def __init__(self, *args):
        _experiment.Box_swiginit(self, _experiment.new_Box(*args))
    __swig_destroy__ = _experiment.delete_Box

# Register Box in _experiment:
_experiment.Box_swigregister(Box)

class CombinatorialGeneratorImplementation(openturns.common.PersistentObject):
    r"""
    Combinatorial generator base class.

    Available constructors:
        CombinatorialGenerator()

        CombinatorialGenerator(*combinatorialGeneratorImp*)

    Parameters
    ----------
    combinatorialGeneratorImp : CombinatorialGeneratorImplementation
        An implementation of a combinatorial generator which is provided by
        :class:`~openturns.Combinations`, :class:`~openturns.KPermutations` or
        :class:`~openturns.Tuples`.

    See also
    --------
    Combinations, KPermutations, Tuples
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.CombinatorialGeneratorImplementation_getClassName(self)

    def __repr__(self):
        return _experiment.CombinatorialGeneratorImplementation___repr__(self)

    def generate(self):
        r"""
        Generate the combinatorial sequence.

        Returns
        -------
        indicesCol : collection  of :class:`~openturns.Indices`
            The collection of all the possible values of the combinatorial generator as
            a set of non-negative integer values stored into an
            :class:`~openturns.Indices`.
        """
        return _experiment.CombinatorialGeneratorImplementation_generate(self)

    def __init__(self, *args):
        _experiment.CombinatorialGeneratorImplementation_swiginit(self, _experiment.new_CombinatorialGeneratorImplementation(*args))
    __swig_destroy__ = _experiment.delete_CombinatorialGeneratorImplementation

# Register CombinatorialGeneratorImplementation in _experiment:
_experiment.CombinatorialGeneratorImplementation_swigregister(CombinatorialGeneratorImplementation)

class CombinatorialGeneratorImplementationTypedInterfaceObject(openturns.common.InterfaceObject):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _experiment.CombinatorialGeneratorImplementationTypedInterfaceObject_swiginit(self, _experiment.new_CombinatorialGeneratorImplementationTypedInterfaceObject(*args))

    def getImplementation(self):
        r"""
        Accessor to the underlying implementation.

        Returns
        -------
        impl : Implementation
            The implementation class.
        """
        return _experiment.CombinatorialGeneratorImplementationTypedInterfaceObject_getImplementation(self)

    def setName(self, name):
        r"""
        Accessor to the object's name.

        Parameters
        ----------
        name : str
            The name of the object.
        """
        return _experiment.CombinatorialGeneratorImplementationTypedInterfaceObject_setName(self, name)

    def getName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        name : str
            The name of the object.
        """
        return _experiment.CombinatorialGeneratorImplementationTypedInterfaceObject_getName(self)

    def __eq__(self, other):
        return _experiment.CombinatorialGeneratorImplementationTypedInterfaceObject___eq__(self, other)

    def __ne__(self, other):
        return _experiment.CombinatorialGeneratorImplementationTypedInterfaceObject___ne__(self, other)
    __swig_destroy__ = _experiment.delete_CombinatorialGeneratorImplementationTypedInterfaceObject

# Register CombinatorialGeneratorImplementationTypedInterfaceObject in _experiment:
_experiment.CombinatorialGeneratorImplementationTypedInterfaceObject_swigregister(CombinatorialGeneratorImplementationTypedInterfaceObject)

class CombinatorialGenerator(CombinatorialGeneratorImplementationTypedInterfaceObject):
    r"""
    Combinatorial generator base class.

    Available constructors:
        CombinatorialGenerator()

        CombinatorialGenerator(*combinatorialGeneratorImp*)

    Parameters
    ----------
    combinatorialGeneratorImp : CombinatorialGeneratorImplementation
        An implementation of a combinatorial generator which is provided by
        :class:`~openturns.Combinations`, :class:`~openturns.KPermutations` or
        :class:`~openturns.Tuples`.

    See also
    --------
    Combinations, KPermutations, Tuples
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.CombinatorialGenerator_getClassName(self)

    def __repr__(self):
        return _experiment.CombinatorialGenerator___repr__(self)

    def generate(self):
        r"""
        Generate the combinatorial sequence.

        Returns
        -------
        indicesCol : collection  of :class:`~openturns.Indices`
            The collection of all the possible values of the combinatorial generator as
            a set of non-negative integer values stored into an
            :class:`~openturns.Indices`.
        """
        return _experiment.CombinatorialGenerator_generate(self)

    def __init__(self, *args):
        _experiment.CombinatorialGenerator_swiginit(self, _experiment.new_CombinatorialGenerator(*args))
    __swig_destroy__ = _experiment.delete_CombinatorialGenerator

# Register CombinatorialGenerator in _experiment:
_experiment.CombinatorialGenerator_swigregister(CombinatorialGenerator)

class Combinations(CombinatorialGeneratorImplementation):
    r"""
    Combinations generator.

    Available constructors:
        Combinations()

        Combinations(*k, n*)

    Parameters
    ----------
    k : integer
        The cardinal of the subsets
    n : integer
        The cardinal of the base set

    See also
    --------
    CombinatorialGenerator, KPermutations, Tuples

    Notes
    -----
    In the first usage, the generator is built using the default values :math:`k = 1`,
    :math:`n = 1`.

    In the second usage, the generator produces all the subsets with *k* elements of
    a base set with *n* elements. The subsets are produced as a collection of 
    :class:`~openturns.Indices` in lexical order, the elements of each subset being
    sorted in increasing order.

    The number of indices generated is:

    .. math::

        \frac{n!}{k! (n - k)!}

    The combinations generator generates a collection of :class:`~openturns.Indices`
    where:

    - the :class:`~openturns.Indices` are sorted in lexical order,
    - the components are sorted within a given :class:`~openturns.Indices`.

    Examples
    --------
    >>> import openturns as ot
    >>> tuples = ot.Combinations(2, 5)
    >>> print(tuples.generate())
    [[0,1],[0,2],[0,3],[0,4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]#10

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.Combinations_getClassName(self)

    def generate(self):
        r"""
        Generate the combinatorial sequence.

        Returns
        -------
        indicesCol : collection  of :class:`~openturns.Indices`
            The collection of all the possible values of the combinatorial generator as
            a set of non-negative integer values stored into an
            :class:`~openturns.Indices`.
        """
        return _experiment.Combinations_generate(self)

    def __repr__(self):
        return _experiment.Combinations___repr__(self)

    def setK(self, k):
        r"""
        Accessor to the cardinal of the subsets.

        Parameters
        ----------
        k : integer
            The cardinal of the subsets.
        """
        return _experiment.Combinations_setK(self, k)

    def getK(self):
        r"""
        Accessor to the cardinal of the subsets.

        Returns
        -------
        k : integer
            The cardinal of the subsets.
        """
        return _experiment.Combinations_getK(self)

    def setN(self, n):
        r"""
        Accessor to the cardinal of the base set.

        Parameters
        ----------
        n : integer
            The cardinal of the base set.
        """
        return _experiment.Combinations_setN(self, n)

    def getN(self):
        r"""
        Accessor to the cardinal of the base set.

        Returns
        -------
        n : integer
            The cardinal of the base set.
        """
        return _experiment.Combinations_getN(self)

    def __init__(self, *args):
        _experiment.Combinations_swiginit(self, _experiment.new_Combinations(*args))
    __swig_destroy__ = _experiment.delete_Combinations

# Register Combinations in _experiment:
_experiment.Combinations_swigregister(Combinations)

class KPermutations(CombinatorialGeneratorImplementation):
    r"""
    K permutations generator.

    Available constructors:
        KPermutations()

        KPermutations(*n*)

        KPermutations(*k, n*)

    Parameters
    ----------
    k : integer
        The cardinal of the origin set
    n : integer
        The cardinal of the goal set

    See also
    --------
    CombinatorialGenerator, Combinations, Tuples

    Notes
    -----
    In the first usage, the generator is built using the default values :math:`k = 1`,
    :math:`n = 1`.

    In the second usage, the generator is built using the value :math:`k = n`.

    In the third usage, the generator produces all the injective functions from a
    set with :math:`k` elements into a set with :math:`n` elements. If :math:`k = n` it means
    all the permutations of a set with :math:`n` elements.

    The number of indices generated is:

    .. math::

        \frac{n!}{(n - k)!}

    The combinations generator generates a collection of :class:`~openturns.Indices`
    that contains all the :math:`k!` permutations of all the
    :math:`\frac{n!}{k! (n - k)!}` subsets with :math:`k` elements of a set with
    :math:`n` elements.

    The subsets are generated in lexical order, and for each subset all the
    corresponding injective functions are generated in lexical order.

    Examples
    --------
    >>> import openturns as ot
    >>> kperm = ot.KPermutations(2, 4)
    >>> print(kperm.generate())
    [[0,1],[1,0],[0,2],[2,0],[0,3],[3,0],[1,2],[2,1],[1,3],[3,1],[2,3],[3,2]]#12

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.KPermutations_getClassName(self)

    def generate(self):
        r"""
        Generate the combinatorial sequence.

        Returns
        -------
        indicesCol : collection  of :class:`~openturns.Indices`
            The collection of all the possible values of the combinatorial generator as
            a set of non-negative integer values stored into an
            :class:`~openturns.Indices`.
        """
        return _experiment.KPermutations_generate(self)

    def __repr__(self):
        return _experiment.KPermutations___repr__(self)

    def setK(self, k):
        r"""
        Accessor to the cardinal of the subsets.

        Parameters
        ----------
        k : integer
            The cardinal of the subsets.
        """
        return _experiment.KPermutations_setK(self, k)

    def getK(self):
        r"""
        Accessor to the cardinal of the subsets.

        Returns
        -------
        k : integer
            The cardinal of the subsets.
        """
        return _experiment.KPermutations_getK(self)

    def setN(self, n):
        r"""
        Accessor to the cardinal of the base set.

        Parameters
        ----------
        n : integer
            The cardinal of the base set.
        """
        return _experiment.KPermutations_setN(self, n)

    def getN(self):
        r"""
        Accessor to the cardinal of the base set.

        Returns
        -------
        n : integer
            The cardinal of the base set.
        """
        return _experiment.KPermutations_getN(self)

    def __init__(self, *args):
        _experiment.KPermutations_swiginit(self, _experiment.new_KPermutations(*args))
    __swig_destroy__ = _experiment.delete_KPermutations

# Register KPermutations in _experiment:
_experiment.KPermutations_swigregister(KPermutations)

class Tuples(CombinatorialGeneratorImplementation):
    r"""
    Tuples generator.

    Available constructors:
        Tuples()

        Tuples(*bounds*)

    Parameters
    ----------
    bounds : :class:`~openturns.Indices`
        The cardinal of all the sets forming the cartesian product.

    See also
    --------
    CombinatorialGenerator, Combinations, KPermutations

    Notes
    -----
    In the first usage, the generator is built using the default values
    :math:`bounds = [1]`.

    In the second usage, the generator produces all the indices
    :math:`[i_0, \ldots, i_{d-1}]` with :math:`i_k \in \{0, \ldots, bounds[k] - 1\}`
    where :math:`d` is the dimension of *bounds*.

    The number of indices generated is:

    .. math::

        \prod_{k = 0}^{d - 1} bounds[k]

    The tuples generator generates a collection of :class:`~openturns.Indices` that
    contains all the elements of the following Cartesian product:

    .. math::

        \prod_{k = 0}^{d - 1} \{ 0, \ldots, bounds[k] -1 \}

    Examples
    --------
    >>> import openturns as ot
    >>> tuples = ot.Tuples([3, 4])
    >>> print(tuples.generate())
    [[0,0],[1,0],[2,0],[0,1],[1,1],[2,1],[0,2],[1,2],[2,2],[0,3],[1,3],[2,3]]#12

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def getClassName(self):
        r"""
        Accessor to the object's name.

        Returns
        -------
        class_name : str
            The object class name (`object.__class__.__name__`).
        """
        return _experiment.Tuples_getClassName(self)

    def generate(self):
        r"""
        Generate the combinatorial sequence.

        Returns
        -------
        indicesCol : collection  of :class:`~openturns.Indices`
            The collection of all the possible values of the combinatorial generator as
            a set of non-negative integer values stored into an
            :class:`~openturns.Indices`.
        """
        return _experiment.Tuples_generate(self)

    def __repr__(self):
        return _experiment.Tuples___repr__(self)

    def setBounds(self, bounds):
        r"""
        Accessor to the bounds.

        Parameters
        ----------
        bounds : :class:`~openturns.Indices`
            The cardinal of all the sets forming the cartesian product.
        """
        return _experiment.Tuples_setBounds(self, bounds)

    def getBounds(self):
        r"""
        Accessor to the bounds.

        Returns
        -------
        bounds : :class:`~openturns.Indices`
            The cardinal of all the sets forming the cartesian product.
        """
        return _experiment.Tuples_getBounds(self)

    def __init__(self, *args):
        _experiment.Tuples_swiginit(self, _experiment.new_Tuples(*args))
    __swig_destroy__ = _experiment.delete_Tuples

# Register Tuples in _experiment:
_experiment.Tuples_swigregister(Tuples)



