# 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.

"""Solvers."""

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 _solver
else:
    import _solver

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__ = _solver.delete_SwigPyIterator

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

# Register SwigPyIterator in _solver:
_solver.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
import openturns.diff
import openturns.optim
import openturns.experiment
class SolverImplementation(openturns.common.PersistentObject):
    r"""
    SolverImplementation of 1D non linear equations.

    Available constructor:
        SolverImplementation()

        SolverImplementation(*solverImplementation*)

        SolverImplementation(*absError, relError, resError, maximumFunctionEvaluation*)

    Parameters
    ----------
    solverImplementation : SolverImplementationImplementation
        The implementation of a particular solver which is :class:`~openturns.Bisection`,
        :class:`~openturns.Brent` or :class:`~openturns.Secant`.   
    absError : positive float
        Absolute error: distance between two successive iterates at the end point.
        Default is :math:`10^{-5}`.
    relError : positive float
        Relative error: distance between the two last successive iterates with
        regards to the last iterate. Default is :math:`10^{-5}`.
    resError : positive float
        Residual error: difference between the last iterate value and the expected
        value. Default is :math:`10^{-8}`.
    maximumFunctionEvaluation : int
        The maximum number of evaluations of the function. Default is :math:`100`.

    See also
    --------
    Bisection, Brent, Secant

    Notes
    -----
    This class enables to solve 1D non linear equations :

    .. math::

        f(x) = value, \forall x \in [infPoint, supPoint]

    if :math:`f` is a continuous function from :math:`\Rset` to :math:`\Rset`,
    :math:`infPoint, supPoint \in \Rset` and if :math:`f` is such that
    :math:`f(infPoint) \times f(supPoint) < 0`, then :math:`f` has at least a zero
    in the interval :math:`[infPoint, supPoint]`. In particular, it is used in the
    root research of a 
    :class:`Directional Sampling simulation <openturns.DirectionalSampling>`.
    """

    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 _solver.SolverImplementation_getClassName(self)

    def __eq__(self, other):
        return _solver.SolverImplementation___eq__(self, other)

    def __repr__(self):
        return _solver.SolverImplementation___repr__(self)

    def solve(self, *args):
        return _solver.SolverImplementation_solve(self, *args)

    def setAbsoluteError(self, absoluteError):
        r"""
        Accessor to the absolute error.

        Parameters
        ----------
        absError : float
            The absolute error: distance between two successive iterates at the end point.
        """
        return _solver.SolverImplementation_setAbsoluteError(self, absoluteError)

    def getAbsoluteError(self):
        r"""
        Accessor to the absolute error.

        Returns
        -------
        absError : float
            The absolute error: distance between two successive iterates at the end point.
        """
        return _solver.SolverImplementation_getAbsoluteError(self)

    def setRelativeError(self, relativeError):
        r"""
        Accessor to the relative error.

        Parameters
        ----------
        relError : float
            The relative error: distance between the two last successive iterates with
            regards to the last iterate.
        """
        return _solver.SolverImplementation_setRelativeError(self, relativeError)

    def getRelativeError(self):
        r"""
        Accessor to the relative error.

        Returns
        -------
        relError : float
            The relative error: distance between the two last successive iterates with
            regards to the last iterate.
        """
        return _solver.SolverImplementation_getRelativeError(self)

    def setResidualError(self, residualError):
        r"""
        Accessor to the residual error.

        Parameters
        ----------
        resError : float
            The residual errors: difference between the last iterate value and the
            expected value.
        """
        return _solver.SolverImplementation_setResidualError(self, residualError)

    def getResidualError(self):
        r"""
        Accessor to the residual error.

        Returns
        -------
        resError : float
            The residual errors: difference between the last iterate value and the
            expected value.
        """
        return _solver.SolverImplementation_getResidualError(self)

    def setMaximumFunctionEvaluation(self, maximumFunctionEvaluation):
        r"""
        Accessor to the maximum number of evaluations of the function.

        Parameters
        ----------
        maxEval : int
            The maximum number of evaluations of the function.
        """
        return _solver.SolverImplementation_setMaximumFunctionEvaluation(self, maximumFunctionEvaluation)

    def getMaximumFunctionEvaluation(self):
        r"""
        Accessor to the maximum number of evaluations of the function.

        Returns
        -------
        maxEval : int
            The maximum number of evaluations of the function.
        """
        return _solver.SolverImplementation_getMaximumFunctionEvaluation(self)

    def getUsedFunctionEvaluation(self):
        r"""
        Accessor to the number of evaluations of the function.

        Returns
        -------
        nEval : int
            The number of evaluations of the function.
        """
        return _solver.SolverImplementation_getUsedFunctionEvaluation(self)

    def __init__(self, *args):
        _solver.SolverImplementation_swiginit(self, _solver.new_SolverImplementation(*args))
    __swig_destroy__ = _solver.delete_SolverImplementation

# Register SolverImplementation in _solver:
_solver.SolverImplementation_swigregister(SolverImplementation)

class SolverImplementationTypedInterfaceObject(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):
        _solver.SolverImplementationTypedInterfaceObject_swiginit(self, _solver.new_SolverImplementationTypedInterfaceObject(*args))

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

        Returns
        -------
        impl : Implementation
            The implementation class.
        """
        return _solver.SolverImplementationTypedInterfaceObject_getImplementation(self)

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

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

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

        Returns
        -------
        name : str
            The name of the object.
        """
        return _solver.SolverImplementationTypedInterfaceObject_getName(self)

    def __eq__(self, other):
        return _solver.SolverImplementationTypedInterfaceObject___eq__(self, other)

    def __ne__(self, other):
        return _solver.SolverImplementationTypedInterfaceObject___ne__(self, other)
    __swig_destroy__ = _solver.delete_SolverImplementationTypedInterfaceObject

# Register SolverImplementationTypedInterfaceObject in _solver:
_solver.SolverImplementationTypedInterfaceObject_swigregister(SolverImplementationTypedInterfaceObject)

class Solver(SolverImplementationTypedInterfaceObject):
    r"""
    SolverImplementation of 1D non linear equations.

    Available constructor:
        SolverImplementation()

        SolverImplementation(*solverImplementation*)

        SolverImplementation(*absError, relError, resError, maximumFunctionEvaluation*)

    Parameters
    ----------
    solverImplementation : SolverImplementationImplementation
        The implementation of a particular solver which is :class:`~openturns.Bisection`,
        :class:`~openturns.Brent` or :class:`~openturns.Secant`.   
    absError : positive float
        Absolute error: distance between two successive iterates at the end point.
        Default is :math:`10^{-5}`.
    relError : positive float
        Relative error: distance between the two last successive iterates with
        regards to the last iterate. Default is :math:`10^{-5}`.
    resError : positive float
        Residual error: difference between the last iterate value and the expected
        value. Default is :math:`10^{-8}`.
    maximumFunctionEvaluation : int
        The maximum number of evaluations of the function. Default is :math:`100`.

    See also
    --------
    Bisection, Brent, Secant

    Notes
    -----
    This class enables to solve 1D non linear equations :

    .. math::

        f(x) = value, \forall x \in [infPoint, supPoint]

    if :math:`f` is a continuous function from :math:`\Rset` to :math:`\Rset`,
    :math:`infPoint, supPoint \in \Rset` and if :math:`f` is such that
    :math:`f(infPoint) \times f(supPoint) < 0`, then :math:`f` has at least a zero
    in the interval :math:`[infPoint, supPoint]`. In particular, it is used in the
    root research of a 
    :class:`Directional Sampling simulation <openturns.DirectionalSampling>`.
    """

    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 _solver.Solver_getClassName(self)

    def __eq__(self, other):
        return _solver.Solver___eq__(self, other)

    def __repr__(self):
        return _solver.Solver___repr__(self)

    def solve(self, *args):
        return _solver.Solver_solve(self, *args)

    def setAbsoluteError(self, absoluteError):
        r"""
        Accessor to the absolute error.

        Parameters
        ----------
        absError : float
            The absolute error: distance between two successive iterates at the end point.
        """
        return _solver.Solver_setAbsoluteError(self, absoluteError)

    def getAbsoluteError(self):
        r"""
        Accessor to the absolute error.

        Returns
        -------
        absError : float
            The absolute error: distance between two successive iterates at the end point.
        """
        return _solver.Solver_getAbsoluteError(self)

    def setRelativeError(self, relativeError):
        r"""
        Accessor to the relative error.

        Parameters
        ----------
        relError : float
            The relative error: distance between the two last successive iterates with
            regards to the last iterate.
        """
        return _solver.Solver_setRelativeError(self, relativeError)

    def getRelativeError(self):
        r"""
        Accessor to the relative error.

        Returns
        -------
        relError : float
            The relative error: distance between the two last successive iterates with
            regards to the last iterate.
        """
        return _solver.Solver_getRelativeError(self)

    def setResidualError(self, residualError):
        r"""
        Accessor to the residual error.

        Parameters
        ----------
        resError : float
            The residual errors: difference between the last iterate value and the
            expected value.
        """
        return _solver.Solver_setResidualError(self, residualError)

    def getResidualError(self):
        r"""
        Accessor to the residual error.

        Returns
        -------
        resError : float
            The residual errors: difference between the last iterate value and the
            expected value.
        """
        return _solver.Solver_getResidualError(self)

    def setMaximumFunctionEvaluation(self, maximumFunctionEvaluation):
        r"""
        Accessor to the maximum number of evaluations of the function.

        Parameters
        ----------
        maxEval : int
            The maximum number of evaluations of the function.
        """
        return _solver.Solver_setMaximumFunctionEvaluation(self, maximumFunctionEvaluation)

    def getMaximumFunctionEvaluation(self):
        r"""
        Accessor to the maximum number of evaluations of the function.

        Returns
        -------
        maxEval : int
            The maximum number of evaluations of the function.
        """
        return _solver.Solver_getMaximumFunctionEvaluation(self)

    def getUsedFunctionEvaluation(self):
        r"""
        Accessor to the number of evaluations of the function.

        Returns
        -------
        nEval : int
            The number of evaluations of the function.
        """
        return _solver.Solver_getUsedFunctionEvaluation(self)

    def __init__(self, *args):
        _solver.Solver_swiginit(self, _solver.new_Solver(*args))
    __swig_destroy__ = _solver.delete_Solver

# Register Solver in _solver:
_solver.Solver_swigregister(Solver)

class Bisection(SolverImplementation):
    r"""
    Bisection algorithm solver for 1D non linear equations.

    Available constructor:
        Bisection()

        Bisection(*absError, relError, resError, maximumFunctionEvaluation*)

    Parameters
    ----------
    absError : positive float
        Absolute error: distance between two successive iterates at the end point.
        Default is :math:`10^{-5}`.
    relError : positive float
        Relative error: distance between the two last successive iterates with
        regards to the last iterate. Default is :math:`10^{-5}`.
    resError : positive float
        Residual error: difference between the last iterate value and the expected
        value. Default is :math:`10^{-8}`.
    maximumFunctionEvaluation : int
        The maximum number of evaluations of the function. Default is :math:`100`.

    See also
    --------
    Solver, Brent, Secant
    """

    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 _solver.Bisection_getClassName(self)

    def __repr__(self):
        return _solver.Bisection___repr__(self)

    def solve(self, *args):
        r"""
        Solve an equation.

        **Available usages**:

            solve(*function, value, infPoint, supPoint*)

            solve(*function, value, infPoint, supPoint, infValue, supValue*)

        Parameters
        ----------
        function : :class:`~openturns.Function`
            The function of the equation :math:`function(x) = value` to be solved in the
            interval :math:`[infPoint, supPoint]`.
        value : float
            The value of which the function must be equal.
        infPoint : float
            Lower bound of the interval definition of the variable :math:`x`.
        supPoint : float
            Upper bound of the interval definition of the variable :math:`x`.
        infValue : float
            The value such that :math:`infValue = function(infPoint)`. It must be of 
            opposite sign of :math:`supValue`.
        supValue : float
            The value such that :math:`supValue = function(supPoint)`. It must be of 
            opposite sign of :math:`infValue`.

        Returns
        -------
        result : float
            The result of the root research.

        Notes
        -----
        If the function :math:`f` is continuous, the Bisection solver will converge
        towards a root of the equation :math:`function(x) = value` in
        :math:`[infPoint, supPoint]`. If not, it will converge towards either a root or
        a discontinuity point of :math:`f` on :math:`[infPoint, supPoint]`. Bisection
        guarantees a convergence.

        """
        return _solver.Bisection_solve(self, *args)

    def __init__(self, *args):
        _solver.Bisection_swiginit(self, _solver.new_Bisection(*args))
    __swig_destroy__ = _solver.delete_Bisection

# Register Bisection in _solver:
_solver.Bisection_swigregister(Bisection)

class Secant(SolverImplementation):
    r"""
    Secant algorithm solver for 1D non linear equations.

    Available constructor:
        Secant()

        Secant(*absError, relError, resError, maximumFunctionEvaluation*)

    Parameters
    ----------
    absError : positive float
        Absolute error: distance between two successive iterates at the end point.
        Default is :math:`10^{-5}`.
    relError : positive float
        Relative error: distance between the two last successive iterates with
        regards to the last iterate. Default is :math:`10^{-5}`.
    resError : positive float
        Residual error: difference between the last iterate value and the expected
        value. Default is :math:`10^{-8}`.
    maximumFunctionEvaluation : int
        The maximum number of evaluations of the function. Default is :math:`100`.

    See also
    --------
    Solver, Bisection, Brent

    Notes
    -----
    The Secant solver is based on the evaluation of a segment between the two last
    iterated points.
    """

    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 _solver.Secant_getClassName(self)

    def __repr__(self):
        return _solver.Secant___repr__(self)

    def solve(self, *args):
        r"""
        Solve an equation.

        **Available usages**:

            solve(*function, value, infPoint, supPoint*)

            solve(*function, value, infPoint, supPoint, infValue, supValue*)

        Parameters
        ----------
        function : :class:`~openturns.Function`
            The function of the equation :math:`function(x) = value` to be solved in the
            interval :math:`[infPoint, supPoint]`.
        value : float
            The value of which the function must be equal.
        infPoint : float
            Lower bound of the interval definition of the variable :math:`x`.
        supPoint : float
            Upper bound of the interval definition of the variable :math:`x`.
        infValue : float
            The value such that :math:`infValue = function(infPoint)`. It must be of 
            opposite sign of :math:`supValue`.
        supValue : float
            The value such that :math:`supValue = function(supPoint)`. It must be of 
            opposite sign of :math:`infValue`.

        Returns
        -------
        result : float
            The result of the root research.

        Notes
        -----
        The Secant solver is based on the evaluation of a segment between the two last
        iterated points. Secant might fail and not converge.
        """
        return _solver.Secant_solve(self, *args)

    def __init__(self, *args):
        _solver.Secant_swiginit(self, _solver.new_Secant(*args))
    __swig_destroy__ = _solver.delete_Secant

# Register Secant in _solver:
_solver.Secant_swigregister(Secant)

class Brent(SolverImplementation):
    r"""
    Brent algorithm solver for 1D non linear equations.

    Available constructor:
        Brent()

        Brent(*absError, relError, resError, maximumFunctionEvaluation*)

    Parameters
    ----------
    absError : positive float
        Absolute error: distance between two successive iterates at the end point.
        Default is :math:`10^{-5}`.
    relError : positive float
        Relative error: distance between the two last successive iterates with
        regards to the last iterate. Default is :math:`10^{-5}`.
    resError : positive float
        Residual error: difference between the last iterate value and the expected
        value. Default is :math:`10^{-8}`.
    maximumFunctionEvaluation : int
        The maximum number of evaluations of the function. Default is :math:`100`.

    See also
    --------
    Solver, Bisection, Secant

    Notes
    -----
    The Brent solver is a mix of Bisection, Secant and inverse quadratic
    interpolation.

    Examples
    --------

    >>> import openturns as ot
    >>> xMin = 0.0
    >>> xMax= 3.0
    >>> f = ot.MemoizeFunction(ot.SymbolicFunction('x', 'x^3-2*x^2-1'))
    >>> solver = ot.Brent()
    >>> root = solver.solve(f, 0.0, xMin, xMax)
    """

    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 _solver.Brent_getClassName(self)

    def __repr__(self):
        return _solver.Brent___repr__(self)

    def solve(self, *args):
        r"""
        Solve an equation.

        **Available usages**:

            solve(*function, value, infPoint, supPoint*)

            solve(*function, value, infPoint, supPoint, infValue, supValue*)

        Parameters
        ----------
        function : :class:`~openturns.Function`
            The function of the equation :math:`function(x) = value` to be solved in the
            interval :math:`[infPoint, supPoint]`.
        value : float
            The value of which the function must be equal.
        infPoint : float
            Lower bound of the interval definition of the variable :math:`x`.
        supPoint : float
            Upper bound of the interval definition of the variable :math:`x`.
        infValue : float
            The value such that :math:`infValue = function(infPoint)`. It must be of 
            opposite sign of :math:`supValue`.
        supValue : float
            The value such that :math:`supValue = function(supPoint)`. It must be of 
            opposite sign of :math:`infValue`.

        Returns
        -------
        result : float
            The result of the root research.

        Notes
        -----
        If the function :math:`f` is continuous, the Brent solver will
        converge towards a root of the equation :math:`function(x) = value` in
        :math:`[infPoint, supPoint]`. If not, it will converge towards either a root or
        a discontinuity point of :math:`f` on :math:`[infPoint, supPoint]`. Bisection
        guarantees a convergence.
        """
        return _solver.Brent_solve(self, *args)

    def __init__(self, *args):
        _solver.Brent_swiginit(self, _solver.new_Brent(*args))
    __swig_destroy__ = _solver.delete_Brent

# Register Brent in _solver:
_solver.Brent_swigregister(Brent)

class ODESolverImplementation(openturns.common.PersistentObject):
    r"""
    ODE solver base class.

    Solve an explicit first-order differential equation in the form :math:`y' = f(t, y)`
    """

    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 _solver.ODESolverImplementation_getClassName(self)

    def __repr__(self):
        return _solver.ODESolverImplementation___repr__(self)

    def solve(self, *args):
        r"""
        Solve ODE.

        Parameters
        ----------
        initialState : sequence of float
            Initial value of the equation
        timeGrid : sequence of float or :class:`~openturns.Mesh` of dimension 1
            Time stamps, ie values of :math:`t` at which the solution is computed.

        Returns
        -------
        values : :class:`~openturns.Sample`
            The solution of the equation at grid points.
        """
        return _solver.ODESolverImplementation_solve(self, *args)

    def setTransitionFunction(self, transitionFunction):
        r"""
        Transition function accessor.

        Parameters
        ----------
        transitionFunction : :class:`~openturns.FieldFunction`
            Transition function.
        """
        return _solver.ODESolverImplementation_setTransitionFunction(self, transitionFunction)

    def getTransitionFunction(self):
        r"""
        Transition function accessor.

        Returns
        -------
        transitionFunction : :class:`~openturns.FieldFunction`
            Transition function.
        """
        return _solver.ODESolverImplementation_getTransitionFunction(self)

    def __init__(self, *args):
        _solver.ODESolverImplementation_swiginit(self, _solver.new_ODESolverImplementation(*args))
    __swig_destroy__ = _solver.delete_ODESolverImplementation

# Register ODESolverImplementation in _solver:
_solver.ODESolverImplementation_swigregister(ODESolverImplementation)

class ODESolverImplementationTypedInterfaceObject(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):
        _solver.ODESolverImplementationTypedInterfaceObject_swiginit(self, _solver.new_ODESolverImplementationTypedInterfaceObject(*args))

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

        Returns
        -------
        impl : Implementation
            The implementation class.
        """
        return _solver.ODESolverImplementationTypedInterfaceObject_getImplementation(self)

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

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

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

        Returns
        -------
        name : str
            The name of the object.
        """
        return _solver.ODESolverImplementationTypedInterfaceObject_getName(self)

    def __eq__(self, other):
        return _solver.ODESolverImplementationTypedInterfaceObject___eq__(self, other)

    def __ne__(self, other):
        return _solver.ODESolverImplementationTypedInterfaceObject___ne__(self, other)
    __swig_destroy__ = _solver.delete_ODESolverImplementationTypedInterfaceObject

# Register ODESolverImplementationTypedInterfaceObject in _solver:
_solver.ODESolverImplementationTypedInterfaceObject_swigregister(ODESolverImplementationTypedInterfaceObject)

class ODESolver(ODESolverImplementationTypedInterfaceObject):
    r"""
    ODE solver base class.

    Solve an explicit first-order differential equation in the form :math:`y' = f(t, y)`
    """

    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 _solver.ODESolver_getClassName(self)

    def __repr__(self):
        return _solver.ODESolver___repr__(self)

    def __str__(self, *args):
        return _solver.ODESolver___str__(self, *args)

    def solve(self, *args):
        r"""
        Solve ODE.

        Parameters
        ----------
        initialState : sequence of float
            Initial value of the equation
        timeGrid : sequence of float or :class:`~openturns.Mesh` of dimension 1
            Time stamps, ie values of :math:`t` at which the solution is computed.

        Returns
        -------
        values : :class:`~openturns.Sample`
            The solution of the equation at grid points.
        """
        return _solver.ODESolver_solve(self, *args)

    def setTransitionFunction(self, transitionFunction):
        r"""
        Transition function accessor.

        Parameters
        ----------
        transitionFunction : :class:`~openturns.FieldFunction`
            Transition function.
        """
        return _solver.ODESolver_setTransitionFunction(self, transitionFunction)

    def getTransitionFunction(self):
        r"""
        Transition function accessor.

        Returns
        -------
        transitionFunction : :class:`~openturns.FieldFunction`
            Transition function.
        """
        return _solver.ODESolver_getTransitionFunction(self)

    def __init__(self, *args):
        _solver.ODESolver_swiginit(self, _solver.new_ODESolver(*args))
    __swig_destroy__ = _solver.delete_ODESolver

# Register ODESolver in _solver:
_solver.ODESolver_swigregister(ODESolver)

class RungeKutta(ODESolverImplementation):
    r"""
    Runge-Kutta fourth-order method.

    Parameters
    ----------
    transitionFunction : :class:`~openturns.Function`
        The function defining the flow of the ordinary differential equation.
        Must have one parameter.

    See also
    --------
    ODESolver

    Examples
    --------
    >>> import openturns as ot
    >>> f = ot.SymbolicFunction(['t', 'y0', 'y1'], ['t - y0', 'y1 + t^2'])
    >>> phi = ot.ParametricFunction(f, [0], [0.0])
    >>> solver = ot.RungeKutta(phi)
    >>> Y0 = [1.0, -1.0]
    >>> nt = 100
    >>> timeGrid = [(i**2.0) / (nt - 1.0)**2.0 for i in range(nt)]
    >>> result = solver.solve(Y0, timeGrid)
    """

    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 _solver.RungeKutta_getClassName(self)

    def __repr__(self):
        return _solver.RungeKutta___repr__(self)

    def solve(self, *args):
        r"""
        Solve ODE.

        Parameters
        ----------
        initialState : sequence of float
            Initial value of the equation
        timeGrid : sequence of float or :class:`~openturns.Mesh` of dimension 1
            Time stamps, ie values of :math:`t` at which the solution is computed.

        Returns
        -------
        values : :class:`~openturns.Sample`
            The solution of the equation at grid points.
        """
        return _solver.RungeKutta_solve(self, *args)

    def __init__(self, *args):
        _solver.RungeKutta_swiginit(self, _solver.new_RungeKutta(*args))
    __swig_destroy__ = _solver.delete_RungeKutta

# Register RungeKutta in _solver:
_solver.RungeKutta_swigregister(RungeKutta)

class Fehlberg(ODESolverImplementation):
    r"""
    Adaptive order Fehlberg method.

    Parameters
    ----------
    transitionFunction : :class:`~openturns.Function`
        The function defining the flow of the ordinary differential equation.
        Must have one parameter.
    localPrecision : float
        The expected absolute error on one step.
    order : int, :math:`order\in\{0,1,2,3,4\}`
        The order of the method, ie the exponent :math:`p` in the estimate of the
        local error for a step of size :math:`h` written as :math:`\cO(h^p)`.

    Notes
    -----
    The Fehlberg method of order :math:`p\in\Nset` is a *one-step* *explicit* method
    made of two *embedded* Runge Kutta methods of order :math:`p` and :math:`p+1`.
    More precisely, such a method approximate the solution of:

    .. math::
        \vect{y}'(t)=f\left(t,\vect{y}(t)\right)\quad\mbox{with}\quad \vect{y}(t_0)=\vect{y}_0

    at a given set of locations :math:`t_0,\dots,t_N` by first building an
    approximation over an adapted grid :math:`\tau_0=t_0,\dots,\tau_M=t_N` with a
    number of points :math:`M` not necessarily equal to the number of locations
    :math:`N` and internal nodes not necessarily part of the set of locations. Then,
    the solution :math:`\vect{y}` is approximated by a smooth piecewise polynomial
    function using :class:`~openturns.PiecewiseHermiteEvaluation`, which is evaluated
    over the set of locations.

    The method proceeds as follows. Knowing the solution at location
    :math:`\vect{y}_i=\vect{y}(\tau_i)` and a current time step :math:`h_i`, two
    approximations :math:`\hat{\vect{y}}_{i+1}` and :math:`\bar{\vect{y}}_{i+1}` of
    :math:`\vect{y}_{i+1}=\vect{y}(\tau_i+h_i)=\vect{y}(\tau_{i+1})` are built, such
    that:

    .. math::
        \hat{\vect{y}}_{i+1}=\vect{y}_i+h_i\vect{\Phi}_{\mathrm{I}}\left(\tau_i, \vect{y}_i, h_i\right) \\
        \bar{\vect{y}}_{i+1}=\vect{y}_i+h_i\vect{\Phi}_{\mathrm{II}}\left(\tau_i, \vect{y}_i, h_i\right)

    where we assume that:

    .. math::
        \left|\vect{\Phi}_{\mathrm{I}}\left(\tau_i,\vect{y}_i,h_i\right)-(\vect{y}_{i+1}-\vect{y}_i)/h_i\right|=\cO\left(h_i^p\right)\\
        \left|\vect{\Phi}_{\mathrm{II}}\left(\tau_i, \vect{y}_i,h_i\right)-(\vect{y}_{i+1}-\vect{y}_i)/h_i\right|=\cO\left(h_i^{p+1}\right)

    The evolution operators :math:`\vect{\Phi}_{\mathrm{I}}` and
    :math:`\vect{\Phi}_{\mathrm{II}}` are constructed as follows:

    .. math::
        \vect{\Phi}_{\mathrm{I}}\left(\tau, \vect{y}_i, h_i\right)=\sum_{k=0}^p
        c_kf_k\left(\tau,\vect{y}_i; h_i\right)\\ 
        \vect{\Phi}_{\mathrm{II}}\left(\tau, \vect{y}_i, h_i\right)=\sum_{k=0}^{p+1}
        \hat{c}_kf_k\left(\tau,\vect{y}_i; h_i\right)

    with
    :math:`f_k=f_k\left(\tau,\vect{y}_i,h_i\right)=f\left(\tau+\alpha_kh_i,\vect{y}_i+h_i\sum_{\ell=0}^{k-1}\beta_{k\ell}f_{\ell}\right)`. The most desirable property of
    these methods is their *embedded* nature: the high-order approximation reuses all
    the evaluations of :math:`f` needed by the low-order approximation. The
    coefficients :math:`c_k`, :math:`\hat{c}_k`, :math:`\alpha_k` and
    :math:`\beta_{k\ell}` fully specify the method.

    For :math:`p=0` we have:

    .. table::

        +-----------+------------------+--------------------+-------------+-------------------+
        | :math:`k` | :math:`\alpha_k` | :math:`\beta_{k0}` | :math:`c_k` | :math:`\hat{c}_k` |
        +===========+==================+====================+=============+===================+
        | 0         | 0                | 0                  | 1           | 1/2               |
        +-----------+------------------+--------------------+-------------+-------------------+
        | 1         | 1                | 1                  |             | 1/2               |
        +-----------+------------------+--------------------+-------------+-------------------+

    For :math:`p=1` we have:

    .. table::

        +-----------+------------------+--------------------+--------------------+-------------+-------------------+
        | :math:`k` | :math:`\alpha_k` | :math:`\beta_{k0}` | :math:`\beta_{k1}` | :math:`c_k` | :math:`\hat{c}_k` |
        +===========+==================+====================+====================+=============+===================+
        | 0         | 0                | 0                  |                    | 1/256       | 1/512             |
        +-----------+------------------+--------------------+--------------------+-------------+-------------------+
        | 1         | 1/2              | 1/2                |                    | 255/256     | 255/256           |
        +-----------+------------------+--------------------+--------------------+-------------+-------------------+
        | 2         | 1                | 1/256              | 255/256            |             | 1/512             |
        +-----------+------------------+--------------------+--------------------+-------------+-------------------+

    For :math:`p=2` we have:

    .. table::

        +-----------+------------------+--------------------+--------------------+--------------------+-------------+-------------------+
        | :math:`k` | :math:`\alpha_k` | :math:`\beta_{k0}` | :math:`\beta_{k1}` | :math:`\beta_{k2}` | :math:`c_k` | :math:`\hat{c}_k` |
        +===========+==================+====================+====================+====================+=============+===================+
        | 0         | 0                | 0                  |                    |                    | 214/891     | 533/2106          |
        +-----------+------------------+--------------------+--------------------+--------------------+-------------+-------------------+
        | 1         | 1/4              | 1/4                |                    |                    | 1/33        | 0                 |
        +-----------+------------------+--------------------+--------------------+--------------------+-------------+-------------------+
        | 2         | 27/40            | -189/800           | 214/891            |                    | 650/891     | 800/1053          |
        +-----------+------------------+--------------------+--------------------+--------------------+-------------+-------------------+
        | 3         | 1                | 729/800            | 1/35               | 650/891            |             | -1/78             |
        +-----------+------------------+--------------------+--------------------+--------------------+-------------+-------------------+

    For :math:`p>2` the coefficients can be found eg in the C++ source code. For
    additional theory on these methods see [stoer1993]_, chapter 7. 

    See also
    --------
    ODESolver

    Examples
    --------
    >>> import openturns as ot
    >>> f = ot.SymbolicFunction(['t', 'y0', 'y1'], ['t - y0', 'y1 + t^2'])
    >>> phi = ot.ParametricFunction(f, [0], [0.0])
    >>> solver = ot.Fehlberg(phi)
    >>> Y0 = [1.0, -1.0]
    >>> nt = 100
    >>> timeGrid = [(i**2.0) / (nt - 1.0)**2.0 for i in range(nt)]
    >>> result = solver.solve(Y0, timeGrid)
    """

    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 _solver.Fehlberg_getClassName(self)

    def __repr__(self):
        return _solver.Fehlberg___repr__(self)

    def solve(self, *args):
        r"""
        Solve ODE.

        Parameters
        ----------
        initialState : sequence of float
            Initial value of the equation
        timeGrid : sequence of float or :class:`~openturns.Mesh` of dimension 1
            Time stamps, ie values of :math:`t` at which the solution is computed.

        Returns
        -------
        values : :class:`~openturns.Sample`
            The solution of the equation at grid points.
        """
        return _solver.Fehlberg_solve(self, *args)

    def __init__(self, *args):
        _solver.Fehlberg_swiginit(self, _solver.new_Fehlberg(*args))
    __swig_destroy__ = _solver.delete_Fehlberg

# Register Fehlberg in _solver:
_solver.Fehlberg_swigregister(Fehlberg)



